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