138 $permissionManager = $services->getPermissionManager();
150 $this->
output(
"Importing Files\n\n" );
152 $dir = $this->
getArg( 0 );
156 $this->
fatalError(
"Cannot specify both protect and unprotect. Only 1 is allowed.\n" );
160 $this->
fatalError(
"You must specify a protection option.\n" );
163 # Prepare the list of allowed extensions
164 $extensions = $this->
hasOption(
'extensions' )
165 ? explode(
',', strtolower( $this->
getOption(
'extensions' ) ) )
166 : $this->
getConfig()->get( MainConfigNames::FileExtensions );
168 # Search the path provided for candidates for import
169 $files = $this->findFiles( $dir, $extensions, $this->
hasOption(
'search-recursively' ) );
170 if ( !$files->valid() ) {
171 $this->
output(
"No suitable files could be found for import.\n" );
175 # Initialise the user for this operation
177 ? User::newFromName( $this->
getOption(
'user' ) )
178 : User::newSystemUser( User::MAINTENANCE_SCRIPT_USER, [
'steal' =>
true ] );
179 if ( !$user instanceof
User ) {
180 $user = User::newSystemUser( User::MAINTENANCE_SCRIPT_USER, [
'steal' =>
true ] );
182 '@phan-var User $user';
183 StubGlobalUser::setUser( $user );
185 # Get block check. If a value is given, this specified how often the check is performed
186 $checkUserBlock = (int)$this->
getOption(
'check-userblock' );
189 $sleep = (int)$this->
getOption(
'sleep' );
190 $limit = (int)$this->
getOption(
'limit' );
191 $timestamp = $this->
getOption(
'timestamp',
false );
193 # Get the upload comment. Provide a default one in case there's no comment given.
194 $commentFile = $this->
getOption(
'comment-file' );
195 if ( $commentFile !==
null ) {
196 $comment = file_get_contents( $commentFile );
197 if ( $comment ===
false || $comment ===
null ) {
198 $this->
fatalError(
"failed to read comment file: {$commentFile}\n" );
201 $comment = $this->
getOption(
'comment',
'Importing file' );
203 $commentExt = $this->
getOption(
'comment-ext' );
204 $summary = $this->
getOption(
'summary',
'' );
205 $license = $this->
getOption(
'license',
'' );
206 $sourceWikiUrl = $this->
getOption(
'source-wiki-url' );
209 ChangeTags::TAG_SERVER_SIDE_UPLOAD,
212 ? [ ChangeTags::TAG_SERVER_SIDE_UPLOAD ]
215 # Batch "upload" operation
216 $restrictionStore = $services->getRestrictionStore();
217 foreach ( $files as $file ) {
219 if ( $sleep && ( $processed > 0 ) ) {
223 $base = UtfNormal\Validator::cleanUp(
wfBaseName( $file ) );
226 $title = Title::makeTitleSafe(
NS_FILE, $base );
229 "{$base} could not be imported; a valid title cannot be produced\n"
235 if ( $from !== $title->getDBkey() ) {
236 $statistics[
'ignored']++;
243 if ( $checkUserBlock && ( ( $processed % $checkUserBlock ) == 0 ) ) {
244 $user->clearInstanceCache(
'name' );
245 if ( $permissionManager->isBlockedFrom( $user, $title ) ) {
247 "{$user->getName()} is blocked from {$title->getPrefixedText()}! skipping.\n"
249 $statistics[
'skipped']++;
255 $image = $services->getRepoGroup()->getLocalRepo()
257 if ( $image->exists() ) {
259 $this->
output(
"{$base} exists, overwriting..." );
260 $svar =
'overwritten';
262 $this->
output(
"{$base} exists, skipping\n" );
263 $statistics[
'skipped']++;
267 if ( $this->
hasOption(
'skip-dupes' ) ) {
268 $repo = $image->getRepo();
269 # XXX: we end up calculating this again when actually uploading. that sucks.
270 $sha1 = FSFile::getSha1Base36FromPath( $file );
271 $dupes = $repo->findBySha1( $sha1 );
274 "{$base} already exists as {$dupes[0]->getName()}, skipping\n"
276 $statistics[
'skipped']++;
281 $this->
output(
"Importing {$base}..." );
285 if ( $sourceWikiUrl ) {
287 $real_comment = $this->getFileCommentFromSourceWiki( $sourceWikiUrl, $base );
288 $commentText = $real_comment !==
false ? $real_comment : $comment;
291 $real_user = $this->getFileUserFromSourceWiki( $sourceWikiUrl, $base );
292 if ( $real_user !==
false ) {
293 $realUser = User::newFromName( $real_user );
294 if ( $realUser ===
false ) {
295 # user does not exist in target wiki
297 "failed: user '$real_user' does not exist in target wiki."
301 StubGlobalUser::setUser( $realUser );
306 $commentText =
false;
309 $f = $this->findAuxFile( $file, $commentExt );
311 $this->
output(
" No comment file with extension {$commentExt} found "
312 .
"for {$file}, using default comment." );
314 $commentText = file_get_contents( $f );
315 if ( !$commentText ) {
317 " Failed to load comment file {$f}, using default comment."
323 if ( !$commentText ) {
324 $commentText = $comment;
331 " publishing {$file} by '{$user->getName()}', comment '$commentText'..."
334 $mwProps =
new MWFileProps( $services->getMimeAnalyzer() );
335 $props = $mwProps->getPropsFromPath( $file,
true );
337 $publishOptions = [];
338 $handler = MediaHandler::getHandler( $props[
'mime'] );
340 $publishOptions[
'headers'] = $handler->getContentHeaders( $props[
'metadata'] );
342 $publishOptions[
'headers'] = [];
344 $archive = $image->publish( $file, $flags, $publishOptions );
345 if ( !$archive->isGood() ) {
346 $this->
output(
"failed. (" .
347 $archive->getMessage(
false,
false,
'en' )->text() .
349 $statistics[
'failed']++;
354 $commentText = SpecialUpload::getInitialPageText( $commentText, $license );
356 $summary = $commentText;
360 $this->
output(
"done.\n" );
361 } elseif ( $image->recordUpload3(
372 $this->
output(
"done.\n" );
376 $protectLevel = $this->
getOption(
'protect' );
377 $restrictionLevels = $this->
getConfig()->get( MainConfigNames::RestrictionLevels );
379 if ( $protectLevel && in_array( $protectLevel, $restrictionLevels ) ) {
389 $this->
output(
"\nWaiting for replica DBs...\n" );
391 sleep( 2 ); # Why
this sleep?
394 $this->
output(
"\nSetting image restrictions ..." );
398 foreach ( $restrictionStore->listApplicableRestrictionTypes( $title ) as $type ) {
399 $restrictions[$type] = $protectLevel;
402 $page = $services->getWikiPageFactory()->newFromTitle( $title );
403 $status = $page->doUpdateRestrictions( $restrictions, [], $cascade,
'', $user );
404 $this->
output( ( $status->isOK() ?
'done' :
'failed' ) .
"\n" );
407 $this->
output(
"failed. (at recordUpload stage)\n" );
411 $statistics[$svar]++;
414 if ( $limit && $processed >= $limit ) {
419 # Print out some statistics
421 foreach ( array_merge(
427 ) as $desc => $number ) {
429 $this->
output( ucfirst( $desc ) .
": $number\n" );
435 return $statistics[
'failed'] === 0;