30require_once __DIR__ .
'/Maintenance.php';
49 parent::__construct();
51 $this->
addDescription(
'Script to update image metadata records' );
56 'Reload metadata from file even if the metadata looks ok',
63 'Only fix really broken records, leave old but still compatible records alone.'
67 'Fix records with an out of date serialization format.'
71 'Enable splitting out large metadata items to the text table. Implies --convert-to-json.'
75 'Output extra information about each upgraded/non-upgraded file.',
80 $this->
addOption(
'start',
'Name of file to start with',
false,
true );
81 $this->
addOption(
'end',
'Name of file to end with',
false,
true );
85 'Only refresh files with this media type, e.g. BITMAP, UNKNOWN etc.',
91 "Only refresh files with this MIME type. Can accept wild-card 'image/*'. "
92 .
"Potentially inefficient unless 'mediatype' is also specified",
98 '(Inefficient!) Only refresh files where the img_metadata field '
99 .
'contains this string. Can be used if its known a specific '
100 .
'property was being extracted incorrectly.',
106 'Time to sleep between each batch (in seconds). Default: 0',
110 $this->
addOption(
'oldimage',
'Run and refresh on oldimage table.' );
115 $brokenOnly = $this->
hasOption(
'broken-only' );
116 $verbose = $this->
hasOption(
'verbose' );
117 $start = $this->
getOption(
'start',
false );
119 $sleep = (int)$this->
getOption(
'sleep', 0 );
120 $reserialize = $this->
hasOption(
'convert-to-json' );
121 $oldimage = $this->
hasOption(
'oldimage' );
123 $fieldPrefix =
'oi_';
124 $fileQuery = OldLocalFile::getQueryInfo();
126 $fieldPrefix =
'img_';
127 $fileQuery = LocalFile::getQueryInfo();
136 if ( $batchSize <= 0 ) {
137 $this->
fatalError(
"Batch size is too low...", 12 );
140 $repo = $this->newLocalRepo( $force, $brokenOnly, $reserialize, $split );
141 $conds = $this->getConditions(
$dbw, $fieldPrefix );
145 if ( $start !==
false ) {
146 $conds2[] = $fieldPrefix .
'name >= ' .
$dbw->
addQuotes( $start );
150 'LIMIT' => $batchSize,
151 'ORDER BY' => $fieldPrefix .
'name ASC',
154 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
158 $fileQuery[
'tables'],
159 $fileQuery[
'fields'],
160 array_merge( $conds, $conds2 ),
166 $nameField = $fieldPrefix .
'name';
167 if (
$res->numRows() > 0 ) {
168 $row1 =
$res->current();
169 $this->
output(
"Processing next {$res->numRows()} row(s) starting with {$row1->$nameField}.\n" );
173 foreach (
$res as $row ) {
176 $file = $repo->newFileFromRow( $row );
177 $file->maybeUpgradeRow();
178 if (
$file->getUpgraded() ) {
181 $this->
output(
"Refreshed File:{$row->$nameField}.\n" );
187 $this->
output(
"Forcibly refreshed File:{$row->$nameField}.\n" );
191 $this->
output(
"Skipping File:{$row->$nameField}.\n" );
195 }
catch ( Exception $e ) {
196 $this->
output(
"{$row->$nameField} failed. {$e->getMessage()}\n" );
199 if (
$res->numRows() > 0 ) {
201 $conds2 = [ $fieldPrefix .
'name > ' .
$dbw->
addQuotes( $row->$nameField ) ];
203 $lbFactory->waitForReplication();
207 }
while (
$res->numRows() === $batchSize );
209 $total = $upgraded + $leftAlone;
211 $this->
output(
"\nFinished refreshing file metadata for $total files. "
212 .
"$upgraded needed to be refreshed, $leftAlone did not need to "
213 .
"be but were refreshed anyways, and $error refreshes were suspicious.\n" );
215 $this->
output(
"\nFinished refreshing file metadata for $total files. "
216 .
"$upgraded were refreshed, $leftAlone were already up to date, "
217 .
"and $error refreshes were suspicious.\n" );
226 private function getConditions(
$dbw, $fieldPrefix ) {
231 $mediatype = $this->
getOption(
'mediatype',
false );
232 $like = $this->
getOption(
'metadata-contains',
false );
234 if ( $end !==
false ) {
235 $conds[] = $fieldPrefix .
'name <= ' .
$dbw->
addQuotes( $end );
237 if (
$mime !==
false ) {
239 $conds[$fieldPrefix .
'major_mime'] = $major;
240 if ( $minor !==
'*' ) {
241 $conds[$fieldPrefix .
'minor_mime'] = $minor;
244 if ( $mediatype !==
false ) {
245 $conds[$fieldPrefix .
'media_type'] = $mediatype;
262 private function newLocalRepo( $force, $brokenOnly, $reserialize, $split ):
LocalRepo {
263 if ( $brokenOnly && $force ) {
264 $this->
fatalError(
'Cannot use --broken-only and --force together. ', 2 );
266 $reserialize = $reserialize || $split;
267 if ( $brokenOnly && $reserialize ) {
268 $this->
fatalError(
'Cannot use --broken-only with --convert-to-json or --split. ',
273 'updateCompatibleMetadata' => !$brokenOnly,
275 if ( $reserialize ) {
276 $overrides[
'reserializeMetadata'] =
true;
277 $overrides[
'useJsonMetadata'] =
true;
280 $overrides[
'useSplitMetadata'] =
true;
283 return MediaWikiServices::getInstance()->getRepoGroup()
284 ->newCustomLocalRepo( $overrides );
289require_once RUN_MAINTENANCE_IF_MAIN;
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
static splitMime(?string $mime)
Split an internet media type into its two components; if not a two-part name, set the minor type to '...
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
output( $out, $channel=null)
Throw some output to the user.
hasOption( $name)
Checks to see if a particular option was set.
getBatchSize()
Returns batch size.
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
Advanced database interface for IDatabase handles that include maintenance methods.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.