MediaWiki
REL1_19
|
00001 <?php 00030 require_once( dirname( __FILE__ ) . '/Maintenance.php' ); 00031 00032 class RefreshImageMetadata extends Maintenance { 00033 00037 protected $dbw; 00038 00039 function __construct() { 00040 parent::__construct(); 00041 00042 $this->mDescription = 'Script to update image metadata records'; 00043 $this->setBatchSize( 200 ); 00044 00045 $this->addOption( 'force', 'Reload metadata from file even if the metadata looks ok', false, false, 'f' ); 00046 $this->addOption( 'broken-only', 'Only fix really broken records, leave old but still compatible records alone.' ); 00047 $this->addOption( 'verbose', 'Output extra information about each upgraded/non-upgraded file.', false, false, 'v' ); 00048 $this->addOption( 'start', 'Name of file to start with', false, true ); 00049 $this->addOption( 'end', 'Name of file to end with', false, true ); 00050 00051 $this->addOption( 'mime', '(Inefficient!) Only refresh files with this mime type. Can accept wild-card image/*' , false, true ); 00052 $this->addOption( 'metadata-contains', '(Inefficient!) Only refresh files where the img_metadata field contains this string. Can be used if its known a specific property was being extracted incorrectly.', false, true ); 00053 00054 } 00055 00056 public function execute() { 00057 $force = $this->hasOption( 'force' ); 00058 $brokenOnly = $this->hasOption( 'broken-only' ); 00059 $verbose = $this->hasOption( 'verbose' ); 00060 $start = $this->getOption( 'start', false ); 00061 $this->setupParameters( $force, $brokenOnly ); 00062 00063 $upgraded = 0; 00064 $leftAlone = 0; 00065 $error = 0; 00066 00067 $dbw = wfGetDB( DB_MASTER ); 00068 if ( $this->mBatchSize <= 0 ) { 00069 $this->error( "Batch size is too low...", 12 ); 00070 } 00071 00072 $repo = RepoGroup::singleton()->getLocalRepo(); 00073 $conds = $this->getConditions( $dbw ); 00074 00075 // For the WHERE img_name > 'foo' condition that comes after doing a batch 00076 $conds2 = array(); 00077 if ( $start !== false ) { 00078 $conds2[] = 'img_name >= ' . $dbw->addQuotes( $start ); 00079 } 00080 00081 $options = array( 00082 'LIMIT' => $this->mBatchSize, 00083 'ORDER BY' => 'img_name ASC', 00084 ); 00085 00086 do { 00087 $res = $dbw->select( 00088 'image', 00089 '*', 00090 array_merge( $conds, $conds2 ), 00091 __METHOD__, 00092 $options 00093 ); 00094 00095 if ( $res->numRows() > 0 ) { 00096 $row1 = $res->current(); 00097 $this->output( "Processing next {$this->mBatchSize} rows starting with {$row1->img_name}.\n"); 00098 $res->rewind(); 00099 } else { 00100 $this->error( "No images to process.", 4 ); 00101 } 00102 00103 foreach ( $res as $row ) { 00104 $file = $repo->newFileFromRow( $row ); 00105 if ( $file->getUpgraded() ) { 00106 // File was upgraded. 00107 $upgraded++; 00108 $newLength = strlen( $file->getMetadata() ); 00109 $oldLength = strlen( $row->img_metadata ); 00110 if ( $newLength < $oldLength - 5 ) { 00111 // If after updating, the metadata is smaller then 00112 // what it was before, that's probably not a good thing 00113 // because we extract more data with time, not less. 00114 // Thus this probably indicates an error of some sort, 00115 // or at the very least is suspicious. Have the - 5 just 00116 // to weed out any inconsequential changes. 00117 $error++; 00118 $this->output( "Warning: File:{$row->img_name} used to have " . 00119 "$oldLength bytes of metadata but now has $newLength bytes.\n" ); 00120 } elseif ( $verbose ) { 00121 $this->output("Refreshed File:{$row->img_name}.\n" ); 00122 } 00123 } else { 00124 $leftAlone++; 00125 if ( $force ) { 00126 $file->upgradeRow(); 00127 $newLength = strlen( $file->getMetadata() ); 00128 $oldLength = strlen( $row->img_metadata ); 00129 if ( $newLength < $oldLength - 5 ) { 00130 $error++; 00131 $this->output( "Warning: File:{$row->img_name} used to have " . 00132 "$oldLength bytes of metadata but now has $newLength bytes. (forced)\n" ); 00133 00134 } 00135 if ( $verbose ) { 00136 $this->output("Forcibly refreshed File:{$row->img_name}.\n" ); 00137 } 00138 } 00139 else { 00140 if ( $verbose ) { 00141 $this->output( "Skipping File:{$row->img_name}.\n" ); 00142 } 00143 } 00144 } 00145 00146 } 00147 $conds2 = array( 'img_name > ' . $dbw->addQuotes( $row->img_name ) ); 00148 wfWaitForSlaves(); 00149 } while( $res->numRows() === $this->mBatchSize ); 00150 00151 $total = $upgraded + $leftAlone; 00152 if ( $force ) { 00153 $this->output( "\nFinished refreshing file metadata for $total files. $upgraded needed to be refreshed, $leftAlone did not need to be but were refreshed anyways, and $error refreshes were suspicious.\n" ); 00154 } else { 00155 $this->output( "\nFinished refreshing file metadata for $total files. $upgraded were refreshed, $leftAlone were already up to date, and $error refreshes were suspicious.\n" ); 00156 } 00157 } 00158 00163 function getConditions( $dbw ) { 00164 $conds = array(); 00165 00166 $end = $this->getOption( 'end', false ); 00167 $mime = $this->getOption( 'mime', false ); 00168 $like = $this->getOption( 'metadata-contains', false ); 00169 00170 if ( $end !== false ) { 00171 $conds[] = 'img_name <= ' . $dbw->addQuotes( $end ) ; 00172 } 00173 if ( $mime !== false ) { 00174 list( $major, $minor ) = File::splitMime( $mime ); 00175 $conds['img_major_mime'] = $major; 00176 if ( $minor !== '*' ) { 00177 $conds['img_minor_mime'] = $minor; 00178 } 00179 } 00180 if ( $like ) { 00181 $conds[] = 'img_metadata ' . $dbw->buildLike( $dbw->anyString(), $like, $dbw->anyString() ); 00182 } 00183 return $conds; 00184 } 00185 00190 function setupParameters( $force, $brokenOnly ) { 00191 global $wgUpdateCompatibleMetadata; 00192 00193 if ( $brokenOnly ) { 00194 $wgUpdateCompatibleMetadata = false; 00195 } else { 00196 $wgUpdateCompatibleMetadata = true; 00197 } 00198 00199 if ( $brokenOnly && $force ) { 00200 $this->error( 'Cannot use --broken-only and --force together. ', 2 ); 00201 } 00202 } 00203 } 00204 00205 00206 $maintClass = 'RefreshImageMetadata'; 00207 require_once( RUN_MAINTENANCE_IF_MAIN );