MediaWiki  REL1_21
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 ) );
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 );