MediaWiki  REL1_21
importImages.php
Go to the documentation of this file.
00001 <?php
00034 $optionsWithArgs = array(
00035         'extensions', 'comment', 'comment-file', 'comment-ext', 'summary', 'user',
00036         'license', 'sleep', 'limit', 'from', 'source-wiki-url', 'timestamp',
00037 );
00038 require_once( __DIR__ . '/commandLine.inc' );
00039 require_once( __DIR__ . '/importImages.inc' );
00040 $processed = $added = $ignored = $skipped = $overwritten = $failed = 0;
00041 
00042 echo( "Import Images\n\n" );
00043 
00044 # Need a path
00045 if ( count( $args ) == 0 ) {
00046         showUsage();
00047 }
00048 
00049 $dir = $args[0];
00050 
00051 # Check Protection
00052 if ( isset( $options['protect'] ) && isset( $options['unprotect'] ) ) {
00053         die( "Cannot specify both protect and unprotect.  Only 1 is allowed.\n" );
00054 }
00055 
00056 if ( isset( $options['protect'] ) && $options['protect'] == 1 ) {
00057         die( "You must specify a protection option.\n" );
00058 }
00059 
00060 # Prepare the list of allowed extensions
00061 global $wgFileExtensions;
00062 $extensions = isset( $options['extensions'] )
00063         ? explode( ',', strtolower( $options['extensions'] ) )
00064         : $wgFileExtensions;
00065 
00066 # Search the path provided for candidates for import
00067 $files = findFiles( $dir, $extensions, isset( $options['search-recursively'] ) );
00068 
00069 # Initialise the user for this operation
00070 $user = isset( $options['user'] )
00071         ? User::newFromName( $options['user'] )
00072         : User::newFromName( 'Maintenance script' );
00073 if ( !$user instanceof User ) {
00074         $user = User::newFromName( 'Maintenance script' );
00075 }
00076 $wgUser = $user;
00077 
00078 # Get block check. If a value is given, this specified how often the check is performed
00079 if ( isset( $options['check-userblock'] ) ) {
00080         if ( !$options['check-userblock'] ) {
00081                 $checkUserBlock = 1;
00082         } else {
00083                 $checkUserBlock = (int)$options['check-userblock'];
00084         }
00085 } else {
00086         $checkUserBlock = false;
00087 }
00088 
00089 # Get --from
00090 $from = @$options['from'];
00091 
00092 # Get sleep time.
00093 $sleep = @$options['sleep'];
00094 if ( $sleep ) {
00095         $sleep = (int)$sleep;
00096 }
00097 
00098 # Get limit number
00099 $limit = @$options['limit'];
00100 if ( $limit ) {
00101         $limit = (int)$limit;
00102 }
00103 
00104 $timestamp = isset( $options['timestamp'] ) ? $options['timestamp'] : false;
00105 
00106 # Get the upload comment. Provide a default one in case there's no comment given.
00107 $comment = 'Importing image file';
00108 
00109 if ( isset( $options['comment-file'] ) ) {
00110         $comment =  file_get_contents( $options['comment-file'] );
00111         if ( $comment === false || $comment === null ) {
00112                 die( "failed to read comment file: {$options['comment-file']}\n" );
00113         }
00114 } elseif ( isset( $options['comment'] ) ) {
00115         $comment =  $options['comment'];
00116 }
00117 
00118 $commentExt = isset( $options['comment-ext'] ) ? $options['comment-ext'] : false;
00119 
00120 $summary = isset( $options['summary'] ) ? $options['summary'] : '';
00121 
00122 # Get the license specifier
00123 $license = isset( $options['license'] ) ? $options['license'] : '';
00124 
00125 # Batch "upload" operation
00126 $count = count( $files );
00127 if ( $count > 0 ) {
00128 
00129         foreach ( $files as $file ) {
00130                 $base = wfBaseName( $file );
00131 
00132                 # Validate a title
00133                 $title = Title::makeTitleSafe( NS_FILE, $base );
00134                 if ( !is_object( $title ) ) {
00135                         echo( "{$base} could not be imported; a valid title cannot be produced\n" );
00136                         continue;
00137                 }
00138 
00139                 if ( $from ) {
00140                         if ( $from == $title->getDBkey() ) {
00141                                 $from = null;
00142                         } else {
00143                                 $ignored++;
00144                                 continue;
00145                         }
00146                 }
00147 
00148                 if ( $checkUserBlock && ( ( $processed % $checkUserBlock ) == 0 ) ) {
00149                         $user->clearInstanceCache( 'name' ); // reload from DB!
00150                         if ( $user->isBlocked() ) {
00151                                 echo( $user->getName() . " was blocked! Aborting.\n" );
00152                                 break;
00153                         }
00154                 }
00155 
00156                 # Check existence
00157                 $image = wfLocalFile( $title );
00158                 if ( $image->exists() ) {
00159                         if ( isset( $options['overwrite'] ) ) {
00160                                 echo( "{$base} exists, overwriting..." );
00161                                 $svar = 'overwritten';
00162                         } else {
00163                                 echo( "{$base} exists, skipping\n" );
00164                                 $skipped++;
00165                                 continue;
00166                         }
00167                 } else {
00168                         if ( isset( $options['skip-dupes'] ) ) {
00169                                 $repo = $image->getRepo();
00170                                 $sha1 = File::sha1Base36( $file ); # XXX: we end up calculating this again when actually uploading. that sucks.
00171 
00172                                 $dupes = $repo->findBySha1( $sha1 );
00173 
00174                                 if ( $dupes ) {
00175                                         echo( "{$base} already exists as " . $dupes[0]->getName() . ", skipping\n" );
00176                                         $skipped++;
00177                                         continue;
00178                                 }
00179                         }
00180 
00181                         echo( "Importing {$base}..." );
00182                         $svar = 'added';
00183                 }
00184 
00185                 if ( isset( $options['source-wiki-url'] ) ) {
00186                         /* find comment text directly from source wiki, through MW's API */
00187                         $real_comment = getFileCommentFromSourceWiki( $options['source-wiki-url'], $base );
00188                         if ( $real_comment === false )
00189                                 $commentText = $comment;
00190                         else
00191                                 $commentText = $real_comment;
00192 
00193                         /* find user directly from source wiki, through MW's API */
00194                         $real_user = getFileUserFromSourceWiki( $options['source-wiki-url'], $base );
00195                         if ( $real_user === false ) {
00196                                 $wgUser = $user;
00197                         } else {
00198                                 $wgUser = User::newFromName( $real_user );
00199                                 if ( $wgUser === false ) {
00200                                         # user does not exist in target wiki
00201                                         echo ( "failed: user '$real_user' does not exist in target wiki." );
00202                                         continue;
00203                                 }
00204                         }
00205                 } else {
00206                         # Find comment text
00207                         $commentText = false;
00208 
00209                         if ( $commentExt ) {
00210                                 $f = findAuxFile( $file, $commentExt );
00211                                 if ( !$f ) {
00212                                         echo( " No comment file with extension {$commentExt} found for {$file}, using default comment. " );
00213                                 } else {
00214                                         $commentText = file_get_contents( $f );
00215                                         if ( !$commentText ) {
00216                                                 echo( " Failed to load comment file {$f}, using default comment. " );
00217                                         }
00218                                 }
00219                         }
00220 
00221                         if ( !$commentText ) {
00222                                 $commentText = $comment;
00223                         }
00224                 }
00225 
00226                 # Import the file
00227                 if ( isset( $options['dry'] ) ) {
00228                         echo( " publishing {$file} by '" . $wgUser->getName() . "', comment '$commentText'... " );
00229                 } else {
00230                         $archive = $image->publish( $file );
00231                         if ( !$archive->isGood() ) {
00232                                 echo( "failed. (" .
00233                                         $archive->getWikiText() .
00234                                         ")\n" );
00235                                 $failed++;
00236                                 continue;
00237                         }
00238                 }
00239 
00240                 $commentText = SpecialUpload::getInitialPageText( $commentText, $license );
00241                 if ( !$summary ) {
00242                         $summary = $commentText;
00243                 }
00244 
00245                 if ( isset( $options['dry'] ) ) {
00246                         echo( "done.\n" );
00247                 } elseif ( $image->recordUpload2( $archive->value, $summary, $commentText, false, $timestamp ) ) {
00248                         # We're done!
00249                         echo( "done.\n" );
00250 
00251                         $doProtect = false;
00252 
00253                         global $wgRestrictionLevels;
00254 
00255                         $protectLevel = isset( $options['protect'] ) ? $options['protect'] : null;
00256 
00257                         if ( $protectLevel && in_array( $protectLevel, $wgRestrictionLevels ) ) {
00258                                 $doProtect = true;
00259                         }
00260                         if ( isset( $options['unprotect'] ) ) {
00261                                 $protectLevel = '';
00262                                 $doProtect = true;
00263                         }
00264 
00265                         if ( $doProtect ) {
00266                                         # Protect the file
00267                                         echo "\nWaiting for slaves...\n";
00268                                         // Wait for slaves.
00269                                         sleep( 2.0 ); # Why this sleep?
00270                                         wfWaitForSlaves();
00271 
00272                                         echo( "\nSetting image restrictions ... " );
00273 
00274                                         $cascade = false;
00275                                         $restrictions = array();
00276                                         foreach( $title->getRestrictionTypes() as $type ) {
00277                                                 $restrictions[$type] = $protectLevel;
00278                                         }
00279 
00280                                         $page = WikiPage::factory( $title );
00281                                         $status = $page->doUpdateRestrictions( $restrictions, array(), $cascade, '', $user );
00282                                         echo( ( $status->isOK() ? 'done' : 'failed' ) . "\n" );
00283                         }
00284 
00285                 } else {
00286                         echo( "failed. (at recordUpload stage)\n" );
00287                         $svar = 'failed';
00288                 }
00289 
00290                 $$svar++;
00291                 $processed++;
00292 
00293                 if ( $limit && $processed >= $limit ) {
00294                         break;
00295                 }
00296 
00297                 if ( $sleep ) {
00298                         sleep( $sleep );
00299                 }
00300         }
00301 
00302         # Print out some statistics
00303         echo( "\n" );
00304         foreach ( array( 'count' => 'Found', 'limit' => 'Limit', 'ignored' => 'Ignored',
00305                 'added' => 'Added', 'skipped' => 'Skipped', 'overwritten' => 'Overwritten',
00306                 'failed' => 'Failed' ) as $var => $desc ) {
00307                 if ( $$var > 0 )
00308                         echo( "{$desc}: {$$var}\n" );
00309         }
00310 
00311 } else {
00312         echo( "No suitable files could be found for import.\n" );
00313 }
00314 
00315 exit( 0 );
00316 
00317 function showUsage( $reason = false ) {
00318         if ( $reason ) {
00319                 echo( $reason . "\n" );
00320         }
00321 
00322         echo <<<TEXT
00323 Imports images and other media files into the wiki
00324 USAGE: php importImages.php [options] <dir>
00325 
00326 <dir> : Path to the directory containing images to be imported
00327 
00328 Options:
00329 --extensions=<exts>     Comma-separated list of allowable extensions, defaults to \$wgFileExtensions
00330 --overwrite             Overwrite existing images with the same name (default is to skip them)
00331 --limit=<num>           Limit the number of images to process. Ignored or skipped images are not counted.
00332 --from=<name>           Ignore all files until the one with the given name. Useful for resuming
00333                         aborted imports. <name> should be the file's canonical database form.
00334 --skip-dupes            Skip images that were already uploaded under a different name (check SHA1)
00335 --search-recursively    Search recursively for files in subdirectories
00336 --sleep=<sec>           Sleep between files. Useful mostly for debugging.
00337 --user=<username>       Set username of uploader, default 'Maintenance script'
00338 --check-userblock       Check if the user got blocked during import.
00339 --comment=<text>        Set file description, default 'Importing image file'.
00340 --comment-file=<file>   Set description to the content of <file>.
00341 --comment-ext=<ext>     Causes the description for each file to be loaded from a file with the same name
00342                         but the extension <ext>. If a global description is also given, it is appended.
00343 --license=<code>        Use an optional license template
00344 --dry                   Dry run, don't import anything
00345 --protect=<protect>     Specify the protect value (autoconfirmed,sysop)
00346 --summary=<summary>     Upload summary, description will be used if not provided
00347 --timestamp=<timestamp> Override upload time/date, all MediaWiki timestamp formats are accepted
00348 --unprotect             Unprotects all uploaded images
00349 --source-wiki-url       If specified, take User and Comment data for each imported file from this URL.
00350                         For example, --source-wiki-url="http://en.wikipedia.org/"
00351 
00352 TEXT;
00353         exit( 1 );
00354 }