[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/maintenance/ -> rebuildImages.php (source)

   1  <?php
   2  /**
   3   * Update image metadata records.
   4   *
   5   * Usage: php rebuildImages.php [--missing] [--dry-run]
   6   * Options:
   7   *   --missing  Crawl the uploads dir for images without records, and
   8   *              add them only.
   9   *
  10   * Copyright © 2005 Brion Vibber <[email protected]>
  11   * https://www.mediawiki.org/
  12   *
  13   * This program is free software; you can redistribute it and/or modify
  14   * it under the terms of the GNU General Public License as published by
  15   * the Free Software Foundation; either version 2 of the License, or
  16   * (at your option) any later version.
  17   *
  18   * This program is distributed in the hope that it will be useful,
  19   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21   * GNU General Public License for more details.
  22   *
  23   * You should have received a copy of the GNU General Public License along
  24   * with this program; if not, write to the Free Software Foundation, Inc.,
  25   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  26   * http://www.gnu.org/copyleft/gpl.html
  27   *
  28   * @file
  29   * @author Brion Vibber <brion at pobox.com>
  30   * @ingroup Maintenance
  31   */
  32  
  33  require_once  __DIR__ . '/Maintenance.php';
  34  
  35  /**
  36   * Maintenance script to update image metadata records.
  37   *
  38   * @ingroup Maintenance
  39   */
  40  class ImageBuilder extends Maintenance {
  41  
  42      /**
  43       * @var DatabaseBase
  44       */
  45      protected $dbw;
  46  
  47  	function __construct() {
  48          parent::__construct();
  49  
  50          global $wgUpdateCompatibleMetadata;
  51          //make sure to update old, but compatible img_metadata fields.
  52          $wgUpdateCompatibleMetadata = true;
  53  
  54          $this->mDescription = 'Script to update image metadata records';
  55  
  56          $this->addOption( 'missing', 'Check for files without associated database record' );
  57          $this->addOption( 'dry-run', 'Only report, don\'t update the database' );
  58      }
  59  
  60  	public function execute() {
  61          $this->dbw = wfGetDB( DB_MASTER );
  62          $this->maxLag = 10; # if slaves are lagged more than 10 secs, wait
  63          $this->dryrun = $this->hasOption( 'dry-run' );
  64          if ( $this->dryrun ) {
  65              $GLOBALS['wgReadOnly'] = 'Dry run mode, image upgrades are suppressed';
  66          }
  67  
  68          if ( $this->hasOption( 'missing' ) ) {
  69              $this->crawlMissing();
  70          } else {
  71              $this->build();
  72          }
  73      }
  74  
  75      /**
  76       * @return FileRepo
  77       */
  78  	function getRepo() {
  79          if ( !isset( $this->repo ) ) {
  80              $this->repo = RepoGroup::singleton()->getLocalRepo();
  81          }
  82  
  83          return $this->repo;
  84      }
  85  
  86  	function build() {
  87          $this->buildImage();
  88          $this->buildOldImage();
  89      }
  90  
  91  	function init( $count, $table ) {
  92          $this->processed = 0;
  93          $this->updated = 0;
  94          $this->count = $count;
  95          $this->startTime = microtime( true );
  96          $this->table = $table;
  97      }
  98  
  99  	function progress( $updated ) {
 100          $this->updated += $updated;
 101          $this->processed++;
 102          if ( $this->processed % 100 != 0 ) {
 103              return;
 104          }
 105          $portion = $this->processed / $this->count;
 106          $updateRate = $this->updated / $this->processed;
 107  
 108          $now = microtime( true );
 109          $delta = $now - $this->startTime;
 110          $estimatedTotalTime = $delta / $portion;
 111          $eta = $this->startTime + $estimatedTotalTime;
 112          $rate = $this->processed / $delta;
 113  
 114          $this->output( sprintf( "%s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec <%.2f%% updated>\n",
 115              wfTimestamp( TS_DB, intval( $now ) ),
 116              $portion * 100.0,
 117              $this->table,
 118              wfTimestamp( TS_DB, intval( $eta ) ),
 119              $this->processed,
 120              $this->count,
 121              $rate,
 122              $updateRate * 100.0 ) );
 123          flush();
 124      }
 125  
 126  	function buildTable( $table, $key, $callback ) {
 127          $count = $this->dbw->selectField( $table, 'count(*)', '', __METHOD__ );
 128          $this->init( $count, $table );
 129          $this->output( "Processing $table...\n" );
 130  
 131          $result = wfGetDB( DB_SLAVE )->select( $table, '*', array(), __METHOD__ );
 132  
 133          foreach ( $result as $row ) {
 134              $update = call_user_func( $callback, $row, null );
 135              if ( $update ) {
 136                  $this->progress( 1 );
 137              } else {
 138                  $this->progress( 0 );
 139              }
 140          }
 141          $this->output( "Finished $table... $this->updated of $this->processed rows updated\n" );
 142      }
 143  
 144  	function buildImage() {
 145          $callback = array( $this, 'imageCallback' );
 146          $this->buildTable( 'image', 'img_name', $callback );
 147      }
 148  
 149  	function imageCallback( $row, $copy ) {
 150          // Create a File object from the row
 151          // This will also upgrade it
 152          $file = $this->getRepo()->newFileFromRow( $row );
 153  
 154          return $file->getUpgraded();
 155      }
 156  
 157  	function buildOldImage() {
 158          $this->buildTable( 'oldimage', 'oi_archive_name', array( $this, 'oldimageCallback' ) );
 159      }
 160  
 161  	function oldimageCallback( $row, $copy ) {
 162          // Create a File object from the row
 163          // This will also upgrade it
 164          if ( $row->oi_archive_name == '' ) {
 165              $this->output( "Empty oi_archive_name for oi_name={$row->oi_name}\n" );
 166  
 167              return false;
 168          }
 169          $file = $this->getRepo()->newFileFromRow( $row );
 170  
 171          return $file->getUpgraded();
 172      }
 173  
 174  	function crawlMissing() {
 175          $this->getRepo()->enumFiles( array( $this, 'checkMissingImage' ) );
 176      }
 177  
 178  	function checkMissingImage( $fullpath ) {
 179          $filename = wfBaseName( $fullpath );
 180          $row = $this->dbw->selectRow( 'image',
 181              array( 'img_name' ),
 182              array( 'img_name' => $filename ),
 183              __METHOD__ );
 184  
 185          if ( !$row ) { // file not registered
 186              $this->addMissingImage( $filename, $fullpath );
 187          }
 188      }
 189  
 190  	function addMissingImage( $filename, $fullpath ) {
 191          global $wgContLang;
 192  
 193          $timestamp = $this->dbw->timestamp( $this->getRepo()->getFileTimestamp( $fullpath ) );
 194  
 195          $altname = $wgContLang->checkTitleEncoding( $filename );
 196          if ( $altname != $filename ) {
 197              if ( $this->dryrun ) {
 198                  $filename = $altname;
 199                  $this->output( "Estimating transcoding... $altname\n" );
 200              } else {
 201                  # @todo FIXME: create renameFile()
 202                  $filename = $this->renameFile( $filename );
 203              }
 204          }
 205  
 206          if ( $filename == '' ) {
 207              $this->output( "Empty filename for $fullpath\n" );
 208  
 209              return;
 210          }
 211          if ( !$this->dryrun ) {
 212              $file = wfLocalFile( $filename );
 213              if ( !$file->recordUpload(
 214                  '',
 215                  '(recovered file, missing upload log entry)',
 216                  '',
 217                  '',
 218                  '',
 219                  false,
 220                  $timestamp
 221              ) ) {
 222                  $this->output( "Error uploading file $fullpath\n" );
 223  
 224                  return;
 225              }
 226          }
 227          $this->output( $fullpath . "\n" );
 228      }
 229  }
 230  
 231  $maintClass = 'ImageBuilder';
 232  require_once RUN_MAINTENANCE_IF_MAIN;


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1