137 $permissionManager = $services->getPermissionManager();
149 $this->
output(
"Importing Files\n\n" );
151 $dir = $this->
getArg( 0 );
155 $this->
fatalError(
"Cannot specify both protect and unprotect. Only 1 is allowed.\n" );
159 $this->
fatalError(
"You must specify a protection option.\n" );
162 # Prepare the list of allowed extensions
163 $extensions = $this->
hasOption(
'extensions' )
164 ? explode(
',', strtolower( $this->
getOption(
'extensions' ) ) )
165 : $this->
getConfig()->get( MainConfigNames::FileExtensions );
167 # Search the path provided for candidates for import
168 $files = $this->findFiles( $dir, $extensions, $this->
hasOption(
'search-recursively' ) );
169 if ( !$files->valid() ) {
170 $this->
output(
"No suitable files could be found for import.\n" );
174 # Initialise the user for this operation
176 ? User::newFromName( $this->
getOption(
'user' ) )
177 : User::newSystemUser( User::MAINTENANCE_SCRIPT_USER, [
'steal' =>
true ] );
178 if ( !$user instanceof
User ) {
179 $user = User::newSystemUser( User::MAINTENANCE_SCRIPT_USER, [
'steal' =>
true ] );
181 '@phan-var User $user';
182 StubGlobalUser::setUser( $user );
184 # Get block check. If a value is given, this specified how often the check is performed
185 $checkUserBlock = (int)$this->
getOption(
'check-userblock' );
188 $sleep = (int)$this->
getOption(
'sleep' );
189 $limit = (int)$this->
getOption(
'limit' );
190 $timestamp = $this->
getOption(
'timestamp',
false );
192 # Get the upload comment. Provide a default one in case there's no comment given.
193 $commentFile = $this->
getOption(
'comment-file' );
194 if ( $commentFile !==
null ) {
195 $comment = file_get_contents( $commentFile );
196 if ( $comment ===
false || $comment ===
null ) {
197 $this->
fatalError(
"failed to read comment file: {$commentFile}\n" );
200 $comment = $this->
getOption(
'comment',
'Importing file' );
202 $commentExt = $this->
getOption(
'comment-ext' );
203 $summary = $this->
getOption(
'summary',
'' );
204 $license = $this->
getOption(
'license',
'' );
205 $sourceWikiUrl = $this->
getOption(
'source-wiki-url' );
214 # Batch "upload" operation
215 $restrictionStore = $services->getRestrictionStore();
216 foreach ( $files as $file ) {
218 if ( $sleep && ( $processed > 0 ) ) {
222 $base = UtfNormal\Validator::cleanUp(
wfBaseName( $file ) );
225 $title = Title::makeTitleSafe(
NS_FILE, $base );
228 "{$base} could not be imported; a valid title cannot be produced\n"
234 if ( $from !== $title->getDBkey() ) {
235 $statistics[
'ignored']++;
242 if ( $checkUserBlock && ( ( $processed % $checkUserBlock ) == 0 ) ) {
243 $user->clearInstanceCache(
'name' );
244 if ( $permissionManager->isBlockedFrom( $user, $title ) ) {
246 "{$user->getName()} is blocked from {$title->getPrefixedText()}! skipping.\n"
248 $statistics[
'skipped']++;
254 $image = $services->getRepoGroup()->getLocalRepo()
256 if ( $image->exists() ) {
258 $this->
output(
"{$base} exists, overwriting..." );
259 $svar =
'overwritten';
261 $this->
output(
"{$base} exists, skipping\n" );
262 $statistics[
'skipped']++;
266 if ( $this->
hasOption(
'skip-dupes' ) ) {
267 $repo = $image->getRepo();
268 # XXX: we end up calculating this again when actually uploading. that sucks.
269 $sha1 = FSFile::getSha1Base36FromPath( $file );
270 $dupes = $repo->findBySha1( $sha1 );
273 "{$base} already exists as {$dupes[0]->getName()}, skipping\n"
275 $statistics[
'skipped']++;
280 $this->
output(
"Importing {$base}..." );
284 if ( $sourceWikiUrl ) {
286 $real_comment = $this->getFileCommentFromSourceWiki( $sourceWikiUrl, $base );
287 $commentText = $real_comment !==
false ? $real_comment : $comment;
290 $real_user = $this->getFileUserFromSourceWiki( $sourceWikiUrl, $base );
291 if ( $real_user !==
false ) {
292 $realUser = User::newFromName( $real_user );
293 if ( $realUser ===
false ) {
294 # user does not exist in target wiki
296 "failed: user '$real_user' does not exist in target wiki."
300 StubGlobalUser::setUser( $realUser );
305 $commentText =
false;
308 $f = $this->findAuxFile( $file, $commentExt );
310 $this->
output(
" No comment file with extension {$commentExt} found "
311 .
"for {$file}, using default comment." );
313 $commentText = file_get_contents( $f );
314 if ( !$commentText ) {
316 " Failed to load comment file {$f}, using default comment."
322 if ( !$commentText ) {
323 $commentText = $comment;
330 " publishing {$file} by '{$user->getName()}', comment '$commentText'..."
333 $mwProps =
new MWFileProps( $services->getMimeAnalyzer() );
334 $props = $mwProps->getPropsFromPath( $file,
true );
336 $publishOptions = [];
337 $handler = MediaHandler::getHandler( $props[
'mime'] );
339 $publishOptions[
'headers'] = $handler->getContentHeaders( $props[
'metadata'] );
341 $publishOptions[
'headers'] = [];
343 $archive = $image->publish( $file, $flags, $publishOptions );
344 if ( !$archive->isGood() ) {
345 $this->
output(
"failed. (" .
346 $archive->getMessage(
false,
false,
'en' )->text() .
348 $statistics[
'failed']++;
353 $commentText = SpecialUpload::getInitialPageText( $commentText, $license );
355 $summary = $commentText;
359 $this->
output(
"done.\n" );
360 } elseif ( $image->recordUpload3(
371 $this->
output(
"done.\n" );
375 $protectLevel = $this->
getOption(
'protect' );
376 $restrictionLevels = $this->
getConfig()->get( MainConfigNames::RestrictionLevels );
378 if ( $protectLevel && in_array( $protectLevel, $restrictionLevels ) ) {
388 $this->
output(
"\nWaiting for replica DBs...\n" );
390 sleep( 2 ); # Why
this sleep?
393 $this->
output(
"\nSetting image restrictions ..." );
397 foreach ( $restrictionStore->listApplicableRestrictionTypes( $title ) as $type ) {
398 $restrictions[$type] = $protectLevel;
401 $page = $services->getWikiPageFactory()->newFromTitle( $title );
402 $status = $page->doUpdateRestrictions( $restrictions, [], $cascade,
'', $user );
403 $this->
output( ( $status->isOK() ?
'done' :
'failed' ) .
"\n" );
406 $this->
output(
"failed. (at recordUpload stage)\n" );
410 $statistics[$svar]++;
413 if ( $limit && $processed >= $limit ) {
418 # Print out some statistics
420 foreach ( array_merge(
426 ) as $desc => $number ) {
428 $this->
output( ucfirst( $desc ) .
": $number\n" );