MediaWiki  REL1_22
cleanupUploadStash.php
Go to the documentation of this file.
00001 <?php
00028 require_once __DIR__ . '/Maintenance.php';
00029 
00036 class UploadStashCleanup extends Maintenance {
00037 
00038     public function __construct() {
00039         parent::__construct();
00040         $this->mDescription = "Clean up abandoned files in temporary uploaded file stash";
00041     }
00042 
00043     public function execute() {
00044         global $wgUploadStashMaxAge;
00045 
00046         $repo = RepoGroup::singleton()->getLocalRepo();
00047         $tempRepo = $repo->getTempRepo();
00048 
00049         $dbr = $repo->getSlaveDb();
00050 
00051         // how far back should this look for files to delete?
00052         $cutoff = time() - $wgUploadStashMaxAge;
00053 
00054         $this->output( "Getting list of files to clean up...\n" );
00055         $res = $dbr->select(
00056             'uploadstash',
00057             'us_key',
00058             'us_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( $cutoff ) ),
00059             __METHOD__
00060         );
00061 
00062         // Delete all registered stash files...
00063         if ( $res->numRows() == 0 ) {
00064             $this->output( "No stashed files to cleanup according to the DB.\n" );
00065         } else {
00066             // finish the read before starting writes.
00067             $keys = array();
00068             foreach ( $res as $row ) {
00069                 array_push( $keys, $row->us_key );
00070             }
00071 
00072             $this->output( 'Removing ' . count( $keys ) . " file(s)...\n" );
00073             // this could be done some other, more direct/efficient way, but using
00074             // UploadStash's own methods means it's less likely to fall accidentally
00075             // out-of-date someday
00076             $stash = new UploadStash( $repo );
00077 
00078             $i = 0;
00079             foreach ( $keys as $key ) {
00080                 $i++;
00081                 try {
00082                     $stash->getFile( $key, true );
00083                     $stash->removeFileNoAuth( $key );
00084                 } catch ( UploadStashBadPathException $ex ) {
00085                     $this->output( "Failed removing stashed upload with key: $key\n" );
00086                 } catch ( UploadStashZeroLengthFileException $ex ) {
00087                     $this->output( "Failed removing stashed upload with key: $key\n" );
00088                 }
00089                 if ( $i % 100 == 0 ) {
00090                     $this->output( "$i\n" );
00091                 }
00092             }
00093             $this->output( "$i done\n" );
00094         }
00095 
00096         // Delete all the corresponding thumbnails...
00097         $dir = $tempRepo->getZonePath( 'thumb' );
00098         $iterator = $tempRepo->getBackend()->getFileList( array( 'dir' => $dir ) );
00099         $this->output( "Deleting old thumbnails...\n" );
00100         $i = 0;
00101         foreach ( $iterator as $file ) {
00102             if ( wfTimestamp( TS_UNIX, $tempRepo->getFileTimestamp( "$dir/$file" ) ) < $cutoff ) {
00103                 $status = $tempRepo->quickPurge( "$dir/$file" );
00104                 if ( !$status->isOK() ) {
00105                     $this->error( print_r( $status->getErrorsArray(), true ) );
00106                 }
00107                 if ( ( ++$i % 100 ) == 0 ) {
00108                     $this->output( "$i\n" );
00109                 }
00110             }
00111         }
00112         $this->output( "$i done\n" );
00113 
00114         // Apparently lots of stash files are not registered in the DB...
00115         $dir = $tempRepo->getZonePath( 'public' );
00116         $iterator = $tempRepo->getBackend()->getFileList( array( 'dir' => $dir, 'adviseStat' => 1 ) );
00117         $this->output( "Deleting orphaned temp files...\n" );
00118         if ( strpos( $dir, '/local-temp' ) === false ) { // sanity check
00119             $this->error( "Temp repo is not using the temp container.", 1 ); // die
00120         }
00121         $i = 0;
00122         foreach ( $iterator as $file ) {
00123             // Absolute sanity check for stashed files and file segments
00124             if ( !preg_match( '#(^\d{14}!|\.\d+\.\w+\.\d+$)#', basename( $file ) ) ) {
00125                 $this->output( "Skipped non-stash $file\n" );
00126                 continue;
00127             }
00128             if ( wfTimestamp( TS_UNIX, $tempRepo->getFileTimestamp( "$dir/$file" ) ) < $cutoff ) {
00129                 $status = $tempRepo->quickPurge( "$dir/$file" );
00130                 if ( !$status->isOK() ) {
00131                     $this->error( print_r( $status->getErrorsArray(), true ) );
00132                 }
00133                 if ( ( ++$i % 100 ) == 0 ) {
00134                     $this->output( "$i\n" );
00135                 }
00136             }
00137         }
00138         $this->output( "$i done\n" );
00139     }
00140 }
00141 
00142 $maintClass = "UploadStashCleanup";
00143 require_once RUN_MAINTENANCE_IF_MAIN;