http://www.mediawiki.org/wiki/Special:Code/MediaWiki/93720

Revision: 93720
Author:   j
Date:     2011-08-02 10:13:56 +0000 (Tue, 02 Aug 2011)
Log Message:
-----------
Extend upload api adding an option to upload files in chunks,
using UploadStash to track the unfinished upload.

Modified Paths:
--------------
    trunk/phase3/includes/api/ApiUpload.php
    trunk/phase3/includes/upload/UploadFromStash.php

Modified: trunk/phase3/includes/api/ApiUpload.php
===================================================================
--- trunk/phase3/includes/api/ApiUpload.php     2011-08-02 10:10:19 UTC (rev 
93719)
+++ trunk/phase3/includes/api/ApiUpload.php     2011-08-02 10:13:56 UTC (rev 
93720)
@@ -58,6 +58,7 @@
                $request = $this->getMain()->getRequest();
                // Add the uploaded file to the params array
                $this->mParams['file'] = $request->getFileName( 'file' );
+               $this->mParams['chunk'] = $request->getFileName( 'chunk' );
 
                // Copy the session key to the file key, for backward 
compatibility.
                if( !$this->mParams['filekey'] && $this->mParams['sessionkey'] 
) {
@@ -85,7 +86,14 @@
                }
 
                // Check if the uploaded file is sane
-               $this->verifyUpload();
+               if ( $this->mParams['chunk'] ) {
+                       $maxSize = $this->mUpload->getMaxUploadSize( );
+                       if( $this->mParams['filesize'] > $maxSize ) {
+                               $this->dieUsage( 'The file you submitted was 
too large', 'file-too-large' );
+                       }
+        } else {
+                       $this->verifyUpload();
+        }
 
 
                // Check if the user has the rights to modify or overwrite the 
requested title
@@ -113,6 +121,26 @@
                        } catch ( MWException $e ) {
                                $result['warnings']['stashfailed'] = 
$e->getMessage();
                        }
+               } elseif ( $this->mParams['chunk'] ) {
+                   $result['result'] = 'Continue';
+                       $chunk = $request->getFileTempName( 'chunk' );
+                       $chunkSize = $request->getFileSize( 'chunk' );
+            if ($this->mParams['offset'] == 0) {
+                               $result['filekey'] = $this->performStash();
+            } else {
+                $status = $this->mUpload->appendChunk($chunk, $chunkSize,
+                                                      
$this->mParams['offset']);
+                       if ( !$status->isGood() ) {
+                                   $this->dieUsage( $status->getWikiText(), 
'stashfailed' );
+                } else {
+                    $result['filekey'] = $this->mParams['filekey'];
+                    if($this->mParams['offset'] + $chunkSize == 
$this->mParams['filesize']) {
+                        $this->mUpload->finalizeFile();
+                        $result['result'] = 'Done';
+                    }
+                }
+            }
+            $result['offset'] = $this->mParams['offset'] + $chunkSize;
                } elseif ( $this->mParams['stash'] ) {
                        // Some uploads can request they be stashed, so as not 
to publish them immediately.
                        // In this case, a failure to stash ought to be fatal
@@ -188,9 +216,10 @@
        protected function selectUploadModule() {
                $request = $this->getMain()->getRequest();
 
-               // One and only one of the following parameters is needed
-               $this->requireOnlyOneParameter( $this->mParams,
-                       'filekey', 'file', 'url', 'statuskey' );
+               // chunk or one and only one of the following parameters is 
needed
+               if(!$this->mParams['chunk'])
+                       $this->requireOnlyOneParameter( $this->mParams,
+                                       'filekey', 'file', 'url', 'statuskey' );
 
                if ( $this->mParams['statuskey'] ) {
                        $this->checkAsyncDownloadEnabled();
@@ -234,6 +263,13 @@
                        
                        $this->mUpload->initialize( $this->mParams['filekey'], 
$this->mParams['filename'] );
 
+               } elseif ( isset( $this->mParams['chunk'] ) ) {
+                       // Start new Chunk upload
+                       $this->mUpload = new UploadFromFile();
+                       $this->mUpload->initialize(
+                               $this->mParams['filename'],
+                               $request->getUpload( 'chunk' )
+                       );
                } elseif ( isset( $this->mParams['file'] ) ) {
                        $this->mUpload = new UploadFromFile();
                        $this->mUpload->initialize(
@@ -488,6 +524,10 @@
                        ),
                        'stash' => false,
 
+                       'filesize' => null,
+                       'offset' => null,
+                       'chunk' => null,
+
                        'asyncdownload' => false,
                        'leavemessage' => false,
                        'statuskey' => null,
@@ -511,6 +551,10 @@
                        'sessionkey' => 'Same as filekey, maintained for 
backward compatibility.',
                        'stash' => 'If set, the server will not add the file to 
the repository and stash it temporarily.',
 
+                       'chunk' => 'Chunk contents',
+                       'offset' => 'Offset of chunk in bytes',
+                       'filesize' => 'Filesize of entire upload',
+
                        'asyncdownload' => 'Make fetching a URL asynchronous',
                        'leavemessage' => 'If asyncdownload is used, leave a 
message on the user talk page if finished',
                        'statuskey' => 'Fetch the upload status for this file 
key',

Modified: trunk/phase3/includes/upload/UploadFromStash.php
===================================================================
--- trunk/phase3/includes/upload/UploadFromStash.php    2011-08-02 10:10:19 UTC 
(rev 93719)
+++ trunk/phase3/includes/upload/UploadFromStash.php    2011-08-02 10:13:56 UTC 
(rev 93720)
@@ -130,4 +130,36 @@
                return $rv;
        }
 
-}
\ No newline at end of file
+       /**
+        * Append a chunk to the temporary file.
+        *
+        * @return void
+        */
+       public function appendChunk($chunk, $chunkSize, $offset) {
+               //to use $this->getFileSize() here, db needs to be updated
+               //in appendToUploadFile for that
+               $fileSize = $this->stash->getFile( $this->mFileKey )->getSize();
+               if ( $fileSize + $chunkSize > $this->getMaxUploadSize()) {
+                       $status = Status::newFatal( 'file-too-large' );
+               } else {
+                       //append chunk
+                       if ( $fileSize == $offset ) {
+                               $status = $this->appendToUploadFile( $chunk,
+                                                                               
                         $this->mVirtualTempPath );
+                       } else {
+                               $status = Status::newFatal( 
'invalid-chunk-offset' );
+                       }
+               }
+               return $status;
+       }
+
+       /**
+        * Append the final chunk and ready file for parent::performUpload()
+        * @return void
+        */
+       public function finalizeFile() {
+               $this->appendFinish ( $this->mVirtualTempPath );
+               $this->cleanupTempFile();
+               $this->mTempPath = $this->getRealPath( $this->mVirtualTempPath 
);
+       }
+}


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to