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