Add job for upload from UploadFromUrl

This is the first step to make upload from url work asynchronously

Bug: T295007
Change-Id: I1fb30352849b543c0fb1f27028a34d49dff17797
This commit is contained in:
Giuseppe Lavagetto 2023-12-13 09:05:06 +01:00
parent 204474377e
commit c2373af679
6 changed files with 102 additions and 4 deletions

View file

@ -3034,6 +3034,7 @@ $wgAutoloadLocalClasses = [
'UploadFromFile' => __DIR__ . '/includes/upload/UploadFromFile.php',
'UploadFromStash' => __DIR__ . '/includes/upload/UploadFromStash.php',
'UploadFromUrl' => __DIR__ . '/includes/upload/UploadFromUrl.php',
'UploadFromUrlJob' => __DIR__ . '/includes/jobqueue/jobs/UploadFromUrlJob.php',
'UploadJobTrait' => __DIR__ . '/includes/jobqueue/jobs/UploadJobTrait.php',
'UploadLogFormatter' => __DIR__ . '/includes/logging/UploadLogFormatter.php',
'UploadRevisionImporter' => __DIR__ . '/includes/import/UploadRevisionImporter.php',

View file

@ -385,7 +385,7 @@ config-schema:
description: |-
Enable deferred upload tasks that use the job queue.
Only enable this if job runners are set up for both the
'AssembleUploadChunks' and 'PublishStashedFile' job types.
'AssembleUploadChunks','PublishStashedFile' and 'UploadFromUrl' job types.
UploadMaintenance:
default: false
description: 'To disable file delete/restore temporarily'
@ -7082,6 +7082,7 @@ config-schema:
AssembleUploadChunks: AssembleUploadChunksJob
PublishStashedFile: PublishStashedFileJob
ThumbnailRender: ThumbnailRenderJob
UploadFromUrl: UploadFromUrlJob
recentChangesUpdate: RecentChangesUpdateJob
refreshLinksPrioritized: RefreshLinksJob
refreshLinksDynamic: RefreshLinksJob
@ -7118,6 +7119,7 @@ config-schema:
default:
- AssembleUploadChunks
- PublishStashedFile
- UploadFromUrl
type: array
description: |-
Jobs that must be explicitly requested, i.e. aren't run by job runners unless

View file

@ -79,6 +79,7 @@ use TagLogFormatter;
use TextContentHandler;
use ThumbnailRenderJob;
use UDPRCFeedEngine;
use UploadFromUrlJob;
use UploadLogFormatter;
use UserEditCountInitJob;
use UserGroupExpiryJob;
@ -847,7 +848,7 @@ class MainConfigSchema {
* Enable deferred upload tasks that use the job queue.
*
* Only enable this if job runners are set up for both the
* 'AssembleUploadChunks' and 'PublishStashedFile' job types.
* 'AssembleUploadChunks','PublishStashedFile' and 'UploadFromUrl' job types.
*/
public const EnableAsyncUploads = [
'default' => false,
@ -11358,6 +11359,7 @@ class MainConfigSchema {
'AssembleUploadChunks' => AssembleUploadChunksJob::class,
'PublishStashedFile' => PublishStashedFileJob::class,
'ThumbnailRender' => ThumbnailRenderJob::class,
'UploadFromUrl' => UploadFromUrlJob::class,
'recentChangesUpdate' => RecentChangesUpdateJob::class,
'refreshLinksPrioritized' => RefreshLinksJob::class,
'refreshLinksDynamic' => RefreshLinksJob::class,
@ -11405,7 +11407,7 @@ class MainConfigSchema {
* These settings should be global to all wikis.
*/
public const JobTypesExcludedFromDefaultQueue = [
'default' => [ 'AssembleUploadChunks', 'PublishStashedFile' ],
'default' => [ 'AssembleUploadChunks', 'PublishStashedFile', 'UploadFromUrl' ],
'type' => 'list',
];

View file

@ -2098,6 +2098,7 @@ return [
'AssembleUploadChunks' => 'AssembleUploadChunksJob',
'PublishStashedFile' => 'PublishStashedFileJob',
'ThumbnailRender' => 'ThumbnailRenderJob',
'UploadFromUrl' => 'UploadFromUrlJob',
'recentChangesUpdate' => 'RecentChangesUpdateJob',
'refreshLinksPrioritized' => 'RefreshLinksJob',
'refreshLinksDynamic' => 'RefreshLinksJob',
@ -2132,6 +2133,7 @@ return [
'JobTypesExcludedFromDefaultQueue' => [
'AssembleUploadChunks',
'PublishStashedFile',
'UploadFromUrl',
],
'JobBackoffThrottling' => [
],

View file

@ -0,0 +1,85 @@
<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
/**
* Upload a file by URL, via the jobqueue.
*
*/
class UploadFromUrlJob extends Job implements GenericParameterJob {
use UploadJobTrait;
public function __construct( array $params ) {
// @TODO: fix the invokation of Job::__construct in the parent class
parent::__construct( 'UploadFromUrl', $params );
$this->removeDuplicates = true;
$this->user = null;
$this->cacheKey = UploadFromUrl::getCacheKey( $this->params );
}
/**
* Deduplicate on title, url alone.
*
* Please note that this could cause some
* edge case failure, when the image at the
* same remote url is changed before the first upload
* is ran.
*
* @return array
*/
public function getDeduplicationInfo() {
$info = parent::getDeduplicationInfo();
if ( is_array( $info['params'] ) ) {
$info['params'] = [ 'url' => $info['params']['url'], 'title' => $info['params']['filename'] ];
}
return $info;
}
/**
* getter for the upload
*
* @return UploadBase
*/
protected function getUpload(): UploadBase {
if ( $this->upload === null ) {
$this->upload = new UploadFromUrl;
$this->upload->initialize( $this->params['filename'], $this->params['url'] );
}
return $this->upload;
}
/**
* Get the parameters for job logging
*
* @param Status[] $status
* @return array
*/
public function logJobParams( $status ): array {
return [
'stage' => $status['stage'] ?? '-',
'result' => $status['result'] ?? '-',
'status' => (string)( $status['status'] ?? '-' ),
'url' => $this->params['url'],
'filename' => $this->params['filename'],
'user' => $this->user->getName(),
];
}
}

View file

@ -178,8 +178,14 @@ trait UploadJobTrait {
* @return bool
*/
protected function fetchFile(): bool {
$this->setStatus( 'fetching' );
// make sure the upload file is here. This is a noop in most cases.
$this->getUpload()->fetchFile();
$status = $this->getUpload()->fetchFile();
if ( !$status->isGood() ) {
$this->setStatus( 'fetching', 'Failure', $status );
$this->setLastError( "Error while fetching the image." );
return false;
}
$this->setStatus( 'publish' );
// We really don't care as this is, as mentioned, generally a noop.
// When that's not the case, classes will need to override this method anyways.