Files
newznab-tmux/nnscripts/remove_parts_without_releases.php
T
2014-01-03 15:02:22 +01:00

273 lines
8.1 KiB
PHP

<?php
/**
* This script removes:
* - parts which do not have a binary matched
* - parts where the binary matched is missing
* - binaries which do not have a part matched
*
* @author NN Scripts
* @license http://opensource.org/licenses/MIT MIT License
* @copyright (c) 2013 - NN Scripts
*
* Changelog:
* 0.4 - Added remove of orphan binary records
*
* 0.3 - Added settings.ini
* Start using nnscript library
*
* 0.2 - Change retrieval of parts in7groups of 10000
*
* 0.1 - Initial version
*/
//----------------------------------------------------------------------
// Load the application
require_once(dirname(__FILE__)."/../bin/config.php");
require_once(WWW_DIR. "lib/framework/db.php");
// nnscripts includes
require_once("lib/nnscripts.php");
/**
* Remove parts which are not linked to a binary
*/
class remove_parts_without_releases extends NNScripts
{
/**
* The script name
* @var string
*/
protected $scriptName = 'Remove parts which are not linked to a binary';
/**
* The script version
* @var string
*/
protected $scriptVersion = '0.4';
/**
* Allowed settings
* @var array
*/
protected $allowedSettings = array('display', 'limit', 'querylimit');
/**
* The constructor
*
*/
public function __construct()
{
// Call the parent constructor
parent::__construct();
// Set the commandline options
$options = array(
array( null, 'querylimit', Ulrichsg\Getopt::REQUIRED_ARGUMENT, 'The query limit (default 10000)' ),
);
$this->setCliOptions( $options, array('display', 'limit', 'help') );
// Show the header
$this->displayHeader();
// Show the settings
$this->displaySettings();
}
/**
* Remove all the parts which are not linked to a binary
*
* @return void
*/
public function cleanup()
{
// Remove old parts without binaries
$this->removePartsWithoutBinary();
// Remove parts where the binary is missing
$this->removePartsWithMissingBinary();
// Remove binaries without parts
$this->removeBinariesWithoutParts();
}
/**
* Remove parts without a binary linked
*
* @return void
*/
private function removePartsWithoutBinary()
{
$this->display( "Removing old part records which are not linked to a binary: " );
// Build the sql
$sql = "DELETE FROM parts
WHERE binaryID = 0";
if( is_numeric( $this->settings['limit'] ) && 0 < $this->settings['limit'] )
{
$sql .= sprintf( ' AND dateadded < "%s" - INTERVAL %s HOUR', $this->settings['now'], $this->settings['limit'] );
}
$result = $this->db->queryDirect( $sql );
$this->display( ( $result ? "Done" : "Error" ) . PHP_EOL );
}
/**
* Remove parts where the binary is missing
*
* @return void
*/
private function removePartsWithMissingBinary()
{
// Get the total parts to remove
$total = $this->getTotalPartsToRemove();
if( 0 < $total )
{
$line = sprintf( "Removing %s parts with missing binaries", number_format($total, 0, '.', '') );
if( $total > $this->settings['querylimit'] )
{
$line .= sprintf( ' (in groups of %d parts)', $this->settings['querylimit'] );
}
$line .= ': ';
$this->display( $line );
// Set the lastID
$lastId = null;
$ids = array();
// Loop until there are no parts to remove
while( 0 < $total )
{
// Build the query
$sql = sprintf("SELECT DISTINCT p.ID
FROM parts AS p
LEFT JOIN binaries AS b ON (b.ID = p.binaryID)
WHERE b.ID IS NULL
%s
%s
ORDER BY p.ID ASC
LIMIT %d",
( null !== $lastId ? sprintf('AND p.ID > %d', $lastId) : '' ),
(
( is_numeric( $this->settings['limit'] ) && 0 < $this->settings['limit'] )
? sprintf( ' AND p.dateadded < "%s" - INTERVAL %s HOUR', $this->settings['now'], $this->settings['limit'] )
: ''
),
$this->settings['querylimit']
);
$result = $this->db->queryDirect( $sql );
if( is_array( $result ) && 0 < count( $result ) )
{
// Build the total ID list
$ids = array();
$counter = 0;
foreach( $result AS $row )
{
$ids[] = $lastId = $row['ID'];
$counter++;
if( $this->settings['querylimit'] === $counter )
{
$this->display( "." );
$sql = sprintf( "DELETE FROM parts WHERE ID IN (%s)", implode(',', $ids) );
$this->db->exec( $sql );
$ids = array();
$counter = 0;
}
}
// Cleanup
unset( $result );
// Lower the total
$total -= $this->settings['querylimit'];
}
else
{
// Query without result?
$total = 0;
}
}
// And remove the rest
if( is_array($ids) && 0 < count($ids) )
{
$this->display( "." );
$sql = sprintf( "DELETE FROM parts WHERE ID IN (%s)", implode(',', $ids) );
$this->db->queryDirect( $sql );
}
$this->display( PHP_EOL );
}
else
{
$this->display( 'No parts with missing binaries to remove.'. PHP_EOL );
}
}
/**
* Get the total count of parts to remove
*
* @return int
*/
protected function getTotalPartsToRemove()
{
// Init
$ret = 0;
// Get the total to remove
$sql = "SELECT count(*) AS total
FROM parts AS p
LEFT JOIN binaries AS b ON (b.ID = p.binaryID)
WHERE b.ID IS NULL";
if( is_numeric( $this->settings['limit'] ) && 0 < $this->settings['limit'] )
{
$sql .= sprintf( ' AND p.dateadded < "%s" - INTERVAL %s HOUR', $this->settings['now'], $this->settings['limit'] );
}
$result = $this->db->queryOneRow( $sql );
if( is_array($result) && array_key_exists('total', $result) )
{
$ret = (int)$result['total'];
}
// Return
return $ret;
}
/**
* Remove orhpan binary records
*
* @return void
*/
protected function removeBinariesWithoutParts()
{
$this->display( "Removing old binary records which do not have parts: " );
$sql = "DELETE binaries FROM binaries
LEFT JOIN parts ON (parts.binaryID = binaries.ID)
WHERE parts.ID IS NULL";
if( is_numeric( $this->settings['limit'] ) && 0 < $this->settings['limit'] )
{
$sql .= sprintf( ' AND binaries.dateadded < "%s" - INTERVAL %s HOUR', $this->settings['now'], $this->settings['limit'] );
}
$result = $this->db->queryDirect( $sql );
$this->display( ( $result ? "Done" : "Error" ) . PHP_EOL );
}
}
// Main application
try
{
// Load the remove_parts_without_releases class
$rpwr = new remove_parts_without_releases();
$rpwr->cleanup();
} catch( Exception $e ) {
echo $e->getMessage() . PHP_EOL;
}