MediaWiki
REL1_22
|
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;