MediaWiki REL1_30
rebuildImages.php
Go to the documentation of this file.
1<?php
33require_once __DIR__ . '/Maintenance.php';
34
36
43
47 protected $dbw;
48
49 function __construct() {
50 parent::__construct();
51
53 // make sure to update old, but compatible img_metadata fields.
55
56 $this->addDescription( 'Script to update image metadata records' );
57
58 $this->addOption( 'missing', 'Check for files without associated database record' );
59 $this->addOption( 'dry-run', 'Only report, don\'t update the database' );
60 }
61
62 public function execute() {
63 $this->dbw = $this->getDB( DB_MASTER );
64 $this->dryrun = $this->hasOption( 'dry-run' );
65 if ( $this->dryrun ) {
66 MediaWiki\MediaWikiServices::getInstance()->getReadOnlyMode()
67 ->setReason( 'Dry run mode, image upgrades are suppressed' );
68 }
69
70 if ( $this->hasOption( 'missing' ) ) {
71 $this->crawlMissing();
72 } else {
73 $this->build();
74 }
75 }
76
80 function getRepo() {
81 if ( !isset( $this->repo ) ) {
82 $this->repo = RepoGroup::singleton()->getLocalRepo();
83 }
84
85 return $this->repo;
86 }
87
88 function build() {
89 $this->buildImage();
90 $this->buildOldImage();
91 }
92
93 function init( $count, $table ) {
94 $this->processed = 0;
95 $this->updated = 0;
96 $this->count = $count;
97 $this->startTime = microtime( true );
98 $this->table = $table;
99 }
100
101 function progress( $updated ) {
102 $this->updated += $updated;
103 $this->processed++;
104 if ( $this->processed % 100 != 0 ) {
105 return;
106 }
107 $portion = $this->processed / $this->count;
108 $updateRate = $this->updated / $this->processed;
109
110 $now = microtime( true );
111 $delta = $now - $this->startTime;
112 $estimatedTotalTime = $delta / $portion;
113 $eta = $this->startTime + $estimatedTotalTime;
114 $rate = $this->processed / $delta;
115
116 $this->output( sprintf( "%s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec <%.2f%% updated>\n",
117 wfTimestamp( TS_DB, intval( $now ) ),
118 $portion * 100.0,
119 $this->table,
120 wfTimestamp( TS_DB, intval( $eta ) ),
121 $this->processed,
122 $this->count,
123 $rate,
124 $updateRate * 100.0 ) );
125 flush();
126 }
127
128 function buildTable( $table, $key, $callback ) {
129 $count = $this->dbw->selectField( $table, 'count(*)', '', __METHOD__ );
130 $this->init( $count, $table );
131 $this->output( "Processing $table...\n" );
132
133 $result = $this->getDB( DB_REPLICA )->select( $table, '*', [], __METHOD__ );
134
135 foreach ( $result as $row ) {
136 $update = call_user_func( $callback, $row, null );
137 if ( $update ) {
138 $this->progress( 1 );
139 } else {
140 $this->progress( 0 );
141 }
142 }
143 $this->output( "Finished $table... $this->updated of $this->processed rows updated\n" );
144 }
145
146 function buildImage() {
147 $callback = [ $this, 'imageCallback' ];
148 $this->buildTable( 'image', 'img_name', $callback );
149 }
150
151 function imageCallback( $row, $copy ) {
152 // Create a File object from the row
153 // This will also upgrade it
154 $file = $this->getRepo()->newFileFromRow( $row );
155
156 return $file->getUpgraded();
157 }
158
159 function buildOldImage() {
160 $this->buildTable( 'oldimage', 'oi_archive_name', [ $this, 'oldimageCallback' ] );
161 }
162
163 function oldimageCallback( $row, $copy ) {
164 // Create a File object from the row
165 // This will also upgrade it
166 if ( $row->oi_archive_name == '' ) {
167 $this->output( "Empty oi_archive_name for oi_name={$row->oi_name}\n" );
168
169 return false;
170 }
171 $file = $this->getRepo()->newFileFromRow( $row );
172
173 return $file->getUpgraded();
174 }
175
176 function crawlMissing() {
177 $this->getRepo()->enumFiles( [ $this, 'checkMissingImage' ] );
178 }
179
180 function checkMissingImage( $fullpath ) {
181 $filename = wfBaseName( $fullpath );
182 $row = $this->dbw->selectRow( 'image',
183 [ 'img_name' ],
184 [ 'img_name' => $filename ],
185 __METHOD__ );
186
187 if ( !$row ) { // file not registered
188 $this->addMissingImage( $filename, $fullpath );
189 }
190 }
191
192 function addMissingImage( $filename, $fullpath ) {
193 global $wgContLang;
194
195 $timestamp = $this->dbw->timestamp( $this->getRepo()->getFileTimestamp( $fullpath ) );
196
197 $altname = $wgContLang->checkTitleEncoding( $filename );
198 if ( $altname != $filename ) {
199 if ( $this->dryrun ) {
200 $filename = $altname;
201 $this->output( "Estimating transcoding... $altname\n" );
202 } else {
203 # @todo FIXME: create renameFile()
204 $filename = $this->renameFile( $filename );
205 }
206 }
207
208 if ( $filename == '' ) {
209 $this->output( "Empty filename for $fullpath\n" );
210
211 return;
212 }
213 if ( !$this->dryrun ) {
214 $file = wfLocalFile( $filename );
215 if ( !$file->recordUpload(
216 '',
217 '(recovered file, missing upload log entry)',
218 '',
219 '',
220 '',
221 false,
222 $timestamp
223 ) ) {
224 $this->output( "Error uploading file $fullpath\n" );
225
226 return;
227 }
228 }
229 $this->output( $fullpath . "\n" );
230 }
231}
232
233$maintClass = 'ImageBuilder';
234require_once RUN_MAINTENANCE_IF_MAIN;
$wgUpdateCompatibleMetadata
If to automatically update the img_metadata field if the metadata field is outdated but compatible wi...
wfBaseName( $path, $suffix='')
Return the final portion of a pathname.
wfLocalFile( $title)
Get an object referring to a locally registered file.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Maintenance script to update image metadata records.
__construct()
Default constructor.
oldimageCallback( $row, $copy)
buildTable( $table, $key, $callback)
checkMissingImage( $fullpath)
IMaintainableDatabase $dbw
imageCallback( $row, $copy)
progress( $updated)
execute()
Do the actual work.
init( $count, $table)
addMissingImage( $filename, $fullpath)
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
getDB( $db, $groups=[], $wiki=false)
Returns a database to be used by current maintenance script.
hasOption( $name)
Checks to see if a particular param exists.
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
static singleton()
Get a RepoGroup instance.
Definition RepoGroup.php:59
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global then executing the whole list after the page is displayed We don t do anything smart like collating updates to the same table or such because the list is almost always going to have just one item on if so it s not worth the trouble Since there is a job queue in the jobs table
Definition deferred.txt:16
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
Definition design.txt:57
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add in any and then calling output() to send it all. It could be easily changed to send incrementally if that becomes useful
Advanced database interface for IDatabase handles that include maintenance methods.
require_once RUN_MAINTENANCE_IF_MAIN
const DB_REPLICA
Definition defines.php:25
const DB_MASTER
Definition defines.php:26
$maintClass