MediaWiki
REL1_19
|
00001 <?php 00033 require_once( dirname( __FILE__ ) . '/Maintenance.php' ); 00034 00035 class ImageBuilder extends Maintenance { 00036 00040 protected $dbw; 00041 00042 function __construct() { 00043 parent::__construct(); 00044 00045 global $wgUpdateCompatibleMetadata; 00046 //make sure to update old, but compatible img_metadata fields. 00047 $wgUpdateCompatibleMetadata = true; 00048 00049 $this->mDescription = 'Script to update image metadata records'; 00050 00051 $this->addOption( 'missing', 'Check for files without associated database record' ); 00052 $this->addOption( 'dry-run', 'Only report, don\'t update the database' ); 00053 } 00054 00055 public function execute() { 00056 $this->dbw = wfGetDB( DB_MASTER ); 00057 $this->maxLag = 10; # if slaves are lagged more than 10 secs, wait 00058 $this->dryrun = $this->hasOption( 'dry-run' ); 00059 if ( $this->dryrun ) { 00060 $GLOBALS['wgReadOnly'] = 'Dry run mode, image upgrades are suppressed'; 00061 } 00062 00063 if ( $this->hasOption( 'missing' ) ) { 00064 $this->crawlMissing(); 00065 } else { 00066 $this->build(); 00067 } 00068 } 00069 00073 function getRepo() { 00074 if ( !isset( $this->repo ) ) { 00075 $this->repo = RepoGroup::singleton()->getLocalRepo(); 00076 } 00077 return $this->repo; 00078 } 00079 00080 function build() { 00081 $this->buildImage(); 00082 $this->buildOldImage(); 00083 } 00084 00085 function init( $count, $table ) { 00086 $this->processed = 0; 00087 $this->updated = 0; 00088 $this->count = $count; 00089 $this->startTime = wfTime(); 00090 $this->table = $table; 00091 } 00092 00093 function progress( $updated ) { 00094 $this->updated += $updated; 00095 $this->processed++; 00096 if ( $this->processed % 100 != 0 ) { 00097 return; 00098 } 00099 $portion = $this->processed / $this->count; 00100 $updateRate = $this->updated / $this->processed; 00101 00102 $now = wfTime(); 00103 $delta = $now - $this->startTime; 00104 $estimatedTotalTime = $delta / $portion; 00105 $eta = $this->startTime + $estimatedTotalTime; 00106 $rate = $this->processed / $delta; 00107 00108 $this->output( sprintf( "%s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec <%.2f%% updated>\n", 00109 wfTimestamp( TS_DB, intval( $now ) ), 00110 $portion * 100.0, 00111 $this->table, 00112 wfTimestamp( TS_DB, intval( $eta ) ), 00113 $this->processed, 00114 $this->count, 00115 $rate, 00116 $updateRate * 100.0 ) ); 00117 flush(); 00118 } 00119 00120 function buildTable( $table, $key, $callback ) { 00121 $count = $this->dbw->selectField( $table, 'count(*)', '', __METHOD__ ); 00122 $this->init( $count, $table ); 00123 $this->output( "Processing $table...\n" ); 00124 00125 $result = wfGetDB( DB_SLAVE )->select( $table, '*', array(), __METHOD__ ); 00126 00127 foreach ( $result as $row ) { 00128 $update = call_user_func( $callback, $row, null ); 00129 if ( $update ) { 00130 $this->progress( 1 ); 00131 } else { 00132 $this->progress( 0 ); 00133 } 00134 } 00135 $this->output( "Finished $table... $this->updated of $this->processed rows updated\n" ); 00136 } 00137 00138 function buildImage() { 00139 $callback = array( $this, 'imageCallback' ); 00140 $this->buildTable( 'image', 'img_name', $callback ); 00141 } 00142 00143 function imageCallback( $row, $copy ) { 00144 // Create a File object from the row 00145 // This will also upgrade it 00146 $file = $this->getRepo()->newFileFromRow( $row ); 00147 return $file->getUpgraded(); 00148 } 00149 00150 function buildOldImage() { 00151 $this->buildTable( 'oldimage', 'oi_archive_name', array( $this, 'oldimageCallback' ) ); 00152 } 00153 00154 function oldimageCallback( $row, $copy ) { 00155 // Create a File object from the row 00156 // This will also upgrade it 00157 if ( $row->oi_archive_name == '' ) { 00158 $this->output( "Empty oi_archive_name for oi_name={$row->oi_name}\n" ); 00159 return false; 00160 } 00161 $file = $this->getRepo()->newFileFromRow( $row ); 00162 return $file->getUpgraded(); 00163 } 00164 00165 function crawlMissing() { 00166 $this->getRepo()->enumFiles( array( $this, 'checkMissingImage' ) ); 00167 } 00168 00169 function checkMissingImage( $fullpath ) { 00170 $filename = wfBaseName( $fullpath ); 00171 $row = $this->dbw->selectRow( 'image', 00172 array( 'img_name' ), 00173 array( 'img_name' => $filename ), 00174 __METHOD__ ); 00175 00176 if ( !$row ) { // file not registered 00177 $this->addMissingImage( $filename, $fullpath ); 00178 } 00179 } 00180 00181 function addMissingImage( $filename, $fullpath ) { 00182 global $wgContLang; 00183 00184 $timestamp = $this->dbw->timestamp( $this->getRepo()->getFileTimestamp( $fullpath ) ); 00185 00186 $altname = $wgContLang->checkTitleEncoding( $filename ); 00187 if ( $altname != $filename ) { 00188 if ( $this->dryrun ) { 00189 $filename = $altname; 00190 $this->output( "Estimating transcoding... $altname\n" ); 00191 } else { 00192 # @FIXME: create renameFile() 00193 $filename = $this->renameFile( $filename ); 00194 } 00195 } 00196 00197 if ( $filename == '' ) { 00198 $this->output( "Empty filename for $fullpath\n" ); 00199 return; 00200 } 00201 if ( !$this->dryrun ) { 00202 $file = wfLocalFile( $filename ); 00203 if ( !$file->recordUpload( '', '(recovered file, missing upload log entry)', '', '', '', 00204 false, $timestamp ) ) 00205 { 00206 $this->output( "Error uploading file $fullpath\n" ); 00207 return; 00208 } 00209 } 00210 $this->output( $fullpath . "\n" ); 00211 } 00212 } 00213 00214 $maintClass = 'ImageBuilder'; 00215 require_once( RUN_MAINTENANCE_IF_MAIN );