X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/includes/jobqueue/jobs/AssembleUploadChunksJob.php diff --git a/includes/jobqueue/jobs/AssembleUploadChunksJob.php b/includes/jobqueue/jobs/AssembleUploadChunksJob.php new file mode 100644 index 00000000..e2914be5 --- /dev/null +++ b/includes/jobqueue/jobs/AssembleUploadChunksJob.php @@ -0,0 +1,138 @@ +removeDuplicates = true; + } + + public function run() { + $scope = RequestContext::importScopedSession( $this->params['session'] ); + $this->addTeardownCallback( function () use ( &$scope ) { + ScopedCallback::consume( $scope ); // T126450 + } ); + + $context = RequestContext::getMain(); + $user = $context->getUser(); + try { + if ( !$user->isLoggedIn() ) { + $this->setLastError( "Could not load the author user from session." ); + + return false; + } + + UploadBase::setSessionStatus( + $user, + $this->params['filekey'], + [ 'result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood() ] + ); + + $upload = new UploadFromChunks( $user ); + $upload->continueChunks( + $this->params['filename'], + $this->params['filekey'], + new WebRequestUpload( $context->getRequest(), 'null' ) + ); + + // Combine all of the chunks into a local file and upload that to a new stash file + $status = $upload->concatenateChunks(); + if ( !$status->isGood() ) { + UploadBase::setSessionStatus( + $user, + $this->params['filekey'], + [ 'result' => 'Failure', 'stage' => 'assembling', 'status' => $status ] + ); + $this->setLastError( $status->getWikiText( false, false, 'en' ) ); + + return false; + } + + // We can only get warnings like 'duplicate' after concatenating the chunks + $status = Status::newGood(); + $status->value = [ 'warnings' => $upload->checkWarnings() ]; + + // We have a new filekey for the fully concatenated file + $newFileKey = $upload->getStashFile()->getFileKey(); + + // Remove the old stash file row and first chunk file + $upload->stash->removeFileNoAuth( $this->params['filekey'] ); + + // Build the image info array while we have the local reference handy + $apiMain = new ApiMain(); // dummy object (XXX) + $imageInfo = $upload->getImageInfo( $apiMain->getResult() ); + + // Cleanup any temporary local file + $upload->cleanupTempFile(); + + // Cache the info so the user doesn't have to wait forever to get the final info + UploadBase::setSessionStatus( + $user, + $this->params['filekey'], + [ + 'result' => 'Success', + 'stage' => 'assembling', + 'filekey' => $newFileKey, + 'imageinfo' => $imageInfo, + 'status' => $status + ] + ); + } catch ( Exception $e ) { + UploadBase::setSessionStatus( + $user, + $this->params['filekey'], + [ + 'result' => 'Failure', + 'stage' => 'assembling', + 'status' => Status::newFatal( 'api-error-stashfailed' ) + ] + ); + $this->setLastError( get_class( $e ) . ": " . $e->getMessage() ); + // To be extra robust. + MWExceptionHandler::rollbackMasterChangesAndLog( $e ); + + return false; + } + + return true; + } + + public function getDeduplicationInfo() { + $info = parent::getDeduplicationInfo(); + if ( is_array( $info['params'] ) ) { + $info['params'] = [ 'filekey' => $info['params']['filekey'] ]; + } + + return $info; + } + + public function allowRetries() { + return false; + } +}