MediaWiki
REL1_22
|
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 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 00194 /* find user directly from source wiki, through MW's API */ 00195 $real_user = getFileUserFromSourceWiki( $options['source-wiki-url'], $base ); 00196 if ( $real_user === false ) { 00197 $wgUser = $user; 00198 } else { 00199 $wgUser = User::newFromName( $real_user ); 00200 if ( $wgUser === false ) { 00201 # user does not exist in target wiki 00202 echo "failed: user '$real_user' does not exist in target wiki."; 00203 continue; 00204 } 00205 } 00206 } else { 00207 # Find comment text 00208 $commentText = false; 00209 00210 if ( $commentExt ) { 00211 $f = findAuxFile( $file, $commentExt ); 00212 if ( !$f ) { 00213 echo " No comment file with extension {$commentExt} found for {$file}, using default comment. "; 00214 } else { 00215 $commentText = file_get_contents( $f ); 00216 if ( !$commentText ) { 00217 echo " Failed to load comment file {$f}, using default comment. "; 00218 } 00219 } 00220 } 00221 00222 if ( !$commentText ) { 00223 $commentText = $comment; 00224 } 00225 } 00226 00227 # Import the file 00228 if ( isset( $options['dry'] ) ) { 00229 echo " publishing {$file} by '" . $wgUser->getName() . "', comment '$commentText'... "; 00230 } else { 00231 $props = FSFile::getPropsFromPath( $file ); 00232 $flags = 0; 00233 $publishOptions = array(); 00234 $handler = MediaHandler::getHandler( $props['mime'] ); 00235 if ( $handler ) { 00236 $publishOptions['headers'] = $handler->getStreamHeaders( $props['metadata'] ); 00237 } else { 00238 $publishOptions['headers'] = array(); 00239 } 00240 $archive = $image->publish( $file, $flags, $publishOptions ); 00241 if ( !$archive->isGood() ) { 00242 echo "failed. (" . 00243 $archive->getWikiText() . 00244 ")\n"; 00245 $failed++; 00246 continue; 00247 } 00248 } 00249 00250 $commentText = SpecialUpload::getInitialPageText( $commentText, $license ); 00251 if ( !isset( $options['summary'] ) ) { 00252 $summary = $commentText; 00253 } 00254 00255 if ( isset( $options['dry'] ) ) { 00256 echo "done.\n"; 00257 } elseif ( $image->recordUpload2( $archive->value, $summary, $commentText, $props, $timestamp ) ) { 00258 # We're done! 00259 echo "done.\n"; 00260 00261 $doProtect = false; 00262 00263 global $wgRestrictionLevels; 00264 00265 $protectLevel = isset( $options['protect'] ) ? $options['protect'] : null; 00266 00267 if ( $protectLevel && in_array( $protectLevel, $wgRestrictionLevels ) ) { 00268 $doProtect = true; 00269 } 00270 if ( isset( $options['unprotect'] ) ) { 00271 $protectLevel = ''; 00272 $doProtect = true; 00273 } 00274 00275 if ( $doProtect ) { 00276 # Protect the file 00277 echo "\nWaiting for slaves...\n"; 00278 // Wait for slaves. 00279 sleep( 2.0 ); # Why this sleep? 00280 wfWaitForSlaves(); 00281 00282 echo "\nSetting image restrictions ... "; 00283 00284 $cascade = false; 00285 $restrictions = array(); 00286 foreach ( $title->getRestrictionTypes() as $type ) { 00287 $restrictions[$type] = $protectLevel; 00288 } 00289 00290 $page = WikiPage::factory( $title ); 00291 $status = $page->doUpdateRestrictions( $restrictions, array(), $cascade, '', $user ); 00292 echo ( $status->isOK() ? 'done' : 'failed' ) . "\n"; 00293 } 00294 00295 } else { 00296 echo "failed. (at recordUpload stage)\n"; 00297 $svar = 'failed'; 00298 } 00299 00300 $$svar++; 00301 $processed++; 00302 00303 if ( $limit && $processed >= $limit ) { 00304 break; 00305 } 00306 00307 if ( $sleep ) { 00308 sleep( $sleep ); 00309 } 00310 } 00311 00312 # Print out some statistics 00313 echo "\n"; 00314 foreach ( array( 'count' => 'Found', 'limit' => 'Limit', 'ignored' => 'Ignored', 00315 'added' => 'Added', 'skipped' => 'Skipped', 'overwritten' => 'Overwritten', 00316 'failed' => 'Failed' ) as $var => $desc ) { 00317 if ( $$var > 0 ) { 00318 echo "{$desc}: {$$var}\n"; 00319 } 00320 } 00321 00322 } else { 00323 echo "No suitable files could be found for import.\n"; 00324 } 00325 00326 exit( 0 ); 00327 00328 function showUsage( $reason = false ) { 00329 if ( $reason ) { 00330 echo $reason . "\n"; 00331 } 00332 00333 echo <<<TEXT 00334 Imports images and other media files into the wiki 00335 USAGE: php importImages.php [options] <dir> 00336 00337 <dir> : Path to the directory containing images to be imported 00338 00339 Options: 00340 --extensions=<exts> Comma-separated list of allowable extensions, defaults to \$wgFileExtensions 00341 --overwrite Overwrite existing images with the same name (default is to skip them) 00342 --limit=<num> Limit the number of images to process. Ignored or skipped images are not counted. 00343 --from=<name> Ignore all files until the one with the given name. Useful for resuming 00344 aborted imports. <name> should be the file's canonical database form. 00345 --skip-dupes Skip images that were already uploaded under a different name (check SHA1) 00346 --search-recursively Search recursively for files in subdirectories 00347 --sleep=<sec> Sleep between files. Useful mostly for debugging. 00348 --user=<username> Set username of uploader, default 'Maintenance script' 00349 --check-userblock Check if the user got blocked during import. 00350 --comment=<text> Set file description, default 'Importing file'. 00351 --comment-file=<file> Set description to the content of <file>. 00352 --comment-ext=<ext> Causes the description for each file to be loaded from a file with the same name 00353 but the extension <ext>. If a global description is also given, it is appended. 00354 --license=<code> Use an optional license template 00355 --dry Dry run, don't import anything 00356 --protect=<protect> Specify the protect value (autoconfirmed,sysop) 00357 --summary=<summary> Upload summary, description will be used if not provided 00358 --timestamp=<timestamp> Override upload time/date, all MediaWiki timestamp formats are accepted 00359 --unprotect Unprotects all uploaded images 00360 --source-wiki-url If specified, take User and Comment data for each imported file from this URL. 00361 For example, --source-wiki-url="http://en.wikipedia.org/" 00362 00363 TEXT; 00364 exit( 1 ); 00365 }