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