r94806 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r94805‎ | r94806 | r94807 >
Date:19:59, 17 August 2011
Author:neilk
Status:ok
Tags:
Comment:
merging in changes for UploadStash in the db
Modified paths:
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizard.config.php (modified) (history)
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizard.i18n.php (modified) (history)
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizard.php (modified) (history)
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizardDependencyLoader.php (deleted) (history)
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizardHooks.php (modified) (history)
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/generateMinifiedResources.php (deleted) (history)
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/resources/mw.Api.js (modified) (history)
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/resources/mw.UploadWizard.js (modified) (history)
  • /branches/wmf/1.17wmf1/extensions/UploadWizard/resources/mw.UploadWizardDetails.js (modified) (history)
  • /branches/wmf/1.17wmf1/includes/DefaultSettings.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/api/ApiQueryStashImageInfo.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/api/ApiUpload.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/installer/MysqlUpdater.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/installer/SqliteUpdater.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/job/UploadFromUrlJob.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/upload/UploadBase.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/upload/UploadFromFile.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/upload/UploadFromStash.php (modified) (history)
  • /branches/wmf/1.17wmf1/includes/upload/UploadStash.php (modified) (history)
  • /branches/wmf/1.17wmf1/maintenance/archives/patch-uploadstash.sql (added) (history)
  • /branches/wmf/1.17wmf1/maintenance/cleanupUploadStash.php (added) (history)
  • /branches/wmf/1.17wmf1/maintenance/tables.sql (modified) (history)

Diff [purge]

Index: branches/wmf/1.17wmf1/maintenance/cleanupUploadStash.php
@@ -0,0 +1,81 @@
 2+<?php
 3+/**
 4+ * Remove old or broken uploads from temporary uploaded file storage,
 5+ * clean up associated database records
 6+ *
 7+ * Copyright © 2011, Wikimedia Foundation
 8+ *
 9+ * This program is free software; you can redistribute it and/or modify
 10+ * it under the terms of the GNU General Public License as published by
 11+ * the Free Software Foundation; either version 2 of the License, or
 12+ * (at your option) any later version.
 13+ *
 14+ * This program is distributed in the hope that it will be useful,
 15+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 17+ * GNU General Public License for more details.
 18+ *
 19+ * You should have received a copy of the GNU General Public License along
 20+ * with this program; if not, write to the Free Software Foundation, Inc.,
 21+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 22+ * http://www.gnu.org/copyleft/gpl.html
 23+ *
 24+ * @file
 25+ * @author Ian Baker <ibaker@wikimedia.org>
 26+ * @ingroup Maintenance
 27+ */
 28+
 29+require_once( dirname( __FILE__ ) . '/Maintenance.php' );
 30+
 31+class UploadStashCleanup extends Maintenance {
 32+
 33+ public function __construct() {
 34+ parent::__construct();
 35+ $this->mDescription = "Clean up abandoned files in temporary uploaded file stash";
 36+ }
 37+
 38+ public function execute() {
 39+ $repo = RepoGroup::singleton()->getLocalRepo();
 40+
 41+ $dbr = $repo->getSlaveDb();
 42+
 43+ // how far back should this look for files to delete?
 44+ global $wgUploadStashMaxAge;
 45+ if( $wgUploadStashMaxAge === null ) {
 46+ $wgUploadStashMaxAge = 6 * 3600; // default: 6 hours.
 47+ }
 48+
 49+ $this->output( "Getting list of files to clean up...\n" );
 50+ $res = $dbr->select(
 51+ 'uploadstash',
 52+ 'us_key',
 53+ 'us_timestamp < ' . $dbr->timestamp( time() - $wgUploadStashMaxAge ),
 54+ __METHOD__
 55+ );
 56+
 57+ if( !is_object( $res ) || $res->numRows() == 0 ) {
 58+ // nothing to do.
 59+ return false;
 60+ }
 61+
 62+ // finish the read before starting writes.
 63+ $keys = array();
 64+ foreach($res as $row) {
 65+ array_push( $keys, $row->us_key );
 66+ }
 67+
 68+ $this->output( 'Removing ' . count($keys) . " file(s)...\n" );
 69+ // this could be done some other, more direct/efficient way, but using
 70+ // UploadStash's own methods means it's less likely to fall accidentally
 71+ // out-of-date someday
 72+ $stash = new UploadStash( $repo );
 73+
 74+ foreach( $keys as $key ) {
 75+ $stash->getFile( $key, true );
 76+ $stash->removeFileNoAuth( $key );
 77+ }
 78+ }
 79+}
 80+
 81+$maintClass = "UploadStashCleanup";
 82+require_once( RUN_MAINTENANCE_IF_MAIN );
\ No newline at end of file
Property changes on: branches/wmf/1.17wmf1/maintenance/cleanupUploadStash.php
___________________________________________________________________
Added: svn:eol-style
183 + native
Index: branches/wmf/1.17wmf1/maintenance/archives/patch-uploadstash.sql
@@ -0,0 +1,49 @@
 2+--
 3+-- Store information about newly uploaded files before they're
 4+-- moved into the actual filestore
 5+--
 6+CREATE TABLE /*_*/uploadstash (
 7+ us_id int unsigned NOT NULL PRIMARY KEY auto_increment,
 8+
 9+ -- the user who uploaded the file.
 10+ us_user int unsigned NOT NULL,
 11+
 12+ -- file key. this is how applications actually search for the file.
 13+ -- this might go away, or become the primary key.
 14+ us_key varchar(255) NOT NULL,
 15+
 16+ -- the original path
 17+ us_orig_path varchar(255) NOT NULL,
 18+
 19+ -- the temporary path at which the file is actually stored
 20+ us_path varchar(255) NOT NULL,
 21+
 22+ -- which type of upload the file came from (sometimes)
 23+ us_source_type varchar(50),
 24+
 25+ -- the date/time on which the file was added
 26+ us_timestamp varbinary(14) not null,
 27+
 28+ us_status varchar(50) not null,
 29+
 30+ -- file properties from File::getPropsFromPath. these may prove unnecessary.
 31+ --
 32+ us_size int unsigned NOT NULL,
 33+ -- this hash comes from File::sha1Base36(), and is 31 characters
 34+ us_sha1 varchar(31) NOT NULL,
 35+ us_mime varchar(255),
 36+ -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table
 37+ us_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
 38+ -- image-specific properties
 39+ us_image_width int unsigned,
 40+ us_image_height int unsigned,
 41+ us_image_bits smallint unsigned
 42+
 43+) /*$wgDBTableOptions*/;
 44+
 45+-- sometimes there's a delete for all of a user's stuff.
 46+CREATE INDEX /*i*/us_user ON /*_*/uploadstash (us_user);
 47+-- pick out files by key, enforce key uniqueness
 48+CREATE UNIQUE INDEX /*i*/us_key ON /*_*/uploadstash (us_key);
 49+-- the abandoned upload cleanup script needs this
 50+CREATE INDEX /*i*/us_timestamp ON /*_*/uploadstash (us_timestamp);
Property changes on: branches/wmf/1.17wmf1/maintenance/archives/patch-uploadstash.sql
___________________________________________________________________
Added: svn:eol-style
151 + native
Index: branches/wmf/1.17wmf1/maintenance/tables.sql
@@ -927,6 +927,57 @@
928928
929929
930930 --
 931+-- Store information about newly uploaded files before they're
 932+-- moved into the actual filestore
 933+--
 934+CREATE TABLE /*_*/uploadstash (
 935+ us_id int unsigned NOT NULL PRIMARY KEY auto_increment,
 936+
 937+ -- the user who uploaded the file.
 938+ us_user int unsigned NOT NULL,
 939+
 940+ -- file key. this is how applications actually search for the file.
 941+ -- this might go away, or become the primary key.
 942+ us_key varchar(255) NOT NULL,
 943+
 944+ -- the original path
 945+ us_orig_path varchar(255) NOT NULL,
 946+
 947+ -- the temporary path at which the file is actually stored
 948+ us_path varchar(255) NOT NULL,
 949+
 950+ -- which type of upload the file came from (sometimes)
 951+ us_source_type varchar(50),
 952+
 953+ -- the date/time on which the file was added
 954+ us_timestamp varbinary(14) not null,
 955+
 956+ us_status varchar(50) not null,
 957+
 958+ -- file properties from File::getPropsFromPath. these may prove unnecessary.
 959+ --
 960+ us_size int unsigned NOT NULL,
 961+ -- this hash comes from File::sha1Base36(), and is 31 characters
 962+ us_sha1 varchar(31) NOT NULL,
 963+ us_mime varchar(255),
 964+ -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table
 965+ us_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
 966+ -- image-specific properties
 967+ us_image_width int unsigned,
 968+ us_image_height int unsigned,
 969+ us_image_bits smallint unsigned
 970+
 971+) /*$wgDBTableOptions*/;
 972+
 973+-- sometimes there's a delete for all of a user's stuff.
 974+CREATE INDEX /*i*/us_user ON /*_*/uploadstash (us_user);
 975+-- pick out files by key, enforce key uniqueness
 976+CREATE UNIQUE INDEX /*i*/us_key ON /*_*/uploadstash (us_key);
 977+-- the abandoned upload cleanup script needs this
 978+CREATE INDEX /*i*/us_timestamp ON /*_*/uploadstash (us_timestamp);
 979+
 980+
 981+--
931982 -- Primarily a summary table for Special:Recentchanges,
932983 -- this table contains some additional info on edits from
933984 -- the last few days, see Article::editUpdates()
Property changes on: branches/wmf/1.17wmf1/maintenance/tables.sql
___________________________________________________________________
Modified: svn:mergeinfo
934985 Merged /trunk/phase3/maintenance/tables.sql:r91022,91679,92009,92030,92035,92039,92043,92081,92200,92213,92247,92250,92269,92459,92815,93065,93137,93476,93778,94536,94539-94540,94592,94594,94670
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/generateMinifiedResources.php
@@ -1,23 +0,0 @@
2 -<?php
3 -$path = getenv( 'MW_INSTALL_PATH' );
4 -if ( strval( $path ) === '' ) {
5 - $path = dirname( __FILE__ ) . '/../..';
6 -}
7 -require_once( "$path/maintenance/Maintenance.php" );
8 -
9 -/**
10 - * Maintenance script to generate combined and minified JS and CSS for UploadWizard
11 - */
12 -class UploadWizardGenerateMinifiedResources extends Maintenance {
13 - public function __construct() {
14 - parent::__construct();
15 - $this->mDescription = 'Generate combined and minified JS and CSS for UploadWizard';
16 - }
17 -
18 - public function execute() {
19 - $dependencyLoader = new UploadWizardDependencyLoader();
20 - $dependencyLoader->writeOptimizedFiles();
21 - }
22 -}
23 -$maintClass = 'UploadWizardGenerateMinifiedResources';
24 -require_once( DO_MAINTENANCE );
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizardDependencyLoader.php
@@ -1,225 +0,0 @@
2 -<?php
3 -
4 -/**
5 - * What's that you say? ANOTHER way to load dependencies? Everyone's doing it.
6 - *
7 - * Doing resource loading the old-fashioned way for now until Resource Loader or something becomes the standard.
8 - * We anticipate that Resource Loader will be available sometime in late 2010 or early 2011,
9 - * so we define scripts in the hooks that Resource Loader will expect, over in UploadWizardHooks.php.
10 - *
11 - * Since the resources are defined in PHP, it was convenient to write the minifier routines here too.
12 - * We do not expect to minify on the fly in MediaWiki; those rotutines will be called by
13 - * developer scripts to write minified files before committing to the source code repository.
14 - *
15 - * (Previously the usability projects had used Makefiles, but then had to keep dependencies in sync in
16 - * PHP and the Makefile). I started to write a PHP file that then would write a Makefile and realized
17 - * this was getting a bit insane.
18 - *
19 - * @author Neil Kandalgaonkar <neilk@wikimedia.org>
20 - */
21 -
22 -class UploadWizardDependencyLoader {
23 -
24 - const STYLES_COMBINED = 'combined.css';
25 - const SCRIPTS_COMBINED = 'combined.js';
26 - const STYLES_MINIFIED = 'combined.min.css';
27 - const SCRIPTS_MINIFIED = 'combined.min.js';
28 -
29 - protected $scripts;
30 - protected $inlineScripts;
31 - protected $styles;
32 -
33 - protected $optimizedStylesFile;
34 - protected $optimizedScriptsFile;
35 -
36 - public function __construct( $langCode = null ) {
37 - $module = UploadWizardHooks::$modules['ext.uploadWizard'];
38 -
39 - $this->scripts = $module['scripts'];
40 -
41 - $this->inlineScripts = array();
42 - if ( $langCode !== null ) {
43 - if ( $langCode !== 'en' && isset( $module['languageScripts'][$langCode] ) ) {
44 - $this->scripts[] = $module['languageScripts'][$langCode];
45 - }
46 - $this->inlineScripts[] = UploadWizardMessages::getMessagesJs( 'UploadWizard', $langCode );
47 - }
48 -
49 - // TODO RTL
50 - $this->styles = $module['styles'];
51 -
52 - $dir = dirname( __FILE__ );
53 - $this->optimizedStylesFile = $dir . '/' . self::STYLES_MINIFIED;
54 - $this->optimizedScriptsFile = $dir . '/' . self::SCRIPTS_MINIFIED;
55 - }
56 -
57 - /**
58 - * Writes HTML tags to load all dependencies separately. Useful when developing.
59 - * @param {OutputPage} $out
60 - * @param {String} $baseUrl: base URL, corresponds to the main directory of this extension.
61 - */
62 - public function outputHtmlDebug( $out, $baseUrl ) {
63 - foreach ( $this->scripts as $script ) {
64 - $out->addScriptFile( $baseUrl . "/" . $script );
65 - }
66 - foreach ( $this->inlineScripts as $script ) {
67 - $out->addInlineScript( $script );
68 - }
69 - // XXX RTL
70 - foreach ( $this->styles as $style ) {
71 - $out->addStyle( $baseUrl . "/" . $style, '', '', 'ltr' );
72 - }
73 - }
74 -
75 - /**
76 - * Writes HTML tags to load optimized dependencies. Useful in production.
77 - * @param {OutputPage} $out
78 - * @param {String} $baseUrl: base URL, corresponds to the main directory of this extension.
79 - * @param {Boolean} $minified: if true, you get minified, otherwise, just combined.
80 - */
81 - public function outputHtml( $out, $baseUrl, $minified = true ) {
82 - if ( $minified ) {
83 - $scriptsFile = self::SCRIPTS_MINIFIED;
84 - $stylesFile = self::STYLES_MINIFIED;
85 - } else {
86 - $scriptsFile = self::SCRIPTS_COMBINED;
87 - $stylesFile = self::STYLES_COMBINED;
88 - }
89 - $scriptsFile = "resources/$scriptsFile";
90 - $stylesFile = "resources/$stylesFile";
91 -
92 - $out->addScriptFile( $baseUrl . "/" . $scriptsFile );
93 - // XXX RTL!?
94 - $out->addStyle( $baseUrl . "/" . $stylesFile, '', '', 'ltr' );
95 -
96 - // the inline scripts still go inline (they are keyed off user language)
97 - foreach ( $this->inlineScripts as $script ) {
98 - $out->addInlineScript( $script );
99 - }
100 - }
101 -
102 - /**
103 - * Write the concatenated and minified files for CSS and JS
104 - * This is the function you want to call to regenerate all such files
105 - * Not intended to be called in production or from the web.
106 - * Intended to be invoked from the same directory as UploadWizard.
107 - */
108 - public function writeOptimizedFiles() {
109 - $extensionDir = dirname( __FILE__ );
110 - $resourceDir = "$extensionDir/resources";
111 -
112 - // have to group styles by dirname, since they sometimes refer to resources by relative path.
113 - $dirStyleCombinedUrls = array();
114 - $dirStyleMinifiedUrls = array();
115 - $dirStylesMap = array();
116 - foreach ( $this->styles as $style ) {
117 - $dir = dirname( $style );
118 - if ( !isset( $dirStylesMap[$dir] ) ) {
119 - $dirStylesMap[$dir] = array();
120 - }
121 - $dirStylesMap[$dir][] = $style;
122 - }
123 - foreach ( $dirStylesMap as $dir => $styles ) {
124 - $combined = "$dir/dir." . self::STYLES_COMBINED;
125 - $this->concatenateFiles( $styles, $combined );
126 - $dirStyleCombinedUrls[] = preg_replace( '/^resources\//', '', $combined );
127 -
128 - $minified = "$dir/dir." . self::STYLES_MINIFIED;
129 - $this->writeMinifiedCss( $combined, $minified );
130 - $dirStyleMinifiedUrls[] = preg_replace( '/^resources\//', '', $minified );
131 - }
132 - $this->writeStyleImporter( $dirStyleCombinedUrls, $resourceDir . '/' . self::STYLES_COMBINED );
133 - $this->writeStyleImporter( $dirStyleMinifiedUrls, $resourceDir . '/' . self::STYLES_MINIFIED );
134 -
135 - // scripts are easy, they don't (or shouldn't) refer to other resources with relative paths
136 - $scriptsCombinedFile = $resourceDir . '/' . self::SCRIPTS_COMBINED;
137 - $this->concatenateFiles( $this->scripts, $scriptsCombinedFile );
138 - $this->writeMinifiedJs( $scriptsCombinedFile, $resourceDir . '/' . self::SCRIPTS_MINIFIED );
139 - }
140 -
141 - /**
142 - * Since I couldn't figure out how to solve the CSS minification issue and how
143 - * it broke relative paths for images, we'll minify one file per directory.
144 - * This means we'll need a "master" file to import them all. We can use CSS @import,
145 - * It's supported by browsers later than NS 4.0 or IE 4.0.
146 - * @param {Array} $urls : list of urls
147 - * @param {String} $outputFile : where to make this file
148 - */
149 - function writeStyleImporter( $urls, $outputFile ) {
150 - $fp = fopen( $outputFile, 'w' );
151 - if ( ! $fp ) {
152 - print "couldn't open $outputFile for writing\n";
153 - exit;
154 - }
155 - foreach ( $urls as $url ) {
156 - fwrite( $fp, "@import \"$url\";\n" );
157 - }
158 - fclose( $fp );
159 - }
160 -
161 - /**
162 - * Concatenates several files on the filesystem into one.
163 - * @param {Array} filenames
164 - * @param {String} filename to concatenate all files into. Will replace existing contents
165 - */
166 - private function concatenateFiles( $files, $outputFile ) {
167 - $fp = fopen( $outputFile, 'w' );
168 - if ( ! $fp ) {
169 - print "couldn't open $outputFile for writing";
170 - exit;
171 - }
172 - foreach ( $files as $file ) {
173 - fwrite( $fp, file_get_contents( $file ) );
174 - }
175 - fclose( $fp );
176 - }
177 -
178 - /**
179 - * Writes a minified version of a particular JavaScript file to the filesystem.
180 - * @param {Script} input filename
181 - * @param {String} filename for minified output
182 - */
183 - private function writeMinifiedJs( $inputFile, $outputFile ) {
184 - $fp = fopen( $outputFile, 'w' );
185 - if ( ! $fp ) {
186 - print "couldn't open $outputFile for writing";
187 - exit;
188 - }
189 - fwrite( $fp, JSMin::minify( file_get_contents( $inputFile ) ) );
190 - fclose( $fp );
191 - }
192 -
193 - /**
194 - * Writes a minified version of a particular CSS file to the filesystem.
195 - * N.B. multiline comment removal can fail in certain situations, which you are unlikely to encounter unless
196 - * you nest comments, or put comment sequences inside values
197 - * @param {Script} input filename
198 - * @param {String} filename for minified output
199 - */
200 - private function writeMinifiedCss( $inputFile, $outputFile ) {
201 - $contents = file_get_contents( $inputFile );
202 -
203 - // remove leading and trailing spaces
204 - $contents = preg_replace( '/^\s*|\s*$/m', '', $contents );
205 -
206 - // remove whitespace immediately after a separator
207 - $contents = preg_replace( '/([:{;,])\s*/', '$1', $contents );
208 -
209 - // remove whitespace immediately before an open-curly
210 - $contents = preg_replace( '/\s*\{/', '{', $contents );
211 -
212 - // remove /* ... */ comments, potentially on multiple lines
213 - // CAUTION: gets edge cases wrong, like nested or quoted comments.
214 - // Not for use with nuclear reactors.
215 - $contents = preg_replace( '/\/\*.*?\*\//s', '', $contents );
216 -
217 - $fp = fopen( $outputFile, 'w' );
218 - if ( ! $fp ) {
219 - print "couldn't open $outputFile for writing";
220 - exit;
221 - }
222 - fwrite( $fp, $contents );
223 - fclose( $fp );
224 - }
225 -
226 -}
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizard.config.php
@@ -220,7 +220,7 @@
221221 'maxOtherInformationLength' => 4096,
222222
223223 // Max number of simultaneous upload requests
224 - 'maxSimultaneousConnections' => 1,
 224+ 'maxSimultaneousConnections' => 3,
225225
226226 // Max number of uploads for a given form
227227 'maxUploads' => 10,
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizardHooks.php
@@ -120,7 +120,7 @@
121121 'mwe-upwiz-api-error-stashfailed',
122122 'mwe-upwiz-api-error-missingresult',
123123 'mwe-upwiz-api-error-missingparam',
124 - 'mwe-upwiz-api-error-invalid-session-key',
 124+ 'mwe-upwiz-api-error-invalid-file-key',
125125 'mwe-upwiz-api-error-copyuploaddisabled',
126126 'mwe-upwiz-api-error-mustbeloggedin',
127127 'mwe-upwiz-api-error-empty-file',
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizard.i18n.php
@@ -33,7 +33,7 @@
3434 'mwe-upwiz-api-error-stashfailed' => 'Internal error: server failed to store temporary file.',
3535 'mwe-upwiz-api-error-missingresult' => 'Internal error: could not determine if the copy succeeded.',
3636 'mwe-upwiz-api-error-missingparam' => 'Internal error: missing parameters on request.',
37 - 'mwe-upwiz-api-error-invalid-session-key' => 'Internal error: file was not found in temporary storage.',
 37+ 'mwe-upwiz-api-error-invalid-file-key' => 'Internal error: file was not found in temporary storage.',
3838 'mwe-upwiz-api-error-copyuploaddisabled' => 'Uploading by URL is disabled on this server.',
3939 'mwe-upwiz-api-error-mustbeloggedin' => 'You must be logged in to upload files.',
4040 'mwe-upwiz-api-error-empty-file' => 'The file you submitted was empty.',
@@ -447,7 +447,7 @@
448448 'mwe-upwiz-api-error-stashfailed' => 'የውስጥ ስህተት: አቅራቢው ጊዜያዊ ፍይሉን አላስቀመጠም።',
449449 'mwe-upwiz-api-error-missingresult' => 'የውስጥ ስህተት: መቅዳቱ እንደተሳካ ማረጋገጥ አልተቻለም።',
450450 'mwe-upwiz-api-error-missingparam' => 'የውስጥ ስህተት: ጥያቄው ግቤቶች ይጎሉታል።',
451 - 'mwe-upwiz-api-error-invalid-session-key' => 'የውስጥ ስህተት: ፍይሉ የጊዜያዊ ማስቀመጫ ውስጥ አልተገኘም።',
 451+ 'mwe-upwiz-api-error-invalid-file-key' => 'የውስጥ ስህተት: ፍይሉ የጊዜያዊ ማስቀመጫ ውስጥ አልተገኘም።',
452452 'mwe-upwiz-api-error-copyuploaddisabled' => 'በሰነድ አድራሻ መላክ በዚህ አቅራቢ ላይ አልተፈቀደም።',
453453 'mwe-upwiz-api-error-mustbeloggedin' => 'ፋይል ለመላክ ተዘግቦ መግባት ያስፈልጋል።',
454454 'mwe-upwiz-api-error-empty-file' => 'የላኩት ፋይል ባዶ ነበር።',
@@ -536,7 +536,7 @@
537537 'mwe-upwiz-api-error-stashfailed' => 'خطأ داخلي: فشل الملقم في تخزين الملفات المؤقتة.',
538538 'mwe-upwiz-api-error-missingresult' => 'خطأ داخلي : لا يمكن التحديد ما إذا كان النسخ ناجحاً.',
539539 'mwe-upwiz-api-error-missingparam' => 'خطأ داخلي : متغيرات مفقودة ضمن الطلب.',
540 - 'mwe-upwiz-api-error-invalid-session-key' => 'خطأ داخلي: لم يتم العثور على الملف في التخزين المؤقت.',
 540+ 'mwe-upwiz-api-error-invalid-file-key' => 'خطأ داخلي: لم يتم العثور على الملف في التخزين المؤقت.',
541541 'mwe-upwiz-api-error-copyuploaddisabled' => 'تم تعطيل تحميل من رابط على هذا الخادم.',
542542 'mwe-upwiz-api-error-mustbeloggedin' => 'يجب أن تكون مسجلا في لتحميل الملفات.',
543543 'mwe-upwiz-api-error-empty-file' => 'كان ملف الذي قمت بإرسال فارغة.',
@@ -782,7 +782,7 @@
783783 'mwe-upwiz-api-error-stashfailed' => 'Fallu internu: el sirvidor nun pudo guardar el ficheru temporal.',
784784 'mwe-upwiz-api-error-missingresult' => 'Fallu internu: nun se pudo determinar si la copia foi bien.',
785785 'mwe-upwiz-api-error-missingparam' => 'Fallu internu: falten parámetros na solicitú.',
786 - 'mwe-upwiz-api-error-invalid-session-key' => "Fallu internu: nun s'atopó el ficheru nel depósitu temporal.",
 786+ 'mwe-upwiz-api-error-invalid-file-key' => "Fallu internu: nun s'atopó el ficheru nel depósitu temporal.",
787787 'mwe-upwiz-api-error-copyuploaddisabled' => "Xubir d'una URL ta desactivao nesti sirvidor.",
788788 'mwe-upwiz-api-error-mustbeloggedin' => 'Tienes de tar autenticáu pa xubir ficheros.',
789789 'mwe-upwiz-api-error-empty-file' => "El ficheru qu'unviasti taba baleru.",
@@ -929,7 +929,7 @@
930930 'mwe-upwiz-api-error-stashfailed' => 'Унутраная памылка: сэрвэр ня змог захаваць часовы файл.',
931931 'mwe-upwiz-api-error-missingresult' => 'Унутраная памылка: немагчыма вызначыць, ці пасьпяхова зробленае капіяваньне.',
932932 'mwe-upwiz-api-error-missingparam' => 'Унутраная памылка: запыт бракуе парамэтраў.',
933 - 'mwe-upwiz-api-error-invalid-session-key' => 'Унутраная памылка: ня быў знойдзены часовы файл.',
 933+ 'mwe-upwiz-api-error-invalid-file-key' => 'Унутраная памылка: ня быў знойдзены часовы файл.',
934934 'mwe-upwiz-api-error-copyuploaddisabled' => 'Загрузка з URL-адрасу забароненая на гэтым сэрвэры.',
935935 'mwe-upwiz-api-error-mustbeloggedin' => 'Для загрузкі файлаў неабходна ўвайсьці ў сыстэму.',
936936 'mwe-upwiz-api-error-empty-file' => 'Дасланы Вамі файл быў пусты.',
@@ -1172,7 +1172,7 @@
11731173 'mwe-upwiz-api-error-badaccess-groups' => 'Нямате необходимите права, за да качвате файлове в това уики.',
11741174 'mwe-upwiz-api-error-stashfailed' => 'Вътрешна грешка: Сървърът не успя да съхрани временния файл.',
11751175 'mwe-upwiz-api-error-missingparam' => 'Вътрешна грешка: Липсващи параметри на заявката.',
1176 - 'mwe-upwiz-api-error-invalid-session-key' => 'Вътрешна грешка: Файлът не беше открит във временното хранилище.',
 1176+ 'mwe-upwiz-api-error-invalid-file-key' => 'Вътрешна грешка: Файлът не беше открит във временното хранилище.',
11771177 'mwe-upwiz-api-error-copyuploaddisabled' => 'Качването през URL е забранено на този сървър.',
11781178 'mwe-upwiz-api-error-mustbeloggedin' => 'Трябва да сте влезли в системата, за да можете да качвате файлове.',
11791179 'mwe-upwiz-api-error-empty-file' => 'Заявеният за качване файл беше празен.',
@@ -1413,7 +1413,7 @@
14141414 'mwe-upwiz-api-error-stashfailed' => 'অভ্যন্তরীণ ত্রুটি: সার্ভার অস্থায়ী ফাইলটি সংরক্ষণ করতে ব্যর্থ হয়েছে।',
14151415 'mwe-upwiz-api-error-missingresult' => 'অভ্যন্তরীণ ত্রুটি: সফলভাবে অনুলিপি করা হয়েছে কিনা তা নিশ্চিত করা সম্ভব হয়নি।',
14161416 'mwe-upwiz-api-error-missingparam' => 'অভ্যন্তরীণ ত্রুটি: অনুরোধে কিছু প্যারামিটারের ঘাটতি রয়েছে।',
1417 - 'mwe-upwiz-api-error-invalid-session-key' => 'অভ্যন্তরীণ ত্রুটি: অস্থায়ী সংরক্ষণশালায় ফাইলটি খুঁজে পাওয়া যায়নি।',
 1417+ 'mwe-upwiz-api-error-invalid-file-key' => 'অভ্যন্তরীণ ত্রুটি: অস্থায়ী সংরক্ষণশালায় ফাইলটি খুঁজে পাওয়া যায়নি।',
14181418 'mwe-upwiz-api-error-copyuploaddisabled' => 'এই সার্ভারে ইউআরএল-এর মাধ্যমে আপলোড করার সুবিধা নিস্ক্রিয় রয়েছে।',
14191419 'mwe-upwiz-api-error-mustbeloggedin' => 'ফাইল আপলোড করার জন্য আপনাকে অবশ্যই এই উইকিতে প্রবেশ বা লগইন করতে হবে।',
14201420 'mwe-upwiz-api-error-empty-file' => 'আপনার জমাদানকৃত ফাইলটি খালি।',
@@ -1591,7 +1591,7 @@
15921592 'mwe-upwiz-api-error-stashfailed' => "Fazi diabarzh : dibosupl d'ar servijer enrollañ ar restr padennek.",
15931593 'mwe-upwiz-api-error-missingresult' => 'Fazi diabarzh : dibosupl termeniñ hag eilet eo bet an traoù ervat.',
15941594 'mwe-upwiz-api-error-missingparam' => 'Fazi diabarzh : Arventennoù a vank er reked.',
1595 - 'mwe-upwiz-api-error-invalid-session-key' => "Fazi diabarzh : n'eo ket bet kavet ar restr er stokañ da c'hortoz.",
 1595+ 'mwe-upwiz-api-error-invalid-file-key' => "Fazi diabarzh : n'eo ket bet kavet ar restr er stokañ da c'hortoz.",
15961596 'mwe-upwiz-api-error-copyuploaddisabled' => 'Diweredekaet eo an enporzhioù dre URL war ar servijer-mañ.',
15971597 'mwe-upwiz-api-error-mustbeloggedin' => "Ret eo deoc'h bezañ kevreet evit pellgargañ restroù.",
15981598 'mwe-upwiz-api-error-empty-file' => "Ar restr hoc'h eus roet a oa goullo.",
@@ -1833,7 +1833,7 @@
18341834 'mwe-upwiz-api-error-stashfailed' => 'Unutrašnja greška: server nije mogao da spremi privremenu datoteku.',
18351835 'mwe-upwiz-api-error-missingresult' => 'Unutrašnja greška: ne može se otkriti da li je kopiranje uspjelo.',
18361836 'mwe-upwiz-api-error-missingparam' => 'Unutrašnja greška: nedostaju parametri u zahtjevu.',
1837 - 'mwe-upwiz-api-error-invalid-session-key' => 'Unutrašnja greška: datoteka nije pronađena u privremenom skladištu.',
 1837+ 'mwe-upwiz-api-error-invalid-file-key' => 'Unutrašnja greška: datoteka nije pronađena u privremenom skladištu.',
18381838 'mwe-upwiz-api-error-copyuploaddisabled' => 'Postavljanja putem URL-a su onemogućena na ovom serveru.',
18391839 'mwe-upwiz-api-error-mustbeloggedin' => 'Morate biti prijavljeni da biste postavljali datoteke.',
18401840 'mwe-upwiz-api-error-empty-file' => 'Datoteka koju ste poslali je bila prazna.',
@@ -2047,7 +2047,7 @@
20482048 'mwe-upwiz-api-error-stashfailed' => 'Error intern: el servidor no ha pogut emmagatzemar fitxers temporals.',
20492049 'mwe-upwiz-api-error-missingresult' => "Error intern: no s'ha pogut determinar si la còpia ha reeixit.",
20502050 'mwe-upwiz-api-error-missingparam' => 'Error intern: falten paràmetres a la petició.',
2051 - 'mwe-upwiz-api-error-invalid-session-key' => "Error intern: no s'ha trobat el fitxer al dipòsit temporal.",
 2051+ 'mwe-upwiz-api-error-invalid-file-key' => "Error intern: no s'ha trobat el fitxer al dipòsit temporal.",
20522052 'mwe-upwiz-api-error-copyuploaddisabled' => 'Les càrregues via URL estan desactivades en aquest servidor.',
20532053 'mwe-upwiz-api-error-mustbeloggedin' => "Cal que estigueu autenticats en un compte d'usuari per a poder carregar fitxers.",
20542054 'mwe-upwiz-api-error-empty-file' => 'El fitxer que heu tramès està buit.',
@@ -2197,7 +2197,7 @@
21982198 'mwe-upwiz-api-error-stashfailed' => 'Vnitřní chyba: serveru se nepodařilo uložit dočasný soubor.',
21992199 'mwe-upwiz-api-error-missingresult' => 'Vnitřní chyba: nelze určit, zda kopírování bylo úspěšné.',
22002200 'mwe-upwiz-api-error-missingparam' => 'Vnitřní chyba: chybí parametry požadavku.',
2201 - 'mwe-upwiz-api-error-invalid-session-key' => 'Vnitřní chyba: soubor nebyl nalezen v dočasném úložišti.',
 2201+ 'mwe-upwiz-api-error-invalid-file-key' => 'Vnitřní chyba: soubor nebyl nalezen v dočasném úložišti.',
22022202 'mwe-upwiz-api-error-copyuploaddisabled' => 'Načítání z URL je na tomto severu zakázáno.',
22032203 'mwe-upwiz-api-error-mustbeloggedin' => 'K načtení souborů musíte být přihlášen.',
22042204 'mwe-upwiz-api-error-empty-file' => 'Načtený soubor je prázdný.',
@@ -2429,7 +2429,7 @@
24302430 'mwe-upwiz-api-error-stashfailed' => "Gwall mewnol: methodd y gweinydd â rhoi'r ffeil dros dro ar gadw.",
24312431 'mwe-upwiz-api-error-missingresult' => 'Gwall mewnol: ni allem ddarganfod a lwyddodd y gwaith copïo ai pheidio.',
24322432 'mwe-upwiz-api-error-missingparam' => 'Gwall mewnol: paramedrau yn eisiau ar y cais.',
2433 - 'mwe-upwiz-api-error-invalid-session-key' => "Gwall mewnol: nid oedd modd dod o hyd i'r ffeil yn y storfa dros dro.",
 2433+ 'mwe-upwiz-api-error-invalid-file-key' => "Gwall mewnol: nid oedd modd dod o hyd i'r ffeil yn y storfa dros dro.",
24342434 'mwe-upwiz-api-error-copyuploaddisabled' => 'Nid oes modd uwchlwytho drwy URL ar y gweinydd hwn',
24352435 'mwe-upwiz-api-error-mustbeloggedin' => 'Rhaid i chi fewngofnodi er mwyn uwchlwytho ffeiliau.',
24362436 'mwe-upwiz-api-error-empty-file' => "Mae'r ffeil a gyflwynwyd gennych yn wag.",
@@ -2609,7 +2609,7 @@
26102610 'mwe-upwiz-api-error-stashfailed' => 'Intern fejl: serveren kunne ikke gemme midlertidig fil.',
26112611 'mwe-upwiz-api-error-missingresult' => 'Intern fejl: kunne ikke afgøre om kopieringen lykkedes.',
26122612 'mwe-upwiz-api-error-missingparam' => 'Intern fejl: manglende parametre i anmodning.',
2613 - 'mwe-upwiz-api-error-invalid-session-key' => 'Intern fejl: filen blev ikke fundet på den midlertidige lagerplads.',
 2613+ 'mwe-upwiz-api-error-invalid-file-key' => 'Intern fejl: filen blev ikke fundet på den midlertidige lagerplads.',
26142614 'mwe-upwiz-api-error-copyuploaddisabled' => 'At lægge filer op via hjemmesideadresser er slået fra på denne server.',
26152615 'mwe-upwiz-api-error-mustbeloggedin' => 'Du skal være logget på for at kunne lægge filer op.',
26162616 'mwe-upwiz-api-error-empty-file' => 'Den fil du indsendte var tom.',
@@ -2862,7 +2862,7 @@
28632863 'mwe-upwiz-api-error-stashfailed' => 'Interner Fehler: Der Server konnte keine temporäre Datei speichern.',
28642864 'mwe-upwiz-api-error-missingresult' => 'Interner Fehler: Es konnte nicht festgestellt werden, ob das Kopieren erfolgreich war.',
28652865 'mwe-upwiz-api-error-missingparam' => 'Interner Fehler: Der Anfrage fehlen Parameter.',
2866 - 'mwe-upwiz-api-error-invalid-session-key' => 'Interner Fehler: Die Datei wurde nicht im temporären Speicher gefunden.',
 2866+ 'mwe-upwiz-api-error-invalid-file-key' => 'Interner Fehler: Die Datei wurde nicht im temporären Speicher gefunden.',
28672867 'mwe-upwiz-api-error-copyuploaddisabled' => 'Das Hochladen via URL wurde auf diesem Server deaktiviert.',
28682868 'mwe-upwiz-api-error-mustbeloggedin' => 'Um Dateien hochladen zu können, musst du angemeldet sein.',
28692869 'mwe-upwiz-api-error-empty-file' => 'Die hochgeladene Datei war leer.',
@@ -3179,7 +3179,7 @@
31803180 'mwe-upwiz-api-error-stashfailed' => 'Εσωτερικό σφάλμα: ο διακομιστής απέτυχε να αποθηκεύσει το προσωρινό αρχείο.',
31813181 'mwe-upwiz-api-error-missingresult' => 'Εσωτερικό σφάλμα: δεν ήταν δυνατό να προσδιοριστεί εάν η αντίγραφή ολοκληρώθηκε με επιτυχία.',
31823182 'mwe-upwiz-api-error-missingparam' => 'Εσωτερικό σφάλμα: λείπουν παράμετροι από το αίτημα.',
3183 - 'mwe-upwiz-api-error-invalid-session-key' => 'Εσωτερικό σφάλμα: το αρχείο δεν βρέθηκε στην προσωρινή αποθήκευση.',
 3183+ 'mwe-upwiz-api-error-invalid-file-key' => 'Εσωτερικό σφάλμα: το αρχείο δεν βρέθηκε στην προσωρινή αποθήκευση.',
31843184 'mwe-upwiz-api-error-copyuploaddisabled' => 'Η επιφόρτωση από URL είναι απενεργοποιημένη σε αυτόν το διακομιστή.',
31853185 'mwe-upwiz-api-error-mustbeloggedin' => 'Θα πρέπει να συνδεθείτε για να φορτώσετε τα αρχεία.',
31863186 'mwe-upwiz-api-error-empty-file' => 'Το αρχείο που υποβάλλατε ήταν κενό.',
@@ -3277,6 +3277,16 @@
32783278 'mwe-upwiz-step-details' => 'Priskribi',
32793279 'mwe-upwiz-step-thanks' => 'Uzo',
32803280 'mwe-upwiz-api-error-unknown-code' => 'Nekonata eraro: "$1"',
 3281+ 'mwe-upwiz-api-error-uploaddisabled' => 'Alŝutato estas malebligata en tiu-ĉi vikio.',
 3282+ 'mwe-upwiz-api-error-nomodule' => 'Interna eraro: ne troveblas alŝuta helpilaro.',
 3283+ 'mwe-upwiz-api-error-mustbeposted' => 'Interna eraro: la peto necesigas alŝuton en formato HTTP.',
 3284+ 'mwe-upwiz-api-error-badaccess-groups' => 'Vi ne havas permeson alŝuti dosierojn al tiu-ĉi vikio.',
 3285+ 'mwe-upwiz-api-error-stashfailed' => 'Interna eraro: la servilo malsukcesis stoki dumtempan dosieron.',
 3286+ 'mwe-upwiz-api-error-missingresult' => 'Interna eraro: ne eblis eltrovi ĉu la kopiado sukcesis.',
 3287+ 'mwe-upwiz-api-error-missingparam' => 'Interna eraro: mankantaj parametroj en la alŝutopeto.',
 3288+ 'mwe-upwiz-api-error-invalid-file-key' => 'Interna eraro: la dosiero ne troveblis en la dumtempa stokejo.',
 3289+ 'mwe-upwiz-api-error-copyuploaddisabled' => 'Alŝuto per URL-adreso estas malebligata en tiu-ĉi servilo.',
 3290+ 'mwe-upwiz-api-error-mustbeloggedin' => 'Vi devas esti ensalutinta por rajti alŝuti dosierojn.',
32813291 'mwe-upwiz-api-error-empty-file' => 'La dosiero kiun vi sendis estis malplena.',
32823292 'mwe-upwiz-api-error-filetype-missing' => 'Mankas sufikso de la dosiero.',
32833293 'mwe-upwiz-api-error-filetype-banned' => 'Ĉi tiu tipo de dosiero estas malpermesita.',
@@ -3403,7 +3413,7 @@
34043414 'mwe-upwiz-api-error-stashfailed' => 'Error interno: el servidor no pudo almacenar el archivo temporal.',
34053415 'mwe-upwiz-api-error-missingresult' => 'Error interno: no se pudo determinar si la copia tuvo éxito.',
34063416 'mwe-upwiz-api-error-missingparam' => 'Error interno: faltan parámetros en la solicitud.',
3407 - 'mwe-upwiz-api-error-invalid-session-key' => 'Error interno: no se encontró el archivo en almacenamiento temporal.',
 3417+ 'mwe-upwiz-api-error-invalid-file-key' => 'Error interno: no se encontró el archivo en almacenamiento temporal.',
34083418 'mwe-upwiz-api-error-copyuploaddisabled' => 'La subida por URL está desactivada en este servidor.',
34093419 'mwe-upwiz-api-error-mustbeloggedin' => 'Debes iniciar sesión para subir archivos.',
34103420 'mwe-upwiz-api-error-empty-file' => 'El archivo que enviaste estaba vacío.',
@@ -3551,7 +3561,7 @@
35523562 'mwe-upwiz-api-error-stashfailed' => 'Sisetõrge: Serveril ei õnnestunud ajutist faili talletada.',
35533563 'mwe-upwiz-api-error-missingresult' => 'Sisetõrge: Ei õnnestu kindlaks teha, kas kopeerimine õnnestus.',
35543564 'mwe-upwiz-api-error-missingparam' => 'Sisetõrge: Päringust puudub mõni parameeter.',
3555 - 'mwe-upwiz-api-error-invalid-session-key' => 'Sisetõrge: Faili ei leitud ajutisest mälust.',
 3565+ 'mwe-upwiz-api-error-invalid-file-key' => 'Sisetõrge: Faili ei leitud ajutisest mälust.',
35563566 'mwe-upwiz-api-error-copyuploaddisabled' => 'URLi kaudu üleslaadimine on selles serveris keelatud.',
35573567 'mwe-upwiz-api-error-mustbeloggedin' => 'Failide üleslaadimiseks pead sisse logima.',
35583568 'mwe-upwiz-api-error-empty-file' => 'Üleslaaditav fail on tühi.',
@@ -3926,7 +3936,7 @@
39273937 'mwe-upwiz-api-error-stashfailed' => 'Sisäinen virhe: välikaikaisen tiedoston tallentaminen epäonnistui.',
39283938 'mwe-upwiz-api-error-missingresult' => 'Sisäinen virhe: ei voitu varmistaa, että tallennus onnistui.',
39293939 'mwe-upwiz-api-error-missingparam' => 'Sisäinen virhe: pyynnöstä puutuu parametrejä.',
3930 - 'mwe-upwiz-api-error-invalid-session-key' => 'Sisäinen virhe: tiedostoa ei löytynyt välikaisvarastosta.',
 3940+ 'mwe-upwiz-api-error-invalid-file-key' => 'Sisäinen virhe: tiedostoa ei löytynyt välikaisvarastosta.',
39313941 'mwe-upwiz-api-error-copyuploaddisabled' => 'Tallentaminen URL-osoitteesta ei ole käytössä.',
39323942 'mwe-upwiz-api-error-mustbeloggedin' => 'Sinun pitää olla kirjautunut sisään, jotta voisit tallentaa tiedostoja.',
39333943 'mwe-upwiz-api-error-empty-file' => 'Määrittämäsi tiedosto on tyhjä.',
@@ -4119,7 +4129,7 @@
41204130 'mwe-upwiz-api-error-stashfailed' => 'Erreur interne : le serveur n’a pas pu enregistrer le fichier temporaire.',
41214131 'mwe-upwiz-api-error-missingresult' => 'Erreur interne : Nous n’avons pas pu déterminer si la copie avait réussi.',
41224132 'mwe-upwiz-api-error-missingparam' => 'Erreur interne : Il manque des paramètres dans la requête.',
4123 - 'mwe-upwiz-api-error-invalid-session-key' => 'Erreur interne : aucun fichier trouvé dans le stockage temporaire.',
 4133+ 'mwe-upwiz-api-error-invalid-file-key' => 'Erreur interne : aucun fichier trouvé dans le stockage temporaire.',
41244134 'mwe-upwiz-api-error-copyuploaddisabled' => 'Les versements via URL sont désactivés sur ce serveur.',
41254135 'mwe-upwiz-api-error-mustbeloggedin' => 'Vous devez être connecté pour télécharger des fichiers.',
41264136 'mwe-upwiz-api-error-empty-file' => 'Le fichier que vous avez soumis était vide.',
@@ -4554,7 +4564,7 @@
45554565 'mwe-upwiz-api-error-stashfailed' => 'Erro interno: O servidor non puido almacenar os ficheiros temporais.',
45564566 'mwe-upwiz-api-error-missingresult' => 'Erro interno: Non se puido determinar se a copia saíu ben.',
45574567 'mwe-upwiz-api-error-missingparam' => 'Erro interno: Faltan parámetros na solicitude.',
4558 - 'mwe-upwiz-api-error-invalid-session-key' => 'Erro interno: Non se atopou o ficheiro no depósito temporal.',
 4568+ 'mwe-upwiz-api-error-invalid-file-key' => 'Erro interno: Non se atopou o ficheiro no depósito temporal.',
45594569 'mwe-upwiz-api-error-copyuploaddisabled' => 'As cargas mediante URL están desactivadas neste servidor.',
45604570 'mwe-upwiz-api-error-mustbeloggedin' => 'Debe acceder ao sistema para cargar ficheiros.',
45614571 'mwe-upwiz-api-error-empty-file' => 'O ficheiro que enviou estaba baleiro.',
@@ -4797,7 +4807,7 @@
47984808 'mwe-upwiz-api-error-stashfailed' => 'Intärne Fähler: Dr Server het kei temporäri Datei chenne spychere.',
47994809 'mwe-upwiz-api-error-missingresult' => 'Intärne Fähler: S het nit chenne feschtgstellt wäre, eb s Kopiere erfolgryych gsi isch.',
48004810 'mwe-upwiz-api-error-missingparam' => 'Intärne Fähler: Zue dr Aafrog fähle Parameter.',
4801 - 'mwe-upwiz-api-error-invalid-session-key' => 'Intärne Fähler: D Datei isch nit im temporäre Spycher gfunde wore.',
 4811+ 'mwe-upwiz-api-error-invalid-file-key' => 'Intärne Fähler: D Datei isch nit im temporäre Spycher gfunde wore.',
48024812 'mwe-upwiz-api-error-copyuploaddisabled' => 'S Uffelade iber e URL isch uf däm Server deaktiviert.',
48034813 'mwe-upwiz-api-error-mustbeloggedin' => 'Zum Dateie uffelade muesch aagmäldet syy.',
48044814 'mwe-upwiz-api-error-empty-file' => 'D Datei, wu Du uffeglade hesch, isch läär.',
@@ -4968,7 +4978,7 @@
49694979 'mwe-upwiz-api-error-stashfailed' => 'שגיאה פנימית: השרת נכשל באחסון הקובץ הזמני.',
49704980 'mwe-upwiz-api-error-missingresult' => 'שגיאה פנימית: לא יכולנו לקבוע אם ההעתקה הצליחה.',
49714981 'mwe-upwiz-api-error-missingparam' => 'שגיאה פנימית: פרמטרים חסרים בַּבַּקָּשָה.',
4972 - 'mwe-upwiz-api-error-invalid-session-key' => 'שגיאה פנימית: הקובץ לא נמצא במאגר הזמני.',
 4982+ 'mwe-upwiz-api-error-invalid-file-key' => 'שגיאה פנימית: הקובץ לא נמצא במאגר הזמני.',
49734983 'mwe-upwiz-api-error-copyuploaddisabled' => 'העלאה לפי כתובת כובתה בשרת זה.',
49744984 'mwe-upwiz-api-error-mustbeloggedin' => 'אתם צריכים להיות מחוברים כדי להעלות קבצים.',
49754985 'mwe-upwiz-api-error-empty-file' => 'קובץ ששלחתם היה ריק.',
@@ -5189,6 +5199,214 @@
51905200 'mwe-upwiz-feedback-error3' => 'שגיאה: אין תשובה מה־API',
51915201 );
51925202
 5203+/** Hindi (हिन्दी)
 5204+ * @author Mayur
 5205+ * @author Vibhijain
 5206+ */
 5207+$messages['hi'] = array(
 5208+ 'uploadwizard' => 'अपलोड विज़ार्ड',
 5209+ 'uploadwizard-desc' => 'अपलोड विज़ार्ड, मल्टीमीडिया प्रयोज्य अनुदान के लिए विकसित',
 5210+ 'mwe-upwiz-uploadcampaigns' => 'अपलोड अभियान',
 5211+ 'mwe-upwiz-js-off' => 'UploadWizard एक बेहतर इंटरफ़ेस के लिए जावास्क्रिप्ट का उपयोग करता है. या तो आपका ब्राउज़र जावास्क्रिप्ट का समर्थन नहीं करता है या जावास्क्रिप्ट बंद कर दिया, तो हम आपको एक सरल अपलोड फार्म दिखा रहे हैं',
 5212+ 'mwe-upwiz-extension-disabled' => 'यह पृष्ठ अस्थायी तकनीकी समस्याओं के कारण निष्क्रिय कर दिया गया. बीच में मानक अपलोड फार्म का प्रयास करें',
 5213+ 'mwe-upwiz-code-unknown' => 'अज्ञात भाषा',
 5214+ 'mwe-upwiz-step-tutorial' => 'जानें',
 5215+ 'mwe-upwiz-step-file' => 'अपलोड करें',
 5216+ 'mwe-upwiz-step-deeds' => 'रिलीज अधिकार',
 5217+ 'mwe-upwiz-step-details' => 'वर्णन',
 5218+ 'mwe-upwiz-step-thanks' => 'प्रयोग करें',
 5219+ 'mwe-upwiz-api-error-http' => 'आंतरिक त्रुटि: सर्वर से कनेक्ट करने में असमर्थ।',
 5220+ 'mwe-upwiz-api-error-ok-but-empty' => 'आंतरिक त्रुटि: सर्वर से कोई जवाब नहीं.',
 5221+ 'mwe-upwiz-api-error-unclassified' => 'एक अज्ञात त्रुटि उत्पन्न हुई',
 5222+ 'mwe-upwiz-api-error-unknown-code' => 'अज्ञात त्रुटि: " $1 "',
 5223+ 'mwe-upwiz-api-error-uploaddisabled' => 'इस विकि पर अपलोड अक्षम है.',
 5224+ 'mwe-upwiz-api-error-nomodule' => 'आंतरिक त्रुटि: कोई अपलोड मॉड्यूल सेट नहीं',
 5225+ 'mwe-upwiz-api-error-mustbeposted' => 'आंतरिक त्रुटि: HTTP POST अनुरोध की आवश्यकता है.',
 5226+ 'mwe-upwiz-api-error-badaccess-groups' => 'आपको इस विकि के लिए फ़ाइलें अपलोड करने की अनुमति नहीं है.',
 5227+ 'mwe-upwiz-api-error-stashfailed' => 'आंतरिक त्रुटि: सर्वर अस्थाई फ़ाइल को संग्रहीत करने में विफल।',
 5228+ 'mwe-upwiz-api-error-missingresult' => 'आन्तरिक त्रुटि: यह प्रतिलिपि सफल निर्धारित नहीं हो सकी',
 5229+ 'mwe-upwiz-api-error-missingparam' => 'आंतरिक त्रुटि: अनुरोध पर पैरामीटर लापता',
 5230+ 'mwe-upwiz-api-error-invalid-file-key' => 'आंतरिक त्रुटि: फ़ाइल अस्थायी भंडारण में नहीं पाया गया.',
 5231+ 'mwe-upwiz-api-error-copyuploaddisabled' => 'URL द्वारा इस सर्वर पर अपलोड अक्षम है।',
 5232+ 'mwe-upwiz-api-error-mustbeloggedin' => 'आप फ़ाइलों को अपलोड करने के लिये आपको लॉग इन होना चाहिए.',
 5233+ 'mwe-upwiz-api-error-empty-file' => 'प्रस्तुत फ़ाइल खाली था।',
 5234+ 'mwe-upwiz-api-error-file-too-large' => 'प्रस्तुत फ़ाइल बहुत बड़ी थी।',
 5235+ 'mwe-upwiz-api-error-filetype-missing' => 'फाईल की एक्सटेंशन लापता है.',
 5236+ 'mwe-upwiz-api-error-filetype-banned' => 'इस प्रकार की फ़ाइल पर प्रतिबंध लगा दिया है।',
 5237+ 'mwe-upwiz-api-error-filename-tooshort' => 'फ़ाइल का नाम बहुत छोटा है।',
 5238+ 'mwe-upwiz-api-error-illegal-filename' => 'फ़ाइल नाम की अनुमति नहीं है।',
 5239+ 'mwe-upwiz-api-error-verification-error' => 'यह फ़ाइल दूषित हो सकती है, या गलत एक्सटेंशन है।',
 5240+ 'mwe-upwiz-api-error-hookaborted' => 'आपके द्वारा प्रयासरत संशोधन विस्तार हूक द्वारा निरस्त किया गया।',
 5241+ 'mwe-upwiz-api-error-unknown-error' => 'आंतरिक त्रुटि: आपकी फ़ाइल अपलोड करने का प्रयास करते समय कुछ गलत हो गया था।',
 5242+ 'mwe-upwiz-api-error-internal-error' => 'आंतरिक त्रुटि: विकि पर अपने अपलोड प्रसंस्करण के साथ कुछ गलत हो गया था.',
 5243+ 'mwe-upwiz-api-error-overwrite' => 'मौजूदा फ़ाइल को अधिलेखित करने की अनुमति नहीं है',
 5244+ 'mwe-upwiz-api-error-badtoken' => 'आंतरिक त्रुटि: बुरी टोकन।',
 5245+ 'mwe-upwiz-api-error-fetchfileerror' => 'आंतरिक त्रुटि: जब फ़ाइल लाया जा रहा तो कुछ गलत हो गया था।',
 5246+ 'mwe-upwiz-api-error-duplicate' => 'वहाँ {{PLURAL:$1| [ $2 अन्य फ़ाइल] | रहे हैं [ $2 कुछ अन्य फ़ाइलों]}} एक ही सामग्री के साथ साइट पर पहले से ही है.',
 5247+ 'mwe-upwiz-api-error-duplicate-popup-title' => 'डुप्लिकेट {{PLURAL:$1| फ़ाइल | फ़ाइलें}}',
 5248+ 'mwe-upwiz-api-error-duplicate-archive' => 'वहाँ {{PLURAL:$1|था [$2 कुछ अन्य फ़ाइल] |were [$2 कुछ अन्य फ़ाइलें]}}, पहले से ही {{PLURAL:$1|यह was|they थे}} परन्तु हटा दिये गये',
 5249+ 'mwe-upwiz-api-error-duplicate-archive-popup-title' => 'डुप्लिकेट {{PLURAL:$1| फ़ाइल | फ़ाइलें}} है कि पहले से ही हटा दिया गया है',
 5250+ 'mwe-upwiz-api-error-unknown-warning' => 'अज्ञात चेतावनी: $1',
 5251+ 'mwe-upwiz-api-error-timeout' => 'सर्वर ने अपेक्षित समय के भीतर जवाब नहीं दिया',
 5252+ 'mwe-upwiz-api-error-noimageinfo' => 'अपलोड सफल, लेकिन सर्वर ने फ़ाइल के बारे में हमें कोई जानकारी नहीं दी.',
 5253+ 'mwe-upwiz-api-warning-exists' => 'वहाँ पहले से ही समान फ़ाइल नाम के साथ [ $1 ] [$1 दूसरी फ़ाइल] मौजूद है',
 5254+ 'mwe-upwiz-api-warning-was-deleted' => 'इस नाम से एक फ़ाइल " $1 " है , लेकिन इसे नष्ट कर दिया गया है और आप फ़ाइल reupload नहीं कर सकते, यदि आपकी फ़ाइल अलग है तो इसका नाम बदल कर इसे अपलोड करे',
 5255+ 'mwe-upwiz-tutorial-error-localized-file-missing' => 'क्षमा करे हमें आपकी भाषा में सामग्री नहीं मिली, कृपया अंग्रेजी भाषा की सहायता ले',
 5256+ 'mwe-upwiz-tutorial-error-file-missing' => 'क्षमा करें, हम हम ऐसे किसी भी को खोजने में असमर्थ रहें जिसकी अपेक्षा आपको यहाँ हैं कृपया सिस्टम व्यवस्थापक से संपर्क करें।',
 5257+ 'mwe-upwiz-tutorial-error-cannot-transform' => 'क्षमा करें, हम इस स्क्रीन फिट करने के लिए ट्यूटोरियल की एक स्केल्ड छवि नहीं मिल सका। यह विकीमीडिया कॉमन्स के साथ एक अस्थायी समस्या हो सकता है; बाद में पुन: प्रयास करें।',
 5258+ 'mwe-upwiz-help-desk' => 'सहायता डेस्क',
 5259+ 'mwe-upwiz-help-desk-url' => 'सहायता डेस्क',
 5260+ 'mwe-upwiz-add-file-n' => 'अन्य फ़ाइल जोड़ें',
 5261+ 'mwe-upwiz-add-file-0-free' => 'किसी मीडीया फाईल को दान करने के लिये चुने',
 5262+ 'mwe-upwiz-transport-started' => 'शुरू ...',
 5263+ 'mwe-upwiz-uploading' => 'अपलोड हो रहा है ...',
 5264+ 'mwe-upwiz-transported' => 'अपलोड समाप्त किया...',
 5265+ 'mwe-upwiz-stashed-upload' => 'ठीक है',
 5266+ 'mwe-upwiz-getting-metadata' => 'फ़ाइल जानकारी पूर्वावलोकन हो रही है...',
 5267+ 'mwe-upwiz-submitting-details' => 'विवरण और प्रकाशन को प्रस्तुत किया जा रहा है .',
 5268+ 'mwe-upwiz-published' => 'प्रकाशित!',
 5269+ 'mwe-upwiz-failed' => 'विफल रहे।',
 5270+ 'mwe-upwiz-remove' => 'हटायें',
 5271+ 'mwe-upwiz-remove-upload' => 'इस फाइल अपलोड करने के लिए फ़ाइलों की सूची से निकालें',
 5272+ 'mwe-upwiz-remove-description' => 'इस वर्णन को निकालें',
 5273+ 'mwe-upwiz-upload' => 'अपलोड करें',
 5274+ 'mwe-upwiz-file-all-ok' => 'सभी अपलोड सफल रहे',
 5275+ 'mwe-upwiz-file-some-failed' => 'कुछ अपलोड विफल रहे।',
 5276+ 'mwe-upwiz-file-retry' => 'विफल अपलोड फिर से प्रयास करें',
 5277+ 'mwe-upwiz-next-file-despite-failures' => 'फिर भी जारी रखें',
 5278+ 'mwe-upwiz-skip-tutorial-future' => 'भविष्य में इस चरण को छोड़',
 5279+ 'mwe-upwiz-file-all-failed' => 'कोई भी अपलोड सफल नहीं रहा',
 5280+ 'mwe-upwiz-progressbar-uploading' => 'अपलोड',
 5281+ 'mwe-upwiz-finished' => 'समाप्त!',
 5282+ 'mwe-upwiz-deeds-custom-prompt' => 'या:',
 5283+ 'mwe-upwiz-source-ownwork-assert-note' => 'सका मतलब है कि आपका काम Creative Commons Attribution ShareAlike लाइसेंस के तहत जारी है',
 5284+ 'mwe-upwiz-source-thirdparty-intro' => 'कृपया वह पता दर्ज करें जहाँ आप प्रत्येक फ़ाइल मिल गया',
 5285+ 'mwe-upwiz-source-thirdparty-custom-multiple-intro' => 'यदि सभी फ़ाइलें एक ही स्रोत, लेखक, और कॉपीराइट की स्थिति है, तो आप उन्हें केवल एक बार उन सभी के लिए दर्ज कर सकते हैं.',
 5286+ 'mwe-upwiz-source-thirdparty-accept' => 'ठीक है',
 5287+ 'mwe-upwiz-more-options' => 'अधिक विकल्प...',
 5288+ 'mwe-upwiz-fewer-options' => 'कम विकल्प ...',
 5289+ 'mwe-upwiz-desc' => 'विवरण',
 5290+ 'mwe-upwiz-desc-add-n' => 'किसी अन्य भाषा में वर्णन जोड़ें',
 5291+ 'mwe-upwiz-desc-add-0' => 'एक वर्णन जोड़ें',
 5292+ 'mwe-upwiz-title' => 'शीर्षक',
 5293+ 'mwe-upwiz-media-type' => 'मीडिया प्रकार',
 5294+ 'mwe-upwiz-date-created' => 'बनाया गया दिनांक',
 5295+ 'mwe-upwiz-location' => 'स्थान',
 5296+ 'mwe-upwiz-copyright-info' => 'रिलीज अधिकार',
 5297+ 'mwe-upwiz-author' => 'लेखक (ओं)',
 5298+ 'mwe-upwiz-other' => 'अन्य जानकारी',
 5299+ 'mwe-upwiz-source' => 'स्रोत',
 5300+ 'mwe-upwiz-thanks-intro' => 'अपलोड करने के लिए धन्यवाद!',
 5301+ 'mwe-upwiz-upload-error-duplicate-filename-error' => 'आप पहले से ही "$1" फ़ाइल अपलोड कर रहे हैं',
 5302+ 'mwe-upwiz-allowed-filename-extensions' => 'अनुमति एक्सटेंशन हैं:',
 5303+ 'mwe-upwiz-help-allowed-filename-extensions' => 'अनुमति प्राप्त फ़ाइल नाम एक्सटेंशन',
 5304+ 'mwe-upwiz-upload-error-duplicate' => 'यह फ़ाइल पहले इस विकि पर अपलोड किया गया था.',
 5305+ 'mwe-upwiz-upload-error-stashed-anyway' => 'वैसे भी अपलोड करें?',
 5306+ 'mwe-upwiz-ok' => 'ठीक है',
 5307+ 'mwe-upwiz-cancel' => 'रद्द करें',
 5308+ 'mwe-upwiz-fileexists-replace-on-page' => 'इस नाम वाली एक फ़ाइल पहले से मौजूद है। यदि आप इसे बदलना चाहते हैं, तो [$2 $1] पेज पर जायें',
 5309+ 'mwe-upwiz-fileexists-replace-no-link' => 'इस नाम वाली एक फ़ाइल पहले से मौजूद है।',
 5310+ 'mwe-upwiz-thumbnail-more' => 'बड़ा करें',
 5311+ 'mwe-upwiz-overwrite' => 'फ़ाइल बदलें',
 5312+ 'mwe-upwiz-next' => 'अगला',
 5313+ 'mwe-upwiz-next-file' => 'जारी रखें',
 5314+ 'mwe-upwiz-next-deeds' => 'अगला',
 5315+ 'mwe-upwiz-next-details' => 'अगला',
 5316+ 'mwe-upwiz-home' => 'विकि मुखपृष्ठ पर जाएँ',
 5317+ 'mwe-upwiz-upload-another' => 'अधिक फ़ाइलें अपलोड करें',
 5318+ 'mwe-upwiz-tooltip-more-info' => 'और जानो.',
 5319+ 'mwe-upwiz-file-need-file' => 'कृपया एक अपलोड करने के पहले जोड़ें।',
 5320+ 'mwe-upwiz-deeds-need-license' => 'कृपया एक लाइसेंस का चयन करें।',
 5321+ 'mwe-upwiz-license-show-all' => 'एक अलग लाइसेंस का प्रयोग करें',
 5322+ 'mwe-upwiz-license-show-recommended' => 'अनुशंसित लायसेंस का उपयोग करें',
 5323+ 'mwe-upwiz-error-signature-blank' => 'आपको अपना यूज़रनेम या असली नाम के साथ क्षेत्र नीचे हस्ताक्षर करना चाहिए.',
 5324+ 'mwe-upwiz-error-signature-too-long' => 'आपका हस्ताक्षर बहुत लंबा है! यह $1 से कम से करो {{PLURAL:$1| चरित्र | अक्षर}}.',
 5325+ 'mwe-upwiz-error-blank' => 'इस फ़ील्ड की आवश्यकता है।',
 5326+ 'mwe-upwiz-error-too-short' => 'यह क्षेत्र बहुत छोटा है कृपाअ इसको $1 {{PLURAL:$1|अक्षरों}} से बढा़ करे',
 5327+ 'mwe-upwiz-error-bad-chars' => 'यह क्षेत्र वह संकेत लिये है जिनकी अनुमति नहीं है, कृपया विकिपाठ या HTML का प्रयाग मत करे',
 5328+ 'mwe-upwiz-error-date' => 'कृपया कोई मान्य दिनांक YYYY-MM-DD स्वरूप में दर्ज करें, या पॉपअप कैलेंडर से कोई दिनांक चुने।',
 5329+ 'mwe-upwiz-error-title-blacklisted' => 'यह शीर्षक में कुछ अवांछनीय पाठ शामिल हैं. कृपया यह संशोधन करे',
 5330+ 'mwe-upwiz-error-title-badchars' => 'यह शीर्षक कुछ अवांछनीय वर्ण हैं. कृपया उन्हें निकालें',
 5331+ 'mwe-upwiz-error-title-senselessimagename' => 'कृपया इस शीर्षक को अधिक अर्थपूर्ण बनाने।',
 5332+ 'mwe-upwiz-error-title-thumbnail' => 'यह एक थंबनेल शीर्षक की तरह लग रहा है। कृपया थंबनेल वापस विकि पर अपलोड न करें। अन्यथा, कृपया फ़ाइल नाम ठीक करें',
 5333+ 'mwe-upwiz-error-title-fileexists-shared-forbidden' => 'यह शीर्षक एक दूरस्थ साझा भण्डार पर एक फ़ाइल द्वारा आरक्षित है। कोई अन्य नाम चुनें।',
 5334+ 'mwe-upwiz-error-title-double-apostrophe' => 'यह शीर्षक एक डबल अपॉस्ट्रॉफ़ी होता है; कृपया इसे हटा दें।',
 5335+ 'mwe-upwiz-error-title-extension' => 'किसी फ़ाइल एक्सटेंशन को जोड़ने की आवश्यकता नहीं। बस एक मानव पठनीय शीर्षक बनाने और अनुप्रयोग के बाकी ख्याल रखना होगा।',
 5336+ 'mwe-upwiz-license-cc-by-sa-3.0' => 'क्रिएटिव कामन्स एट्रीब्यूशन-शेयर एलाइक 3.0',
 5337+ 'mwe-upwiz-license-cc-by-3.0' => 'क्रिएटिव कॉमन्स रोपण 3.0',
 5338+ 'mwe-upwiz-license-cc-by-sa-2.5' => 'क्रिएटिव कामन्स एट्रीब्यूशन-शेयर एलाइक 2.5',
 5339+ 'mwe-upwiz-license-cc-by-2.5' => 'क्रिएटिव कॉमन्स रोपण 2.5',
 5340+ 'mwe-upwiz-license-cc-by-sa-2.0' => 'क्रिएटिव कामन्स एट्रीब्यूशन-शेयर एलाइक 2.0',
 5341+ 'mwe-upwiz-license-cc-by-2.0' => 'क्रिएटिव कॉमन्स रोपण 2.0',
 5342+ 'mwe-upwiz-license-cc-zero' => 'क्रिएटिव कॉमन्स CC0 छूट (सार्वजनिक डोमेन)',
 5343+ 'mwe-upwiz-license-fal' => 'मुफ्त कलात्मक लाइसेंस',
 5344+ 'mwe-upwiz-license-own-pd' => 'सार्वजनिक डोमेन (सभी क्रिएटिव कॉमन्स शून्य लाइसेंस के साथ माफ कर दी अधिकार)',
 5345+ 'mwe-upwiz-license-pd-old-100' => 'लेखक 100 से अधिक साल पहले मर गया',
 5346+ 'mwe-upwiz-license-pd-old' => 'लेखक अधिक से अधिक 70 साल पहले मर गया',
 5347+ 'mwe-upwiz-license-pd-art' => 'प्रजनित चित्र जो उसकी उम्र के कारण सार्वजनिक क्षेत्र में है',
 5348+ 'mwe-upwiz-license-pd-us' => '1923 से पहले संयुक्त राज्य अमेरिका में प्रकाशित',
 5349+ 'mwe-upwiz-license-pd-usgov' => 'अमेरिका की संघीय सरकार का मूल कार्य',
 5350+ 'mwe-upwiz-license-pd-usgov-nasa' => 'नासा का मूल काम',
 5351+ 'mwe-upwiz-license-pd-usgov-military-navy' => 'अमेरिकी सैन्य नौसेना के मूल काम',
 5352+ 'mwe-upwiz-license-pd-ineligible' => 'कॉपीराइट होना करने के लिए भी सरल',
 5353+ 'mwe-upwiz-license-pd-ineligible-help' => 'इस एक के साथ सावधान रहना होगा। छवि बहुत आसान है, एक हरे रंग चक्र या लाल वर्ग की तरह हो गया है',
 5354+ 'mwe-upwiz-license-pd-textlogo' => 'केवल सरल पाठ (wordmark) के साथ लोगो',
 5355+ 'mwe-upwiz-license-copyrighted-free-use' => 'कॉपीराइट है, लेकिन किसी भी प्रयोजन के लिए व्यावसायिक रूप से शामिल किया जा सकता',
 5356+ 'mwe-upwiz-license-attribution' => 'यदि कॉपीराइट धारक ठीक से जिम्मेदार है व्यावसायिक तौर पर किसी भी प्रयोजन के लिए इस्तेमाल किया जा सकता है',
 5357+ 'mwe-upwiz-license-gfdl' => 'GNU मुक्त प्रलेखन अनुज्ञापत्र',
 5358+ 'mwe-upwiz-license-cc-by-sa-3.0-gfdl' => 'Copyleft, attribution required (GFDL, CC-BY-SA-3.0)',
 5359+ 'mwe-upwiz-license-cc-head' => 'कॉपीराइट धारक ने {{PLURAL:$1| यह कार्य|यह कार्य}} सही क्रिएटिव कॉमन्स लाइसेंस के साथ प्रकाशित किया है',
 5360+ 'mwe-upwiz-license-cc-subhead' => 'सभी क्रियेटिव कामन्स लाईसेन्स {{SITENAME}} अच्छे नहीं, कृपया कापीराईट धारक किसी एक लाईसेन्स का प्रयोग करे',
 5361+ 'mwe-upwiz-license-flickr-head' => 'कॉपीराइट धारक यह {{PLURAL:$1| फोटो या वीडियो | तस्वीरें या वीडियो}} फ़्लिकर पर सही लाइसेंस के साथ प्रकाशित् की थी।',
 5362+ 'mwe-upwiz-license-flickr-subhead' => 'Check the "License" header on the side of the Flickr page. Both the icons and license name that they used have to match one of the choices here.',
 5363+ 'mwe-upwiz-license-public-domain-head' => 'कॉपीराइट निश्चित रूप से समाप्त हो गया है',
 5364+ 'mwe-upwiz-license-usgov-head' => '{{PLURAL:$1|यह कार्य|यह कार्य}} यूस सरकार द्वारा बनाये गये थे',
 5365+ 'mwe-upwiz-license-misc' => 'विविध कारण',
 5366+ 'mwe-upwiz-license-custom-head' => 'केवल विशेषज्ञ :यहाँ ना दिखाये गये लाईसेन्स का कोड् भरे',
 5367+ 'mwe-upwiz-license-custom-subhead' => 'अपना विकिपाठ लिखे जो आपके अपलोड्स पे लाईसेन्स साँचा जोड देगा',
 5368+ 'mwe-upwiz-license-none-applicable-head' => 'मैं यह नहीं जानता कि उपरोक्त में कौनसा विकल्प लागू होता है, कृपया सहायता करे',
 5369+ 'mwe-upwiz-license-none-applicable-subhead' => 'अगर तुमको बिल्कुल यकीन नहीं है जो मूल लेखक के इरादे थे तो कृपया {{SITENAME}} के लिए अपलोड {{PLURAL:$1|इस file|these फ़ाइलें}} नहीं करो। छोड़ने के लिए नीचे का बटन दबाएँ',
 5370+ 'mwe-upwiz-license-none-applicable' => '{{PLURAL:$1|इस upload|these अपलोड}} प्रकाशन के बिना त्याग दें',
 5371+ 'mwe-upwiz-license-confirm-remove' => 'क्या वाकई आप {{PLURAL:$1|इस upload|these अपलोड}} निकालना चाहते हैं ?',
 5372+ 'mwe-upwiz-license-confirm-remove-title' => 'निकालने की पुष्टि करें',
 5373+ 'mwe-upwiz-license-external' => 'यह फ़ाइल $1: <b>$2</b> पर निम्नलिखित लाइसेंस के अंतर्गत है',
 5374+ 'mwe-upwiz-license-external-invalid' => 'यह फ़ाइल निम्नलिखित लाइसेंस के अंतर्गत है $1: <b>$2</b> एवं दुर्भाग्य से यह लाइसेंस {{SITENAME}} पर उपयोग के लिए उपयुक्त नहीं है।',
 5375+ 'mwe-upwiz-categories' => 'श्रेणियाँ',
 5376+ 'mwe-upwiz-categories-add' => 'जोड़ें',
 5377+ 'mwe-upwiz-category-remove' => 'यह श्रेणी हटाएँ',
 5378+ 'mwe-upwiz-thanks-caption' => 'यहाँ कैप्शन जोड़ें',
 5379+ 'mwe-upwiz-help-popup' => 'मदद',
 5380+ 'mwe-upwiz-help-popup-title' => 'शीर्षक',
 5381+ 'mwe-upwiz-thumbnail-failed' => 'अपलोड सफल, लेकिन सर्वर एक पूर्वावलोकन थंबनेल नहीं मिल सका.',
 5382+ 'mwe-upwiz-unparseable-filename' => '"$1" फ़ाइल का नाम नहीं समझ सका',
 5383+ 'mwe-upwiz-image-preview' => 'चित्र पूर्वावलोकन',
 5384+ 'mwe-upwiz-subhead-message' => 'हमारे नए अपलोड उपकरण का उपयोग करने के लिए धन्यवाद!',
 5385+ 'mwe-upwiz-subhead-bugs' => '[$1 ज्ञात समस्याएँ]',
 5386+ 'mwe-upwiz-subhead-translate' => '[ $1 अनुवाद के साथ मदद]',
 5387+ 'mwe-upwiz-subhead-alt-upload' => '[$1 पुराने फार्म को वापस]',
 5388+ 'mwe-upwiz-feedback-prompt' => '[$1 प्रतिक्रिया छोड़]',
 5389+ 'mwe-upwiz-feedback-note' => 'आपकी प्रतिक्रिया सार्वजनिक रूप से पृष्ठ "[$2 $1]" पर पोस्ट किया जाएगा अपने उपयोगकर्ता नाम, ब्राउज़र संस्करण और ऑपरेटिंग सिस्टम के साथ।',
 5390+ 'mwe-upwiz-feedback-subject' => 'विषय:',
 5391+ 'mwe-upwiz-feedback-message' => 'संदेश:',
 5392+ 'mwe-upwiz-feedback-title' => 'अपलोड विज़ार्ड के बारे में प्रतिक्रिया दो',
 5393+ 'mwe-upwiz-feedback-cancel' => 'रद्द करें',
 5394+ 'mwe-upwiz-feedback-submit' => 'प्रतिक्रिया भेजें',
 5395+ 'mwe-upwiz-feedback-adding' => 'पृष्ठ पर प्रतिक्रिया जोड़ना ...',
 5396+ 'mwe-upwiz-feedback-error1' => 'त्रुटि: न पहचाना गया परिणाम एपीआई से',
 5397+ 'mwe-upwiz-feedback-error2' => 'त्रुटि: संपादन विफल रहा है',
 5398+ 'mwe-upwiz-feedback-error3' => 'त्रुटि: एपीआई से कोई प्रतिक्रिया नहीं',
 5399+ 'mwe-upwiz-campaigns-name' => 'अभियान का नाम',
 5400+ 'mwe-upwiz-campaigns-status' => 'स्थिति',
 5401+ 'mwe-upwiz-campaigns-enabled' => 'सक्षम',
 5402+ 'mwe-upwiz-campaigns-disabled' => 'अक्षम',
 5403+ 'mwe-upwiz-campaigns-edit' => 'संपादन',
 5404+ 'mwe-upwiz-campaigns-add' => 'जोड़ें',
 5405+ 'mwe-upwiz-campaigns-addnew' => 'एक नया अभियान जोड़ें',
 5406+ 'mwe-upwiz-campaigns-newname' => 'अभियान का नाम:',
 5407+ 'mwe-upwiz-campaigns-namedoc' => 'अभियान का नाम यूआरएल में इस्तेमाल पहचानकर्ता है। ie "name" in ?campaign=name',
 5408+ 'mwe-upwiz-campaigns-existing' => 'मौजूदा अभियान',
 5409+);
 5410+
51935411 /** Croatian (Hrvatski)
51945412 * @author Roberta F.
51955413 * @author SpeedyGonsales
@@ -5213,7 +5431,7 @@
52145432 'mwe-upwiz-api-error-stashfailed' => 'Wikiprojekt nije mogao spremiti datoteku.',
52155433 'mwe-upwiz-api-error-missingresult' => 'Nismo mogli utvrditi je li kopiranje uspjelo.',
52165434 'mwe-upwiz-api-error-missingparam' => 'Postavljanje nije imalo sve nužne podatke (možda je pogrješka u ovom postavljaču.)',
5217 - 'mwe-upwiz-api-error-invalid-session-key' => 'Poslužitelj nije mogao naći tu datoteku u vašim postavljenim datotekama.',
 5435+ 'mwe-upwiz-api-error-invalid-file-key' => 'Poslužitelj nije mogao naći tu datoteku u vašim postavljenim datotekama.',
52185436 'mwe-upwiz-api-error-copyuploaddisabled' => 'Postavljanja datoteka kopiranjem su onemogućena.',
52195437 'mwe-upwiz-api-error-mustbeloggedin' => 'Niste pravilno prijavljeni.',
52205438 'mwe-upwiz-api-error-empty-file' => 'Datoteka koju ste poslali je prazna.',
@@ -5373,7 +5591,7 @@
53745592 'mwe-upwiz-api-error-stashfailed' => 'Nutřkowny zmylk: serwer njemóžeše nachwilnu dataju składować.',
53755593 'mwe-upwiz-api-error-missingresult' => 'Nutřkowny zmylk: njeda so zwěsćić, hač kopěrowanje je so poradźiło.',
53765594 'mwe-upwiz-api-error-missingparam' => 'Nutřkowny zmylk: falowace parametry při naprašowanju.',
5377 - 'mwe-upwiz-api-error-invalid-session-key' => 'Nutřkowny zmylk: dataja njeje so w nachwilnym składowaku namakała.',
 5595+ 'mwe-upwiz-api-error-invalid-file-key' => 'Nutřkowny zmylk: dataja njeje so w nachwilnym składowaku namakała.',
53785596 'mwe-upwiz-api-error-copyuploaddisabled' => 'Nahrawanje přez URL je na tutym serwerje znjemóžnjene.',
53795597 'mwe-upwiz-api-error-mustbeloggedin' => 'Dyrbiš přizjewjeny być, zo by dataje nahrał.',
53805598 'mwe-upwiz-api-error-empty-file' => 'Dataja, kotruž sy nahrał, je prózdna.',
@@ -5549,7 +5767,7 @@
55505768 'mwe-upwiz-api-error-stashfailed' => 'Belső hiba: a kiszolgálünak nem sikerült eltárolni az ideiglenes fájlt.',
55515769 'mwe-upwiz-api-error-missingresult' => 'Belső hiba: nem sikerült megállapítani, hogy a másolás sikeres volt-e.',
55525770 'mwe-upwiz-api-error-missingparam' => 'Belső hiba: paraméterek hiányoznak a kérésből.',
5553 - 'mwe-upwiz-api-error-invalid-session-key' => 'Belső hiba: a fájl nem található az ideiglenes tárhelyen.',
 5771+ 'mwe-upwiz-api-error-invalid-file-key' => 'Belső hiba: a fájl nem található az ideiglenes tárhelyen.',
55545772 'mwe-upwiz-api-error-copyuploaddisabled' => 'Az URL-címes feltöltés nem engedélyezett ezen a kiszolgálón.',
55555773 'mwe-upwiz-api-error-mustbeloggedin' => 'Be kell jelentkezned fájlok feltöltéséhez.',
55565774 'mwe-upwiz-api-error-empty-file' => 'Az általad elküldött fájl üres volt.',
@@ -5792,7 +6010,7 @@
57936011 'mwe-upwiz-api-error-stashfailed' => 'Error interne: le servitor non poteva immagazinar le file temporari.',
57946012 'mwe-upwiz-api-error-missingresult' => 'Error interne: non poteva determinar si le copia succedeva.',
57956013 'mwe-upwiz-api-error-missingparam' => 'Error interne: certe parametros mancava al requesta.',
5796 - 'mwe-upwiz-api-error-invalid-session-key' => 'Error interne: file non trovate in le spatio de immagazinage temporari.',
 6014+ 'mwe-upwiz-api-error-invalid-file-key' => 'Error interne: file non trovate in le spatio de immagazinage temporari.',
57976015 'mwe-upwiz-api-error-copyuploaddisabled' => 'Le incargamentos per URL es disactivate in iste servitor.',
57986016 'mwe-upwiz-api-error-mustbeloggedin' => 'Es necessari aperir session pro incargar files.',
57996017 'mwe-upwiz-api-error-empty-file' => 'Le file que tu submitteva es vacue.',
@@ -6038,7 +6256,7 @@
60396257 'mwe-upwiz-api-error-stashfailed' => 'Kesalahan internal: server gagal menyimpan berkas sementara.',
60406258 'mwe-upwiz-api-error-missingresult' => 'Kesalahan internal: tidak dapat menentukan apakah penyalinan berhasil.',
60416259 'mwe-upwiz-api-error-missingparam' => 'Kesalahan internal: parameter permintaan hilang.',
6042 - 'mwe-upwiz-api-error-invalid-session-key' => 'Kesalahan internal: berkas tidak ditemukan di penyimpanan sementara.',
 6260+ 'mwe-upwiz-api-error-invalid-file-key' => 'Kesalahan internal: berkas tidak ditemukan di penyimpanan sementara.',
60436261 'mwe-upwiz-api-error-copyuploaddisabled' => 'Mengunggah melalui URL dilarang pada peladen ini.',
60446262 'mwe-upwiz-api-error-mustbeloggedin' => 'Anda harus masuk log untuk mengunggah berkas.',
60456263 'mwe-upwiz-api-error-empty-file' => 'Berkas yang Anda kirim kosong.',
@@ -6314,7 +6532,7 @@
63156533 'mwe-upwiz-api-error-stashfailed' => 'Errore interno: il server non è riuscito a memorizzare il documento temporaneo.',
63166534 'mwe-upwiz-api-error-missingresult' => 'Errore interno: impossibile determinare se la copia è riuscita.',
63176535 'mwe-upwiz-api-error-missingparam' => 'Errore interno: parametri della richiesta mancanti',
6318 - 'mwe-upwiz-api-error-invalid-session-key' => 'Errore interno: documento non presente nella cartella dei file temporanei',
 6536+ 'mwe-upwiz-api-error-invalid-file-key' => 'Errore interno: documento non presente nella cartella dei file temporanei',
63196537 'mwe-upwiz-api-error-copyuploaddisabled' => 'Il caricamento tramite URL è disabilitato su questo server.',
63206538 'mwe-upwiz-api-error-mustbeloggedin' => "Devi aver effettuato l'accesso per caricare i documenti.",
63216539 'mwe-upwiz-api-error-empty-file' => 'Il documento selezionato era vuoto.',
@@ -6566,7 +6784,7 @@
65676785 'mwe-upwiz-api-error-stashfailed' => '内部エラー:サーバーは一時ファイルを格納できませんでした。',
65686786 'mwe-upwiz-api-error-missingresult' => '内部エラー:複製に成功したか判断できませんでした。',
65696787 'mwe-upwiz-api-error-missingparam' => '内部エラー:リクエストのパラメータが足りません。',
6570 - 'mwe-upwiz-api-error-invalid-session-key' => '内部エラー:一時格納場所にファイルが見つかりませんでした。',
 6788+ 'mwe-upwiz-api-error-invalid-file-key' => '内部エラー:一時格納場所にファイルが見つかりませんでした。',
65716789 'mwe-upwiz-api-error-copyuploaddisabled' => 'URLによるアップロードはこのサーバーでは無効になっています。',
65726790 'mwe-upwiz-api-error-mustbeloggedin' => 'ファイルをアップロードするにはログインする必要があります。',
65736791 'mwe-upwiz-api-error-empty-file' => '送信されたファイルは空でした。',
@@ -6756,7 +6974,7 @@
67576975 'mwe-upwiz-api-error-stashfailed' => 'შიდა შეცდომა. ვიკიმ ვერ შეძლო დროებით ფაილის შენახვა.',
67586976 'mwe-upwiz-api-error-missingresult' => 'შიდა შეცდომა. ვერ მოხერხდა იმის დადგენა, იყო თუ არა კოპირება წარმატებული.',
67596977 'mwe-upwiz-api-error-missingparam' => 'ფაილი არ შეიცავს ყველა საჭირო ინფორმაციას (შესაძლებელია პროგრამული შეცდომაც)',
6760 - 'mwe-upwiz-api-error-invalid-session-key' => 'სერვერმა ვერ იპოვა თქვენ მიერ მითითებული ფაილი',
 6978+ 'mwe-upwiz-api-error-invalid-file-key' => 'სერვერმა ვერ იპოვა თქვენ მიერ მითითებული ფაილი',
67616979 'mwe-upwiz-api-error-copyuploaddisabled' => 'კოპირების გზით ატვირთვის შესაძლებლობა ამ ვიკიში გამორთულია.',
67626980 'mwe-upwiz-api-error-mustbeloggedin' => 'თქვენ არ ხართ შემოსული.',
67636981 'mwe-upwiz-api-error-empty-file' => 'არჩეული ფაილი ცარიელია.',
@@ -6889,7 +7107,7 @@
68907108 'mwe-upwiz-api-error-stashfailed' => '내부 오류: 서버가 임시 파일을 저장하지 못했습니다.',
68917109 'mwe-upwiz-api-error-missingresult' => '내부 오류: 파일의 복제가 성공했는지 판단할 수 없습니다.',
68927110 'mwe-upwiz-api-error-missingparam' => '내부 오류: 요청 중 매개변수가 누락되었습니다.',
6893 - 'mwe-upwiz-api-error-invalid-session-key' => '내부 오류: 임시 저장소에서 파일을 찾지 못했습니다.',
 7111+ 'mwe-upwiz-api-error-invalid-file-key' => '내부 오류: 임시 저장소에서 파일을 찾지 못했습니다.',
68947112 'mwe-upwiz-api-error-copyuploaddisabled' => '이 서버에서 URL을 통해 파일 올리기가 비활성화되어 있습니다.',
68957113 'mwe-upwiz-api-error-mustbeloggedin' => '파일을 올리기 위해서는 로그인해야 합니다.',
68967114 'mwe-upwiz-api-error-empty-file' => '당신이 올리려는 파일이 비어 있습니다.',
@@ -6952,7 +7170,7 @@
69537171 'mwe-upwiz-api-error-stashfailed' => 'Fähler: Dä ẞööver hät kein Datteije zweschejeschpeischert.',
69547172 'mwe-upwiz-api-error-missingresult' => 'Fähler: Mer kunnte nit eruß krijje, ob et Koppeere joht jejange wohr.',
69557173 'mwe-upwiz-api-error-missingparam' => 'Fähler: Doh fähle Parrameetere en däm, wat aan dä ẞööver övvermeddelt woode es.',
6956 - 'mwe-upwiz-api-error-invalid-session-key' => 'Fähler: En Dattei wohr nit em Zwescheschpeischer ze fenge.',
 7174+ 'mwe-upwiz-api-error-invalid-file-key' => 'Fähler: En Dattei wohr nit em Zwescheschpeischer ze fenge.',
69577175 'mwe-upwiz-api-error-copyuploaddisabled' => 'Et Huhlaade vun enem <i lang="en">URL</i> es op däm ẞööver heh nit zohjelohße.',
69587176 'mwe-upwiz-api-error-mustbeloggedin' => 'För Datteije huh_ze_laade moß de ald enjelogg sinn.',
69597177 'mwe-upwiz-api-error-empty-file' => 'En dä huhjelaade Dattei wohr jaa_nix dren.',
@@ -7192,7 +7410,7 @@
71937411 'mwe-upwiz-api-error-stashfailed' => 'Interne Feeler: de Server konnt den temporäre Fichier net späicheren.',
71947412 'mwe-upwiz-api-error-missingresult' => "Interne Feeler: et konnt net festgestallt ginn ob d'Kopie eppes ginn ass.",
71957413 'mwe-upwiz-api-error-missingparam' => 'Interne Feeler: E vun de Parameter feelt an der Ufro.',
7196 - 'mwe-upwiz-api-error-invalid-session-key' => 'Interne Feeler: de Fichier gouf op der temporärer Späicherplaz net fonnt.',
 7414+ 'mwe-upwiz-api-error-invalid-file-key' => 'Interne Feeler: de Fichier gouf op der temporärer Späicherplaz net fonnt.',
71977415 'mwe-upwiz-api-error-copyuploaddisabled' => "D'Eroplueden iwwer eng URL ass op dësem Server desaktivéiert.",
71987416 'mwe-upwiz-api-error-mustbeloggedin' => 'Dir musst ageloggt si fir Fichieren eropzelueden.',
71997417 'mwe-upwiz-api-error-empty-file' => 'De Fichier deen Dir geschéckt hutt war eidel.',
@@ -7398,7 +7616,7 @@
73997617 'mwe-upwiz-api-error-uploaddisabled' => 'Įkėlimas išjungtas šioje wiki.',
74007618 'mwe-upwiz-api-error-mustbeposted' => 'Vidinė klaida: prašymas reikalauja HTTP POST.',
74017619 'mwe-upwiz-api-error-badaccess-groups' => 'Jums neleidžiama įkelti failus į šią wiki.',
7402 - 'mwe-upwiz-api-error-invalid-session-key' => 'Vidinė klaida: failas nerastas saugykloje.',
 7620+ 'mwe-upwiz-api-error-invalid-file-key' => 'Vidinė klaida: failas nerastas saugykloje.',
74037621 'mwe-upwiz-api-error-copyuploaddisabled' => 'Siuntimas pagal URL yra išjungtas šiame serveryje.',
74047622 'mwe-upwiz-api-error-mustbeloggedin' => 'Jūs turite būti prisijungęs kad galėtumėte įkelti failus.',
74057623 'mwe-upwiz-api-error-empty-file' => 'Pateikta failas buvo tuščias.',
@@ -7490,7 +7708,7 @@
74917709 'mwe-upwiz-api-error-stashfailed' => 'Внатрешна грешка: опслужувачот не успеа да ја складира привремената податотека.',
74927710 'mwe-upwiz-api-error-missingresult' => 'Внатрешна грешка: не можев да одредам дали копирањето заврши успешно.',
74937711 'mwe-upwiz-api-error-missingparam' => 'Внатрешна грешка: недостасуваат параметри за барањето.',
7494 - 'mwe-upwiz-api-error-invalid-session-key' => 'Внатрешна грешка: не ја пронајдов податотеката во привременото складиште.',
 7712+ 'mwe-upwiz-api-error-invalid-file-key' => 'Внатрешна грешка: не ја пронајдов податотеката во привременото складиште.',
74957713 'mwe-upwiz-api-error-copyuploaddisabled' => 'Подигањата со URL се оневозможени на овој опслужувач.',
74967714 'mwe-upwiz-api-error-mustbeloggedin' => 'Мора да сте најавени за да можете да подигате податотеки.',
74977715 'mwe-upwiz-api-error-empty-file' => 'Поднесената податотека е празна.',
@@ -7734,7 +7952,7 @@
77357953 'mwe-upwiz-api-error-stashfailed' => 'ആന്തരിക പിഴവ്: പ്രമാണം താത്കാലികമായി സംഭരിക്കുന്നതിൽ സെർവർ പരാജയപ്പെട്ടു.',
77367954 'mwe-upwiz-api-error-missingresult' => 'ആന്തരിക പിഴവ്: പകർത്തൽ വിജയകരമായിരുന്നോ എന്ന് നിർണ്ണയിക്കാനാവുന്നില്ല.',
77377955 'mwe-upwiz-api-error-missingparam' => 'ആന്തരിക പിഴവ്: ഈ അഭ്യർത്ഥനയിൽ ആവശ്യമായ ചരങ്ങൾ ലഭിച്ചില്ല.',
7738 - 'mwe-upwiz-api-error-invalid-session-key' => 'ആന്തരിക പിഴവ്: താത്കാലിക സംഭരണിയിൽ നിന്ന് പ്രമാണം കണ്ടെത്താനായില്ല.',
 7956+ 'mwe-upwiz-api-error-invalid-file-key' => 'ആന്തരിക പിഴവ്: താത്കാലിക സംഭരണിയിൽ നിന്ന് പ്രമാണം കണ്ടെത്താനായില്ല.',
77397957 'mwe-upwiz-api-error-copyuploaddisabled' => 'യൂ.ആർ.എൽ. ഉപയോഗിച്ചുള്ള അപ്‌ലോഡ് ഈ സെർവറിൽ പ്രവർത്തനസജ്ജമാക്കിയിട്ടില്ല.',
77407958 'mwe-upwiz-api-error-mustbeloggedin' => 'പ്രമാണങ്ങൾ അപ്‌ലോഡ് ചെയ്യാൻ താങ്കൾ ലോഗിൻ ചെയ്തിരിക്കണം.',
77417959 'mwe-upwiz-api-error-empty-file' => 'താങ്കൾ സമർപ്പിച്ച പ്രമാണം ശൂന്യമാണ്.',
@@ -7988,7 +8206,7 @@
79898207 'mwe-upwiz-api-error-stashfailed' => 'Ralat dalaman: pelayan tidak dapat menyimpan fail sementara.',
79908208 'mwe-upwiz-api-error-missingresult' => 'Ralat dalaman: tidak dapat ditentukan sama ada penyalinan berjaya.',
79918209 'mwe-upwiz-api-error-missingparam' => 'Ralat dalaman: kekosongan parameter pada permohonan.',
7992 - 'mwe-upwiz-api-error-invalid-session-key' => 'Ralat dalaman: fail tidak dijumpai dalam storan sementara.',
 8210+ 'mwe-upwiz-api-error-invalid-file-key' => 'Ralat dalaman: fail tidak dijumpai dalam storan sementara.',
79938211 'mwe-upwiz-api-error-copyuploaddisabled' => 'Ciri memuat naik melalui URL dimatikan di pelayan ini.',
79948212 'mwe-upwiz-api-error-mustbeloggedin' => 'Anda mesti log masuk untuk memuat naik fail.',
79958213 'mwe-upwiz-api-error-empty-file' => 'Fail yang anda serahkan adalah kosong.',
@@ -8298,7 +8516,7 @@
82998517 'mwe-upwiz-api-error-stashfailed' => 'आन्तरिक त्रुटि: अस्थाई फाइल राख्न सर्वर असफल भयो।',
83008518 'mwe-upwiz-api-error-missingresult' => 'आन्तरिक त्रुटि: कपी सफल भयो भएन भनेर निश्चय गर्ने सकिएन।',
83018519 'mwe-upwiz-api-error-missingparam' => 'आन्तरिक त्रुटि: अनुरोधमा पैरामीटरहरुको कमी',
8302 - 'mwe-upwiz-api-error-invalid-session-key' => 'आन्तरिक त्रुटि: अस्थाई भण्डारमा फाइल पाइएन।',
 8520+ 'mwe-upwiz-api-error-invalid-file-key' => 'आन्तरिक त्रुटि: अस्थाई भण्डारमा फाइल पाइएन।',
83038521 'mwe-upwiz-api-error-copyuploaddisabled' => 'यस सर्वरमा URL द्वारा अपलोड गर्ने व्यवस्था निस्क्रिय गरिएकोछ।',
83048522 'mwe-upwiz-api-error-mustbeloggedin' => 'फाइल अपलोड गर्न तपाईंले प्रवेश गरेको हुनुपर्छ।',
83058523 'mwe-upwiz-api-error-empty-file' => 'तपाईंले बुझाएको फाइल खालि छ।',
@@ -8420,7 +8638,7 @@
84218639 'mwe-upwiz-api-error-stashfailed' => 'Interne fout: de server kon het tijdelijke bestand niet opslaan.',
84228640 'mwe-upwiz-api-error-missingresult' => 'Interne fout: het was niet mogelijk vast te stellen of het kopiëren is geslaagd.',
84238641 'mwe-upwiz-api-error-missingparam' => 'Interne fout: niet alle parameters zijn in het verzoek meegeleverd.',
8424 - 'mwe-upwiz-api-error-invalid-session-key' => 'Interne fout: het bestand is niet aangetroffen in de tijdelijke opslag.',
 8642+ 'mwe-upwiz-api-error-invalid-file-key' => 'Interne fout: het bestand is niet aangetroffen in de tijdelijke opslag.',
84258643 'mwe-upwiz-api-error-copyuploaddisabled' => 'Uploaden via URL is uitgeschakeld op deze server.',
84268644 'mwe-upwiz-api-error-mustbeloggedin' => 'U moet aangemeld zijn om bestanden te kunnen uploaden.',
84278645 'mwe-upwiz-api-error-empty-file' => 'Het bestand dat u hebt geüpload is leeg.',
@@ -8810,7 +9028,7 @@
88119029 'mwe-upwiz-api-error-stashfailed' => 'ଭିତର ଅସୁବିଧା: ସର୍ଭର ଅସ୍ଥାୟୀ ଫାଇଲକୁ ସାଇତି ପାରିଲା ନାହିଁ ।',
88129030 'mwe-upwiz-api-error-missingresult' => 'ଭିତର ଅସୁବିଧା: ନକଲ କରିବା ଠିକରେ ହେଲାକି ନାହିଁ ଜାଣି ପାରିଲା ନାହିଁ ।',
88139031 'mwe-upwiz-api-error-missingparam' => 'ଭିତର ଅସୁବିଧା: ହଜିଯାଇଥିବା ପାରାମିଟର ସବୁକୁ ଅନୁରୋଧ କ୍ରମେ ଦେଖାଇଦିଆଗଲା ।',
8814 - 'mwe-upwiz-api-error-invalid-session-key' => 'ଭିତର ଅସୁବିଧା: ଫାଇଲଟି ଅସ୍ଥାୟୀ ସାଇତାଘର ଭିତରୁ ମିଳିଲାନାହିଁ ।',
 9032+ 'mwe-upwiz-api-error-invalid-file-key' => 'ଭିତର ଅସୁବିଧା: ଫାଇଲଟି ଅସ୍ଥାୟୀ ସାଇତାଘର ଭିତରୁ ମିଳିଲାନାହିଁ ।',
88159033 'mwe-upwiz-stashed-upload' => 'ଠିକ ଅଛି',
88169034 'mwe-upwiz-remove' => 'ବାହାର କରିବା',
88179035 'mwe-upwiz-source-thirdparty-accept' => 'ଠିକ ଅଛି',
@@ -8883,7 +9101,7 @@
88849102 'mwe-upwiz-api-error-stashfailed' => 'Błąd wewnętrzny – serwer nie mógł zapisać pliku tymczasowego.',
88859103 'mwe-upwiz-api-error-missingresult' => 'Błąd wewnętrzny – nie można określić czy kopiowanie się udało.',
88869104 'mwe-upwiz-api-error-missingparam' => 'Błąd wewnętrzny – brak jest niektórych wymaganych informacji do realizacji przesłania.',
8887 - 'mwe-upwiz-api-error-invalid-session-key' => 'Błąd wewnętrzny – nie można odnaleźć pliku w wśród plików tymczasowych.',
 9105+ 'mwe-upwiz-api-error-invalid-file-key' => 'Błąd wewnętrzny – nie można odnaleźć pliku w wśród plików tymczasowych.',
88889106 'mwe-upwiz-api-error-copyuploaddisabled' => 'Przesyłanie poprzez podanie adresu URL zostało na tym serwerze wyłączone.',
88899107 'mwe-upwiz-api-error-mustbeloggedin' => 'Musisz się zalogować aby przesyłać pliki.',
88909108 'mwe-upwiz-api-error-empty-file' => 'Przesłany przez Ciebie plik jest pusty.',
@@ -9127,7 +9345,7 @@
91289346 'mwe-upwiz-api-error-stashfailed' => "Eror antern: ël sërvent a l'ha pa podù memorisé l'archivi a temp.",
91299347 'mwe-upwiz-api-error-missingresult' => "Eror antern: as peul pa determiné se la còpia a l'é andàita bin.",
91309348 'mwe-upwiz-api-error-missingparam' => "Eror antern: paràmetr mancant ant l'arcesta.",
9131 - 'mwe-upwiz-api-error-invalid-session-key' => 'Eror antern: archivi pa trovà ant la memòria a temp.',
 9349+ 'mwe-upwiz-api-error-invalid-file-key' => 'Eror antern: archivi pa trovà ant la memòria a temp.',
91329350 'mwe-upwiz-api-error-copyuploaddisabled' => "Cariagi për anliura a l'é disabilità su sto sërvent.",
91339351 'mwe-upwiz-api-error-mustbeloggedin' => "A deuv esse intrà ant ël sistema për carié dj'archivi.",
91349352 'mwe-upwiz-api-error-empty-file' => "L'archivi ch'a l'ha mandà a l'era veuid.",
@@ -9393,7 +9611,7 @@
93949612 'mwe-upwiz-api-error-stashfailed' => 'Erro interno: O servidor não conseguiu armazenar o ficheiro temporário.',
93959613 'mwe-upwiz-api-error-missingresult' => 'Erro interno: Não foi possível determinar se a cópia foi feita.',
93969614 'mwe-upwiz-api-error-missingparam' => 'Erro interno: Há parâmetros em falta no pedido.',
9397 - 'mwe-upwiz-api-error-invalid-session-key' => 'Erro interno: O ficheiro não foi encontrado no armazenamento temporário.',
 9615+ 'mwe-upwiz-api-error-invalid-file-key' => 'Erro interno: O ficheiro não foi encontrado no armazenamento temporário.',
93989616 'mwe-upwiz-api-error-copyuploaddisabled' => 'O recebimento de ficheiros por URL não foi possibilitado neste servidor.',
93999617 'mwe-upwiz-api-error-mustbeloggedin' => 'Tem de estar autenticado para enviar ficheiros.',
94009618 'mwe-upwiz-api-error-empty-file' => 'O ficheiro que enviou está vazio.',
@@ -9641,7 +9859,7 @@
96429860 'mwe-upwiz-api-error-stashfailed' => 'Erro interno: o servidor não conseguiu armazenar o arquivo temporário.',
96439861 'mwe-upwiz-api-error-missingresult' => 'Erro interno: não foi possível determinar se a cópia foi feita.',
96449862 'mwe-upwiz-api-error-missingparam' => 'Erro interno: parâmetros em falta no pedido.',
9645 - 'mwe-upwiz-api-error-invalid-session-key' => 'Erro interno: o arquivo não foi encontrado no armazenamento temporário.',
 9863+ 'mwe-upwiz-api-error-invalid-file-key' => 'Erro interno: o arquivo não foi encontrado no armazenamento temporário.',
96469864 'mwe-upwiz-api-error-copyuploaddisabled' => 'O upload por URL está desativado neste servidor.',
96479865 'mwe-upwiz-api-error-mustbeloggedin' => 'Você precisa estar autenticado para enviar arquivos.',
96489866 'mwe-upwiz-api-error-empty-file' => 'O arquivo que você enviou está vazio.',
@@ -9883,7 +10101,7 @@
988410102 'mwe-upwiz-api-error-stashfailed' => 'Eroare internă: serverul nu a putut stoca fișierul temporar.',
988510103 'mwe-upwiz-api-error-missingresult' => 'Eroare internă: nu s-a putut determina dacă copierea a reușit.',
988610104 'mwe-upwiz-api-error-missingparam' => 'Eroare internă: lipsesc parametrii cererii.',
9887 - 'mwe-upwiz-api-error-invalid-session-key' => 'Eroare internă: fișierul nu a fost găsit în depozitul temporar.',
 10105+ 'mwe-upwiz-api-error-invalid-file-key' => 'Eroare internă: fișierul nu a fost găsit în depozitul temporar.',
988810106 'mwe-upwiz-api-error-copyuploaddisabled' => 'Încărcarea prin URL este dezactivată pe acest server.',
988910107 'mwe-upwiz-api-error-mustbeloggedin' => 'Trebuie să fiți autentificat pentru a încărca fișiere.',
989010108 'mwe-upwiz-api-error-empty-file' => 'Fișierul încărcat de dumneavoastră este gol.',
@@ -10069,7 +10287,7 @@
1007010288 'mwe-upwiz-api-error-stashfailed' => 'Внутренняя ошибка. Сервер не смог сохранить временный файл.',
1007110289 'mwe-upwiz-api-error-missingresult' => 'Внутренняя ошибка. Не удалось определить завершилось ли копирование успешно.',
1007210290 'mwe-upwiz-api-error-missingparam' => 'Внутренняя ошибка. Отсутствуют параметры по запросу.',
10073 - 'mwe-upwiz-api-error-invalid-session-key' => 'Внутренняя ошибка. Не найден файл во временном хранилище.',
 10291+ 'mwe-upwiz-api-error-invalid-file-key' => 'Внутренняя ошибка. Не найден файл во временном хранилище.',
1007410292 'mwe-upwiz-api-error-copyuploaddisabled' => 'Загрузка по URL-адресу отключена на этом сервере.',
1007510293 'mwe-upwiz-api-error-mustbeloggedin' => 'Вы должны представиться системе для загрузки файлов.',
1007610294 'mwe-upwiz-api-error-empty-file' => 'Отправленный вами файл пуст.',
@@ -10336,7 +10554,7 @@
1033710555 'mwe-upwiz-api-error-stashfailed' => 'Ис алҕас: сиэрбэр быстах кэмҥэ оҥоһуллубут билэни кыайан бигэргэппэтэх.',
1033810556 'mwe-upwiz-api-error-missingresult' => 'Ис алҕас: Хатылааһын сатаммыта-сатамматаҕа биллибэтэ.',
1033910557 'mwe-upwiz-api-error-missingparam' => 'Ис алҕас: Көрдөбүл туруоруулара суохтар эбит.',
10340 - 'mwe-upwiz-api-error-invalid-session-key' => 'Ис алҕас: Быстах уурар сиргэ билэ көстүбэтэ.',
 10558+ 'mwe-upwiz-api-error-invalid-file-key' => 'Ис алҕас: Быстах уурар сиргэ билэ көстүбэтэ.',
1034110559 'mwe-upwiz-api-error-copyuploaddisabled' => 'URL көмөтүнэн киллэрии бу сиэрбэргэ араарыллыбыт.',
1034210560 'mwe-upwiz-api-error-mustbeloggedin' => 'Билэни киллэрэргэ бастаан ааккын этиэхтээххин.',
1034310561 'mwe-upwiz-api-error-empty-file' => 'Ыыппыт билэҥ кураанах.',
@@ -10508,7 +10726,7 @@
1050910727 'mwe-upwiz-api-error-stashfailed' => 'Vnútorná chyba: Serveru sa nepodarilo uložiť dočasný súbor.',
1051010728 'mwe-upwiz-api-error-missingresult' => 'Vnútorná chyba: Nepodarilo sa určiť, či kopírovanie prebehlo úspešne.',
1051110729 'mwe-upwiz-api-error-missingparam' => 'Vnútorná chyba: Chýbajú parametre požiadavky.',
10512 - 'mwe-upwiz-api-error-invalid-session-key' => 'Vnútorná chyba: Súbor sa nenašiel v dočasnom úložisku.',
 10730+ 'mwe-upwiz-api-error-invalid-file-key' => 'Vnútorná chyba: Súbor sa nenašiel v dočasnom úložisku.',
1051310731 'mwe-upwiz-api-error-copyuploaddisabled' => 'Nahrávanie z URL je na tomto serveri zakázané.',
1051410732 'mwe-upwiz-api-error-mustbeloggedin' => 'Aby ste mohli nahrávať súbory, musíte sa prihlásiť',
1051510733 'mwe-upwiz-api-error-empty-file' => 'Súbor, ktorý ste poslali bol prázdny.',
@@ -10615,7 +10833,7 @@
1061610834 'mwe-upwiz-api-error-stashfailed' => 'Notranja napaka: strežnik ni uspel shraniti začasne datoteke.',
1061710835 'mwe-upwiz-api-error-missingresult' => 'Notranja napaka: ni bilo mogoče določiti, če je kopiranje uspelo.',
1061810836 'mwe-upwiz-api-error-missingparam' => 'Notranja napaka: manjkajoči parametri ob zahtevi.',
10619 - 'mwe-upwiz-api-error-invalid-session-key' => 'Notranja napaka: datoteke ni bilo mogoče najti v začasni hrambi.',
 10837+ 'mwe-upwiz-api-error-invalid-file-key' => 'Notranja napaka: datoteke ni bilo mogoče najti v začasni hrambi.',
1062010838 'mwe-upwiz-api-error-copyuploaddisabled' => 'Nalaganje preko URL je na tem strežniku onemogočeno.',
1062110839 'mwe-upwiz-api-error-mustbeloggedin' => 'Za nalaganje datotek morate biti prijavljeni.',
1062210840 'mwe-upwiz-api-error-empty-file' => 'Poslana datoteka je prazna.',
@@ -10914,7 +11132,7 @@
1091511133 'mwe-upwiz-api-error-stashfailed' => 'Унутрашња грешка: сервер не може да сачува привремену датотеку.',
1091611134 'mwe-upwiz-api-error-missingresult' => 'Унутрашња грешка: не зна се да ли је умножавање успело.',
1091711135 'mwe-upwiz-api-error-missingparam' => 'Унутрашња грешка: недостају параметри у захтеву.',
10918 - 'mwe-upwiz-api-error-invalid-session-key' => 'Унутрашња грешка: датотека није пронађена у привременој остави.',
 11136+ 'mwe-upwiz-api-error-invalid-file-key' => 'Унутрашња грешка: датотека није пронађена у привременој остави.',
1091911137 'mwe-upwiz-api-error-copyuploaddisabled' => 'Отпремање путем адресе је онемогућено на овом серверу.',
1092011138 'mwe-upwiz-api-error-mustbeloggedin' => 'Морате бити пријављени да бисте отпремали датотеке.',
1092111139 'mwe-upwiz-api-error-empty-file' => 'Датотека коју сте послали је празна.',
@@ -11079,7 +11297,7 @@
1108011298 'mwe-upwiz-api-error-stashfailed' => 'Internt fel: servern kunde inte lagra temporär fil.',
1108111299 'mwe-upwiz-api-error-missingresult' => 'Internt fel: kunde inte avgöra om kopieringen lyckades.',
1108211300 'mwe-upwiz-api-error-missingparam' => 'Internt fel: saknas parametrar på begäran.',
11083 - 'mwe-upwiz-api-error-invalid-session-key' => 'Internt fel: filen hittades inte i tillfällig lagring.',
 11301+ 'mwe-upwiz-api-error-invalid-file-key' => 'Internt fel: filen hittades inte i tillfällig lagring.',
1108411302 'mwe-upwiz-api-error-copyuploaddisabled' => 'Uppladdning via URL är inaktiverad på den här servern.',
1108511303 'mwe-upwiz-api-error-mustbeloggedin' => 'Du måste vara inloggad för att ladda upp filer.',
1108611304 'mwe-upwiz-api-error-empty-file' => 'Filen du skickade var tom.',
@@ -11330,7 +11548,7 @@
1133111549 'mwe-upwiz-api-error-stashfailed' => 'உள்ளகப் பிழை: வழங்கி தற்காலிகக் கோப்பைத் தேக்கத் தவறிவிட்டது.',
1133211550 'mwe-upwiz-api-error-missingresult' => 'உள்ளகப் பிழை: நகல் வெற்றியடைந்ததா என்று தீர்மாணிக்க முடியவில்லை.',
1133311551 'mwe-upwiz-api-error-missingparam' => 'உள்ளகப் பிழை: கோரிக்கையில் அளபுருக்கள் விடுபடுகின்றன.',
11334 - 'mwe-upwiz-api-error-invalid-session-key' => 'உள்ளகப் பிழை: தற்காலிகச் சேமிப்பில் கோப்பு காணப்படவில்லை.',
 11552+ 'mwe-upwiz-api-error-invalid-file-key' => 'உள்ளகப் பிழை: தற்காலிகச் சேமிப்பில் கோப்பு காணப்படவில்லை.',
1133511553 'mwe-upwiz-api-error-copyuploaddisabled' => 'உரலி மூலம் பதிவேற்றுவது இந்த வழங்கியில் செயலிழக்கச் செய்யப்பட்டுள்ளது.',
1133611554 'mwe-upwiz-api-error-mustbeloggedin' => 'கோப்புகளைப் பதிவேற்ற நீங்கள் கண்டிப்பாகப் புகுபதிகை செய்திருக்க வேண்டும்.',
1133711555 'mwe-upwiz-api-error-empty-file' => 'நீங்கள் அளித்த கோப்பு காலியாக உள்ளது.',
@@ -11426,7 +11644,7 @@
1142711645 'mwe-upwiz-api-error-unknown-code' => 'తెలియని దోషము: $1',
1142811646 'mwe-upwiz-api-error-uploaddisabled' => 'ఈ వికీలో ఎక్కింపులని అచేతనం చేసారు.',
1142911647 'mwe-upwiz-api-error-nomodule' => 'అంతర్గత దోషము: ఎక్కింపు పర్వికము అమర్చబడలేదు.',
11430 - 'mwe-upwiz-api-error-invalid-session-key' => 'అంతర్గత దోషము: తాత్కాలిక నిల్వలో ఫైల్ కనపడలేదు.',
 11648+ 'mwe-upwiz-api-error-invalid-file-key' => 'అంతర్గత దోషము: తాత్కాలిక నిల్వలో ఫైల్ కనపడలేదు.',
1143111649 'mwe-upwiz-api-error-mustbeloggedin' => 'దస్త్రాలను ఎక్కించడానికి మీరు ప్రవేశించివుండాలి.',
1143211650 'mwe-upwiz-api-error-empty-file' => 'మీరు దాఖలుచేసిన ఫైల్ ఖాళీది.',
1143311651 'mwe-upwiz-api-error-filetype-banned' => 'ఈ రకపు దస్త్రాలని నిషేధించారు.',
@@ -11553,7 +11771,7 @@
1155411772 'mwe-upwiz-api-error-stashfailed' => 'Panloob na kamalian: nabigo ang tagapaghain na magtabi ng pansamantalang talaksan.',
1155511773 'mwe-upwiz-api-error-missingresult' => 'Panloob na kamalian: hindi matukoy kung nagtagumpay ang kopya.',
1155611774 'mwe-upwiz-api-error-missingparam' => 'Panloob na kamalian: nawawala ang mga parametro ng kahilingan.',
11557 - 'mwe-upwiz-api-error-invalid-session-key' => 'Panloob na kamalian: hindi matagpuan ang talaksan sa loob ng pansamantalang taguan.',
 11775+ 'mwe-upwiz-api-error-invalid-file-key' => 'Panloob na kamalian: hindi matagpuan ang talaksan sa loob ng pansamantalang taguan.',
1155811776 'mwe-upwiz-api-error-copyuploaddisabled' => 'Ang pagkakarga ng URL ay hindi pinagagana sa tagapaghaing ito.',
1155911777 'mwe-upwiz-api-error-mustbeloggedin' => 'Dapat na nakalagda ka upang makapagkarga ng mga talaksan.',
1156011778 'mwe-upwiz-api-error-empty-file' => 'Walang laman ang ipinasa mong talaksan.',
@@ -12033,7 +12251,7 @@
1203412252 'mwe-upwiz-api-error-stashfailed' => 'Lỗi nội bộ: Máy chủ bị thất bại trong việc lưu giữ tập tin tạm.',
1203512253 'mwe-upwiz-api-error-missingresult' => 'Lỗi nội bộ: Không rõ việc sao chép có thành công.',
1203612254 'mwe-upwiz-api-error-missingparam' => 'Lỗi nội bộ: Yêu cầu thiếu tham số.',
12037 - 'mwe-upwiz-api-error-invalid-session-key' => 'Lỗi nội bộ: Không tìm thấy tập tin trong kho tạm.',
 12255+ 'mwe-upwiz-api-error-invalid-file-key' => 'Lỗi nội bộ: Không tìm thấy tập tin trong kho tạm.',
1203812256 'mwe-upwiz-api-error-copyuploaddisabled' => 'Chức năng tải lên từ URL đã bị tắt trên máy chủ này.',
1203912257 'mwe-upwiz-api-error-mustbeloggedin' => 'Bạn phải đăng nhập để tải lên tập tin.',
1204012258 'mwe-upwiz-api-error-empty-file' => 'Bạn đã gửi tập tin rỗng.',
@@ -12280,7 +12498,7 @@
1228112499 'mwe-upwiz-api-error-stashfailed' => 'אינערלעכער גרײַז: סערווירער האט נישט געקענט אײַנשפייכלערן צייַטווייַליקע טעקע.',
1228212500 'mwe-upwiz-api-error-missingresult' => 'אינערלעכער גרײַז: נישט געקענט פֿעסטשטעלן צי קאפירן איז געווען דערפֿאלגרייך.',
1228312501 'mwe-upwiz-api-error-missingparam' => 'אינערלעכער גרײַז: פֿעלן פאראמעטערס אין פֿאַרלאַנג',
12284 - 'mwe-upwiz-api-error-invalid-session-key' => 'אינערלעכער גרײַז: נישט געטראפֿן טעקע אין צײַטווײַליקן שפייכלער',
 12502+ 'mwe-upwiz-api-error-invalid-file-key' => 'אינערלעכער גרײַז: נישט געטראפֿן טעקע אין צײַטווײַליקן שפייכלער',
1228512503 'mwe-upwiz-api-error-copyuploaddisabled' => 'אַרויפֿלאָדן דורך URL איז אומאַקטיווירט אויף דעם סערווירער.',
1228612504 'mwe-upwiz-api-error-mustbeloggedin' => 'איר דארפֿט זײַן אַרײַנלאגירט אַרויפֿצולאָדן טעקעס.',
1228712505 'mwe-upwiz-api-error-empty-file' => 'די טעקע וואָס איר האט אײַנגעגעבן איז ליידיג.',
@@ -12417,7 +12635,7 @@
1241812636 'mwe-upwiz-api-error-stashfailed' => '内部错误:服务器保存临时文件失败。',
1241912637 'mwe-upwiz-api-error-missingresult' => '内部错误:无法确定是否复制成功。',
1242012638 'mwe-upwiz-api-error-missingparam' => '内部错误:请求中缺少参数。',
12421 - 'mwe-upwiz-api-error-invalid-session-key' => '内部错误:找不到临时文件。',
 12639+ 'mwe-upwiz-api-error-invalid-file-key' => '内部错误:找不到临时文件。',
1242212640 'mwe-upwiz-api-error-copyuploaddisabled' => '通过URL上传的功能已被此服务器禁用。',
1242312641 'mwe-upwiz-api-error-mustbeloggedin' => '您必须登录后再上传文件。',
1242412642 'mwe-upwiz-api-error-empty-file' => '您提交的文件是空的。',
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/resources/mw.Api.js
@@ -179,7 +179,7 @@
180180 'stashfailed',
181181 'missingresult',
182182 'missingparam',
183 - 'invalid-session-key',
 183+ 'invalid-file-key',
184184 'copyuploaddisabled',
185185 'mustbeloggedin',
186186 'empty-file',
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/resources/mw.UploadWizard.js
@@ -21,7 +21,7 @@
2222 this.mimetype = undefined;
2323 this.extension = undefined;
2424
25 - this.sessionKey = undefined;
 25+ this.fileKey = undefined;
2626
2727 // this should be moved to the interface, if we even keep this
2828 this.transportWeight = 1; // default all same
@@ -355,8 +355,8 @@
356356 */
357357 extractUploadInfo: function( resultUpload ) {
358358
359 - if ( resultUpload.sessionkey ) {
360 - this.sessionKey = resultUpload.sessionkey;
 359+ if ( resultUpload.filekey ) {
 360+ this.fileKey = resultUpload.filekey;
361361 }
362362
363363 if ( resultUpload.imageinfo ) {
@@ -431,7 +431,7 @@
432432
433433 var params = {
434434 'prop': 'stashimageinfo',
435 - 'siisessionkey': _this.sessionKey,
 435+ 'siifilekey': _this.fileKey,
436436 'siiprop': props.join( '|' )
437437 };
438438
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/resources/mw.UploadWizardDetails.js
@@ -714,7 +714,7 @@
715715
716716 var params = {
717717 action: 'upload',
718 - sessionkey: _this.upload.sessionKey,
 718+ filekey: _this.upload.fileKey,
719719 filename: _this.upload.title.getMain(),
720720 text: wikiText,
721721 summary: "User created page with " + mw.UploadWizard.userAgent
Index: branches/wmf/1.17wmf1/extensions/UploadWizard/UploadWizard.php
@@ -12,7 +12,7 @@
1313 *
1414 * @author Neil Kandalgaonkar <neil@wikimedia.org>
1515 * @license GPL v2 or later
16 - * @version 0.1.1
 16+ * @version 1.1
1717 */
1818
1919 /* Configuration */
@@ -23,7 +23,7 @@
2424 'path' => __FILE__,
2525 'name' => 'Upload Wizard',
2626 'author' => 'Neil Kandalgaonkar',
27 - 'version' => '0.1.1',
 27+ 'version' => '1.1',
2828 'descriptionmsg' => 'uploadwizard-desc',
2929 'url' => 'http://www.mediawiki.org/wiki/Extension:UploadWizard'
3030 );
@@ -39,10 +39,8 @@
4040 foreach ( array( 'SpecialUploadWizard',
4141 'UploadWizardMessages',
4242 'UploadWizardHooks',
43 - 'UploadWizardTutorial',
44 - 'UploadWizardDependencyLoader'
45 - //, 'ApiTitleCheck'
46 - ) as $module ) {
 43+ 'UploadWizardTutorial'
 44+ ) as $module ) {
4745 $wgAutoloadLocalClasses[$module] = $wgUpwizDir . "/" . $module . ".php";
4846 }
4947
Index: branches/wmf/1.17wmf1/includes/upload/UploadFromStash.php
@@ -8,49 +8,74 @@
99 */
1010
1111 class UploadFromStash extends UploadBase {
12 - public static function isValidSessionKey( $key, $sessionData ) {
13 - return !empty( $key ) &&
14 - is_array( $sessionData ) &&
15 - isset( $sessionData[$key] ) &&
16 - isset( $sessionData[$key]['version'] ) &&
17 - $sessionData[$key]['version'] == self::SESSION_VERSION;
 12+ protected $mFileKey, $mVirtualTempPath, $mFileProps, $mSourceType;
 13+
 14+ // an instance of UploadStash
 15+ private $stash;
 16+
 17+ //LocalFile repo
 18+ private $repo;
 19+
 20+ public function __construct( $user = false, $stash = false, $repo = false ) {
 21+ // user object. sometimes this won't exist, as when running from cron.
 22+ $this->user = $user;
 23+
 24+ if( $repo ) {
 25+ $this->repo = $repo;
 26+ } else {
 27+ $this->repo = RepoGroup::singleton()->getLocalRepo();
 28+ }
 29+
 30+ if( $stash ) {
 31+ $this->stash = $stash;
 32+ } else {
 33+ wfDebug( __METHOD__ . " creating new UploadStash instance for " . $user->getId() . "\n" );
 34+ $this->stash = new UploadStash( $this->repo, $this->user );
 35+ }
 36+
 37+ return true;
1838 }
 39+
 40+ public static function isValidKey( $key ) {
 41+ // this is checked in more detail in UploadStash
 42+ return (bool)preg_match( UploadStash::KEY_FORMAT_REGEX, $key );
 43+ }
1944
2045 public static function isValidRequest( $request ) {
21 - $sessionData = $request->getSessionData( self::SESSION_KEYNAME );
22 - return self::isValidSessionKey(
23 - $request->getText( 'wpSessionKey' ),
24 - $sessionData
25 - );
 46+ // this passes wpSessionKey to getText() as a default when wpFileKey isn't set.
 47+ // wpSessionKey has no default which guarantees failure if both are missing
 48+ // (though that should have been caught earlier)
 49+ return self::isValidKey( $request->getText( 'wpFileKey', $request->getText( 'wpSessionKey' ) ) );
2650 }
2751
28 - public function initialize( $name, $sessionKey, $sessionData ) {
29 - /**
30 - * Confirming a temporarily stashed upload.
31 - * We don't want path names to be forged, so we keep
32 - * them in the session on the server and just give
33 - * an opaque key to the user agent.
34 - */
 52+ public function initialize( $key, $name = 'upload_file' ) {
 53+ /**
 54+ * Confirming a temporarily stashed upload.
 55+ * We don't want path names to be forged, so we keep
 56+ * them in the session on the server and just give
 57+ * an opaque key to the user agent.
 58+ */
 59+ $metadata = $this->stash->getMetadata( $key );
 60+ $this->initializePathInfo( $name,
 61+ $this->getRealPath ( $metadata['us_path'] ),
 62+ $metadata['us_size'],
 63+ false
 64+ );
3565
36 - $this->initializePathInfo( $name,
37 - $this->getRealPath ( $sessionData['mTempPath'] ),
38 - $sessionData['mFileSize'],
39 - false
40 - );
41 -
42 - $this->mSessionKey = $sessionKey;
43 - $this->mVirtualTempPath = $sessionData['mTempPath'];
44 - $this->mFileProps = $sessionData['mFileProps'];
 66+ $this->mFileKey = $key;
 67+ $this->mVirtualTempPath = $metadata['us_path'];
 68+ $this->mFileProps = $this->stash->getFileProps( $key );
 69+ $this->mSourceType = $metadata['us_source_type'];
4570 }
4671
4772 public function initializeFromRequest( &$request ) {
48 - $sessionKey = $request->getText( 'wpSessionKey' );
49 - $sessionData = $request->getSessionData( self::SESSION_KEYNAME );
 73+ // sends wpSessionKey as a default when wpFileKey is missing
 74+ $fileKey = $request->getText( 'wpFileKey', $request->getText( 'wpSessionKey' ) );
5075
51 - $desiredDestName = $request->getText( 'wpDestFile' );
52 - if( !$desiredDestName )
53 - $desiredDestName = $request->getText( 'wpUploadFile' );
54 - return $this->initialize( $desiredDestName, $sessionKey, $sessionData[$sessionKey] );
 76+ // chooses one of wpDestFile, wpUploadFile, filename in that order.
 77+ $desiredDestName = $request->getText( 'wpDestFile', $request->getText( 'wpUploadFile', $request->getText( 'filename' ) ) );
 78+
 79+ return $this->initialize( $fileKey, $desiredDestName );
5580 }
5681
5782 /**
@@ -64,20 +89,35 @@
6590 /**
6691 * There is no need to stash the image twice
6792 */
68 - public function stashSession( $key = null ) {
69 - if ( !empty( $this->mSessionKey ) )
70 - return $this->mSessionKey;
71 - return parent::stashSession();
 93+ public function stashFile() {
 94+ if ( $this->mLocalFile ) {
 95+ return $this->mLocalFile;
 96+ }
 97+ return parent::stashFile();
7298 }
7399
74100 /**
 101+ * Alias for stashFile
 102+ */
 103+ public function stashSession() {
 104+ return $this->stashFile();
 105+ }
 106+
 107+ /**
75108 * Remove a temporarily kept file stashed by saveTempUploadedFile().
76109 * @return success
77110 */
78111 public function unsaveUploadedFile() {
79 - $repo = RepoGroup::singleton()->getLocalRepo();
80 - $success = $repo->freeTemp( $this->mVirtualTempPath );
81 - return $success;
 112+ return $this->stash->removeFile( $this->mFileKey );
82113 }
83114
84 -}
\ No newline at end of file
 115+ /**
 116+ * Perform the upload, then remove the database record afterward.
 117+ */
 118+ public function performUpload( $comment, $pageText, $watch, $user ) {
 119+ $rv = parent::performUpload( $comment, $pageText, $watch, $user );
 120+ $this->unsaveUploadedFile();
 121+ return $rv;
 122+ }
 123+
 124+}
Index: branches/wmf/1.17wmf1/includes/upload/UploadBase.php
@@ -35,13 +35,6 @@
3636 const HOOK_ABORTED = 11;
3737 const FILE_TOO_LARGE = 12;
3838
39 - const SESSION_VERSION = 2;
40 - const SESSION_KEYNAME = 'wsUploadData';
41 -
42 - static public function getSessionKeyname() {
43 - return self::SESSION_KEYNAME;
44 - }
45 -
4639 public function getVerificationErrorCode( $error ) {
4740 $code_to_status = array(self::EMPTY_FILE => 'empty-file',
4841 self::FILE_TOO_LARGE => 'file-too-large',
@@ -521,7 +514,7 @@
522515 if ( $watch ) {
523516 $user->addWatch( $this->getLocalFile()->getTitle() );
524517 }
525 -
 518+
526519 wfRunHooks( 'UploadComplete', array( &$this ) );
527520 }
528521
@@ -630,33 +623,39 @@
631624 * by design) then we may want to stash the file temporarily, get more information, and publish the file later.
632625 *
633626 * This method will stash a file in a temporary directory for later processing, and save the necessary descriptive info
634 - * into the user's session.
635 - * This method returns the file object, which also has a 'sessionKey' property which can be passed through a form or
 627+ * into the database.
 628+ * This method returns the file object, which also has a 'fileKey' property which can be passed through a form or
636629 * API request to find this stashed file again.
637630 *
638 - * @param $key String: (optional) the session key used to find the file info again. If not supplied, a key will be autogenerated.
639631 * @return File: stashed file
640632 */
641 - public function stashSessionFile( $key = null ) {
642 - $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash();;
643 - $data = array(
644 - 'mFileProps' => $this->mFileProps
645 - );
646 - $file = $stash->stashFile( $this->mTempPath, $data, $key );
 633+ public function stashFile() {
 634+ // was stashSessionFile
 635+ $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash();
 636+
 637+ $file = $stash->stashFile( $this->mTempPath, $this->getSourceType() );
647638 $this->mLocalFile = $file;
648639 return $file;
649640 }
650641
651642 /**
652 - * Stash a file in a temporary directory, returning a key which can be used to find the file again. See stashSessionFile().
 643+ * Stash a file in a temporary directory, returning a key which can be used to find the file again. See stashFile().
653644 *
654 - * @param $key String: (optional) the session key used to find the file info again. If not supplied, a key will be autogenerated.
655 - * @return String: session key
 645+ * @return String: file key
656646 */
657 - public function stashSession( $key = null ) {
658 - return $this->stashSessionFile( $key )->getSessionKey();
 647+ public function stashFileGetKey() {
 648+ return $this->stashFile()->getFileKey();
659649 }
660650
 651+ /**
 652+ * alias for stashFileGetKey, for backwards compatibility
 653+ *
 654+ * @return String: file key
 655+ */
 656+ public function stashSession() {
 657+ return $this->stashFileGetKey();
 658+ }
 659+
661660 /**
662661 * If we've modified the upload file we need to manually remove it
663662 * on exit to clean up.
Property changes on: branches/wmf/1.17wmf1/includes/upload/UploadBase.php
___________________________________________________________________
Modified: svn:mergeinfo
664663 Merged /trunk/phase3/includes/upload/UploadBase.php:r91022,91679,92009,92030,92035,92039,92043,92081,92200,92213,92247,92250,92269,92459,92815,93065,93137,93476,93778,94536,94539-94540,94592,94594,94670
Index: branches/wmf/1.17wmf1/includes/upload/UploadStash.php
@@ -5,105 +5,173 @@
66 * - Several parts of MediaWiki do this in similar ways: UploadBase, UploadWizard, and FirefoggChunkedExtension
77 * And there are several that reimplement stashing from scratch, in idiosyncratic ways. The idea is to unify them all here.
88 * Mostly all of them are the same except for storing some custom fields, which we subsume into the data array.
9 - * - enable applications to find said files later, as long as the session or temp files haven't been purged.
 9+ * - enable applications to find said files later, as long as the db table or temp files haven't been purged.
1010 * - enable the uploading user (and *ONLY* the uploading user) to access said files, and thumbnails of said files, via a URL.
11 - * We accomplish this by making the session serve as a URL->file mapping, on the assumption that nobody else can access
12 - * the session, even the uploading user. See SpecialUploadStash, which implements a web interface to some files stored this way.
 11+ * We accomplish this using a database table, with ownership checking as you might expect. See SpecialUploadStash, which
 12+ * implements a web interface to some files stored this way.
1313 *
 14+ * UploadStash right now is *mostly* intended to show you one user's slice of the entire stash. The user parameter is only optional
 15+ * because there are few cases where we clean out the stash from an automated script. In the future we might refactor this.
 16+ *
 17+ * UploadStash represents the entire stash of temporary files.
 18+ * UploadStashFile is a filestore for the actual physical disk files.
 19+ * UploadFromStash extends UploadBase, and represents a single stashed file as it is moved from the stash to the regular file repository
1420 */
1521 class UploadStash {
1622
1723 // Format of the key for files -- has to be suitable as a filename itself (e.g. ab12cd34ef.jpg)
18 - const KEY_FORMAT_REGEX = '/^[\w-]+\.\w+$/';
 24+ const KEY_FORMAT_REGEX = '/^[\w-\.]+\.\w*$/';
1925
20 - // repository that this uses to store temp files
21 - // public because we sometimes need to get a LocalFile within the same repo.
22 - public $repo;
23 -
24 - // array of initialized objects obtained from session (lazily initialized upon getFile())
25 - private $files = array();
 26+ /**
 27+ * repository that this uses to store temp files
 28+ * public because we sometimes need to get a LocalFile within the same repo.
 29+ *
 30+ * @var LocalRepo
 31+ */
 32+ public $repo;
2633
27 - // TODO: Once UploadBase starts using this, switch to use these constants rather than UploadBase::SESSION*
28 - // const SESSION_VERSION = 2;
29 - // const SESSION_KEYNAME = 'wsUploadData';
 34+ // array of initialized repo objects
 35+ protected $files = array();
3036
 37+ // cache of the file metadata that's stored in the database
 38+ protected $fileMetadata = array();
 39+
 40+ // fileprops cache
 41+ protected $fileProps = array();
 42+
 43+ // current user
 44+ protected $user, $userId, $isLoggedIn;
 45+
3146 /**
32 - * Represents the session which contains temporarily stored files.
 47+ * Represents a temporary filestore, with metadata in the database.
3348 * Designed to be compatible with the session stashing code in UploadBase (should replace it eventually)
3449 */
35 - public function __construct() {
36 -
 50+ public function __construct( $repo, $user = null ) {
3751 // this might change based on wiki's configuration.
3852 $this->repo = RepoGroup::singleton()->getLocalRepo();
3953
40 - if ( ! isset( $_SESSION ) ) {
41 - throw new UploadStashNotAvailableException( 'no session variable' );
 54+ // if a user was passed, use it. otherwise, attempt to use the global.
 55+ // this keeps FileRepo from breaking when it creates an UploadStash object
 56+ if ( $user ) {
 57+ $this->user = $user;
 58+ } else {
 59+ global $wgUser;
 60+ $this->user = $wgUser;
4261 }
4362
44 - if ( !isset( $_SESSION[UploadBase::SESSION_KEYNAME] ) ) {
45 - $_SESSION[UploadBase::SESSION_KEYNAME] = array();
 63+ if ( is_object( $this->user ) ) {
 64+ $this->userId = $this->user->getId();
 65+ $this->isLoggedIn = $this->user->isLoggedIn();
4666 }
47 -
 67+
 68+ // Age of the repository in seconds. That is, after how long will files be assumed abandoned and deleted?
 69+ global $wgUploadStashMaxAge;
 70+ if( $wgUploadStashMaxAge === null ) {
 71+ $wgUploadStashMaxAge = 6 * 3600; // default: 6 hours.
 72+ }
4873 }
4974
5075
5176 /**
5277 * Get a file and its metadata from the stash.
53 - * May throw exception if session data cannot be parsed due to schema change, or key not found.
 78+ * The noAuth param is a bit janky but is required for automated scripts which clean out the stash.
5479 *
55 - * @param $key Integer: key
 80+ * @param $key String: key under which file information is stored
 81+ * @param $noAuth Boolean (optional) Don't check authentication. Used by maintenance scripts.
5682 * @throws UploadStashFileNotFoundException
57 - * @throws UploadStashBadVersionException
 83+ * @throws UploadStashNotLoggedInException
 84+ * @throws UploadStashWrongOwnerException
 85+ * @throws UploadStashBadPathException
5886 * @return UploadStashFile
5987 */
60 - public function getFile( $key ) {
 88+ public function getFile( $key, $noAuth = false ) {
 89+
6190 if ( ! preg_match( self::KEY_FORMAT_REGEX, $key ) ) {
6291 throw new UploadStashBadPathException( "key '$key' is not in a proper format" );
63 - }
64 -
65 - if ( !isset( $this->files[$key] ) ) {
66 - if ( !isset( $_SESSION[UploadBase::SESSION_KEYNAME][$key] ) ) {
 92+ }
 93+
 94+ if ( !$noAuth ) {
 95+ if ( !$this->isLoggedIn ) {
 96+ throw new UploadStashNotLoggedInException( __METHOD__ . ' No user is logged in, files must belong to users' );
 97+ }
 98+ }
 99+
 100+ $dbr = $this->repo->getSlaveDb();
 101+
 102+ if ( !isset( $this->fileMetadata[$key] ) ) {
 103+ if ( !$this->fetchFileMetadata( $key ) ) {
 104+ // If nothing was received, it's likely due to replication lag. Check the master to see if the record is there.
 105+ $this->fetchFileMetadata( $key, DB_MASTER );
 106+ }
 107+
 108+ if ( !isset( $this->fileMetadata[$key] ) ) {
67109 throw new UploadStashFileNotFoundException( "key '$key' not found in stash" );
68110 }
69111
70 - $data = $_SESSION[UploadBase::SESSION_KEYNAME][$key];
71 - // guards against PHP class changing while session data doesn't
72 - if ($data['version'] !== UploadBase::SESSION_VERSION ) {
73 - throw new UploadStashBadVersionException( $data['version'] . " does not match current version " . UploadBase::SESSION_VERSION );
 112+ // create $this->files[$key]
 113+ $this->initFile( $key );
 114+
 115+ // fetch fileprops
 116+ $path = $this->fileMetadata[$key]['us_path'];
 117+ if ( $this->repo->isVirtualUrl( $path ) ) {
 118+ $path = $this->repo->resolveVirtualUrl( $path );
74119 }
75 -
76 - // separate the stashData into the path, and then the rest of the data
77 - $path = $data['mTempPath'];
78 - unset( $data['mTempPath'] );
 120+ $this->fileProps[$key] = File::getPropsFromPath( $path );
 121+ }
79122
80 - $file = new UploadStashFile( $this, $this->repo, $path, $key, $data );
81 - if ( $file->getSize() === 0 ) {
82 - throw new UploadStashZeroLengthFileException( "File is zero length" );
 123+ if ( ! $this->files[$key]->exists() ) {
 124+ wfDebug( __METHOD__ . " tried to get file at $key, but it doesn't exist\n" );
 125+ throw new UploadStashBadPathException( "path doesn't exist" );
 126+ }
 127+
 128+ if ( !$noAuth ) {
 129+ if ( $this->fileMetadata[$key]['us_user'] != $this->userId ) {
 130+ throw new UploadStashWrongOwnerException( "This file ($key) doesn't belong to the current user." );
83131 }
84 - $this->files[$key] = $file;
 132+ }
85133
86 - }
87134 return $this->files[$key];
88135 }
89136
90137 /**
91 - * Stash a file in a temp directory and record that we did this in the session, along with other metadata.
92 - * We store data in a flat key-val namespace because that's how UploadBase did it. This also means we have to
93 - * ensure that the key-val pairs in $data do not overwrite other required fields.
 138+ * Getter for file metadata.
94139 *
 140+ * @param key String: key under which file information is stored
 141+ * @return Array
 142+ */
 143+ public function getMetadata ( $key ) {
 144+ $this->getFile( $key );
 145+ return $this->fileMetadata[$key];
 146+ }
 147+
 148+ /**
 149+ * Getter for fileProps
 150+ *
 151+ * @param key String: key under which file information is stored
 152+ * @return Array
 153+ */
 154+ public function getFileProps ( $key ) {
 155+ $this->getFile( $key );
 156+ return $this->fileProps[$key];
 157+ }
 158+
 159+ /**
 160+ * Stash a file in a temp directory and record that we did this in the database, along with other metadata.
 161+ *
95162 * @param $path String: path to file you want stashed
96 - * @param $data Array: optional, other data you want associated with the file. Do not use 'mTempPath', 'mFileProps', 'mFileSize', or 'version' as keys here
97 - * @param $key String: optional, unique key for this file in this session. Used for directory hashing when storing, otherwise not important
 163+ * @param $sourceType String: the type of upload that generated this file (currently, I believe, 'file' or null)
98164 * @throws UploadStashBadPathException
99165 * @throws UploadStashFileException
 166+ * @throws UploadStashNotLoggedInException
100167 * @return UploadStashFile: file, or null on failure
101168 */
102 - public function stashFile( $path, $data = array(), $key = null ) {
 169+ public function stashFile( $path, $sourceType = null ) {
103170 if ( ! file_exists( $path ) ) {
104 - wfDebug( "UploadStash: tried to stash file at '$path', but it doesn't exist\n" );
 171+ wfDebug( __METHOD__ . " tried to stash file at '$path', but it doesn't exist\n" );
105172 throw new UploadStashBadPathException( "path doesn't exist" );
106173 }
107174 $fileProps = File::getPropsFromPath( $path );
 175+ wfDebug( __METHOD__ . " stashing file at '$path'\n" );
108176
109177 // we will be initializing from some tmpnam files that don't have extensions.
110178 // most of MediaWiki assumes all uploaded files have good extensions. So, we fix this.
@@ -116,82 +184,237 @@
117185 $path = $pathWithGoodExtension;
118186 }
119187
120 - // If no key was supplied, use content hash. Also has the nice property of collapsing multiple identical files
121 - // uploaded this session, which could happen if uploads had failed.
122 - if ( is_null( $key ) ) {
123 - $key = $fileProps['sha1'] . "." . $extension;
124 - }
 188+ // If no key was supplied, make one. a mysql insertid would be totally reasonable here, except
 189+ // that for historical reasons, the key is this random thing instead. At least it's not guessable.
 190+ //
 191+ // some things that when combined will make a suitably unique key.
 192+ // see: http://www.jwz.org/doc/mid.html
 193+ list ($usec, $sec) = explode( ' ', microtime() );
 194+ $usec = substr($usec, 2);
 195+ $key = wfBaseConvert( $sec . $usec, 10, 36 ) . '.' .
 196+ wfBaseConvert( mt_rand(), 10, 36 ) . '.'.
 197+ $this->userId . '.' .
 198+ $extension;
125199
 200+ $this->fileProps[$key] = $fileProps;
 201+
126202 if ( ! preg_match( self::KEY_FORMAT_REGEX, $key ) ) {
127203 throw new UploadStashBadPathException( "key '$key' is not in a proper format" );
128204 }
129205
 206+ wfDebug( __METHOD__ . " key for '$path': $key\n" );
130207
 208+
131209 // if not already in a temporary area, put it there
132 - $status = $this->repo->storeTemp( basename( $path ), $path );
 210+ $storeStatus = $this->repo->storeTemp( basename( $path ), $path );
133211
134 - if( ! $status->isOK() ) {
 212+ if ( ! $storeStatus->isOK() ) {
135213 // It is a convention in MediaWiki to only return one error per API exception, even if multiple errors
136214 // are available. We use reset() to pick the "first" thing that was wrong, preferring errors to warnings.
137 - // This is a bit lame, as we may have more info in the $status and we're throwing it away, but to fix it means
 215+ // This is a bit lame, as we may have more info in the $storeStatus and we're throwing it away, but to fix it means
138216 // redesigning API errors significantly.
139 - // $status->value just contains the virtual URL (if anything) which is probably useless to the caller
140 - $error = reset( $status->getErrorsArray() );
 217+ // $storeStatus->value just contains the virtual URL (if anything) which is probably useless to the caller
 218+ $error = $storeStatus->getErrorsArray();
 219+ $error = reset( $error );
141220 if ( ! count( $error ) ) {
142 - $error = reset( $status->getWarningsArray() );
 221+ $error = $storeStatus->getWarningsArray();
 222+ $error = reset( $error );
143223 if ( ! count( $error ) ) {
144224 $error = array( 'unknown', 'no error recorded' );
145225 }
146226 }
147227 throw new UploadStashFileException( "error storing file in '$path': " . implode( '; ', $error ) );
148228 }
149 - $stashPath = $status->value;
 229+ $stashPath = $storeStatus->value;
150230
151 - // required info we always store. Must trump any other application info in $data
152 - // 'mTempPath', 'mFileSize', and 'mFileProps' are arbitrary names
153 - // chosen for compatibility with UploadBase's way of doing this.
154 - $requiredData = array(
155 - 'mTempPath' => $stashPath,
156 - 'mFileSize' => $fileProps['size'],
157 - 'mFileProps' => $fileProps,
158 - 'version' => UploadBase::SESSION_VERSION
 231+ // fetch the current user ID
 232+ if ( !$this->isLoggedIn ) {
 233+ throw new UploadStashNotLoggedInException( __METHOD__ . ' No user is logged in, files must belong to users' );
 234+ }
 235+
 236+ // insert the file metadata into the db.
 237+ wfDebug( __METHOD__ . " inserting $stashPath under $key\n" );
 238+ $dbw = $this->repo->getMasterDb();
 239+
 240+ // select happens on the master so this can all be in a transaction, which
 241+ // avoids a race condition that's likely with multiple people uploading from the same
 242+ // set of files
 243+ $dbw->begin();
 244+ // first, check to see if it's already there.
 245+ $row = $dbw->selectRow(
 246+ 'uploadstash',
 247+ 'us_user, us_timestamp',
 248+ array( 'us_key' => $key ),
 249+ __METHOD__
159250 );
160251
161 - // now, merge required info and extra data into the session. (The extra data changes from application to application.
162 - // UploadWizard wants different things than say FirefoggChunkedUpload.)
163 - wfDebug( __METHOD__ . " storing under $key\n" );
164 - $_SESSION[UploadBase::SESSION_KEYNAME][$key] = array_merge( $data, $requiredData );
 252+ // The current user can't have this key if:
 253+ // - the key is owned by someone else and
 254+ // - the age of the key is less than $wgUploadStashMaxAge
 255+ if ( is_object( $row ) ) {
 256+ if ( $row->us_user != $this->userId &&
 257+ $row->wfTimestamp( TS_UNIX, $row->us_timestamp ) > time() - $wgUploadStashMaxAge
 258+ ) {
 259+ $dbw->rollback();
 260+ throw new UploadStashWrongOwnerException( "Attempting to upload a duplicate of a file that someone else has stashed" );
 261+ }
 262+ }
 263+
 264+ $this->fileMetadata[$key] = array(
 265+ 'us_user' => $this->userId,
 266+ 'us_key' => $key,
 267+ 'us_orig_path' => $path,
 268+ 'us_path' => $stashPath,
 269+ 'us_size' => $fileProps['size'],
 270+ 'us_sha1' => $fileProps['sha1'],
 271+ 'us_mime' => $fileProps['mime'],
 272+ 'us_media_type' => $fileProps['media_type'],
 273+ 'us_image_width' => $fileProps['width'],
 274+ 'us_image_height' => $fileProps['height'],
 275+ 'us_image_bits' => $fileProps['bits'],
 276+ 'us_source_type' => $sourceType,
 277+ 'us_timestamp' => $dbw->timestamp(),
 278+ 'us_status' => 'finished'
 279+ );
 280+
 281+ $dbw->insert(
 282+ 'uploadstash',
 283+ $this->fileMetadata[$key],
 284+ __METHOD__
 285+ );
 286+
 287+ // store the insertid in the class variable so immediate retrieval (possibly laggy) isn't necesary.
 288+ $this->fileMetadata[$key]['us_id'] = $dbw->insertId();
165289
 290+ # create the UploadStashFile object for this file.
 291+ $this->initFile( $key );
 292+
166293 return $this->getFile( $key );
167294 }
168295
169296 /**
170297 * Remove all files from the stash.
171298 * Does not clean up files in the repo, just the record of them.
 299+ *
 300+ * @throws UploadStashNotLoggedInException
172301 * @return boolean: success
173302 */
174303 public function clear() {
175 - $_SESSION[UploadBase::SESSION_KEYNAME] = array();
 304+ if ( !$this->isLoggedIn ) {
 305+ throw new UploadStashNotLoggedInException( __METHOD__ . ' No user is logged in, files must belong to users' );
 306+ }
 307+
 308+ wfDebug( __METHOD__ . " clearing all rows for user $userId\n" );
 309+ $dbw = $this->repo->getMasterDb();
 310+ $dbw->delete(
 311+ 'uploadstash',
 312+ array( 'us_user' => $this->userId ),
 313+ __METHOD__
 314+ );
 315+
 316+ # destroy objects.
 317+ $this->files = array();
 318+ $this->fileMetadata = array();
 319+
176320 return true;
177321 }
178322
 323+ /**
 324+ * Remove a particular file from the stash. Also removes it from the repo.
 325+ *
 326+ * @throws UploadStashNotLoggedInException
 327+ * @throws UploadStashWrongOwnerException
 328+ * @return boolean: success
 329+ */
 330+ public function removeFile( $key ) {
 331+ if ( !$this->isLoggedIn ) {
 332+ throw new UploadStashNotLoggedInException( __METHOD__ . ' No user is logged in, files must belong to users' );
 333+ }
179334
 335+ $dbw = $this->repo->getMasterDb();
 336+
 337+ // this is a cheap query. it runs on the master so that this function still works when there's lag.
 338+ // it won't be called all that often.
 339+ $row = $dbw->selectRow(
 340+ 'uploadstash',
 341+ 'us_user',
 342+ array( 'us_key' => $key ),
 343+ __METHOD__
 344+ );
 345+
 346+ if( !$row ) {
 347+ throw new UploadStashNoSuchKeyException( "No such key ($key), cannot remove" );
 348+ }
 349+
 350+ if ( $row->us_user != $this->userId ) {
 351+ throw new UploadStashWrongOwnerException( "Can't delete: the file ($key) doesn't belong to this user." );
 352+ }
 353+
 354+ return $this->removeFileNoAuth( $key );
 355+ }
 356+
 357+
180358 /**
181 - * Remove a particular file from the stash.
182 - * Does not clean up file in the repo, just the record of it.
 359+ * Remove a file (see removeFile), but doesn't check ownership first.
 360+ *
183361 * @return boolean: success
184362 */
185 - public function removeFile( $key ) {
186 - unset ( $_SESSION[UploadBase::SESSION_KEYNAME][$key] );
 363+ public function removeFileNoAuth( $key ) {
 364+ wfDebug( __METHOD__ . " clearing row $key\n" );
 365+
 366+ $dbw = $this->repo->getMasterDb();
 367+
 368+ // this gets its own transaction since it's called serially by the cleanupUploadStash maintenance script
 369+ $dbw->begin();
 370+ $dbw->delete(
 371+ 'uploadstash',
 372+ array( 'us_key' => $key ),
 373+ __METHOD__
 374+ );
 375+ $dbw->commit();
 376+
 377+ // TODO: look into UnregisteredLocalFile and find out why the rv here is sometimes wrong (false when file was removed)
 378+ // for now, ignore.
 379+ $this->files[$key]->remove();
 380+
 381+ unset( $this->files[$key] );
 382+ unset( $this->fileMetadata[$key] );
 383+
187384 return true;
188385 }
189386
190387
191388 /**
192389 * List all files in the stash.
 390+ *
 391+ * @throws UploadStashNotLoggedInException
 392+ * @return Array
193393 */
194394 public function listFiles() {
195 - return array_keys( $_SESSION[UploadBase::SESSION_KEYNAME] );
 395+ if ( !$this->isLoggedIn ) {
 396+ throw new UploadStashNotLoggedInException( __METHOD__ . ' No user is logged in, files must belong to users' );
 397+ }
 398+
 399+ $dbr = $this->repo->getSlaveDb();
 400+ $res = $dbr->select(
 401+ 'uploadstash',
 402+ 'us_key',
 403+ array( 'us_user' => $this->userId ),
 404+ __METHOD__
 405+ );
 406+
 407+ if ( !is_object( $res ) || $res->numRows() == 0 ) {
 408+ // nothing to do.
 409+ return false;
 410+ }
 411+
 412+ // finish the read before starting writes.
 413+ $keys = array();
 414+ foreach ( $res as $row ) {
 415+ array_push( $keys, $row->us_key );
 416+ }
 417+
 418+ return $keys;
196419 }
197420
198421
@@ -225,48 +448,92 @@
226449 return File::normalizeExtension( $extension );
227450 }
228451
 452+ /**
 453+ * Helper function: do the actual database query to fetch file metadata.
 454+ *
 455+ * @param $key String: key
 456+ * @return boolean
 457+ */
 458+ protected function fetchFileMetadata( $key, $readFromDB = DB_SLAVE ) {
 459+ // populate $fileMetadata[$key]
 460+ $dbr = null;
 461+ if( $readFromDB === DB_MASTER ) {
 462+ // sometimes reading from the master is necessary, if there's replication lag.
 463+ $dbr = $this->repo->getMasterDb();
 464+ } else {
 465+ $dbr = $this->repo->getSlaveDb();
 466+ }
 467+
 468+ $row = $dbr->selectRow(
 469+ 'uploadstash',
 470+ '*',
 471+ array( 'us_key' => $key ),
 472+ __METHOD__
 473+ );
 474+
 475+ if ( !is_object( $row ) ) {
 476+ // key wasn't present in the database. this will happen sometimes.
 477+ return false;
 478+ }
 479+
 480+ $this->fileMetadata[$key] = (array)$row;
 481+
 482+ return true;
 483+ }
 484+
 485+ /**
 486+ * Helper function: Initialize the UploadStashFile for a given file.
 487+ *
 488+ * @param $path String: path to file
 489+ * @param $key String: key under which to store the object
 490+ * @throws UploadStashZeroLengthFileException
 491+ * @return bool
 492+ */
 493+ protected function initFile( $key ) {
 494+ $file = new UploadStashFile( $this->repo, $this->fileMetadata[$key]['us_path'], $key );
 495+ if ( $file->getSize() === 0 ) {
 496+ throw new UploadStashZeroLengthFileException( "File is zero length" );
 497+ }
 498+ $this->files[$key] = $file;
 499+ return true;
 500+ }
229501 }
230502
231503 class UploadStashFile extends UnregisteredLocalFile {
232 - private $sessionStash;
233 - private $sessionKey;
234 - private $sessionData;
 504+ private $fileKey;
235505 private $urlName;
236506
237507 /**
238508 * A LocalFile wrapper around a file that has been temporarily stashed, so we can do things like create thumbnails for it
239509 * Arguably UnregisteredLocalFile should be handling its own file repo but that class is a bit retarded currently
240510 *
241 - * @param $stash UploadStash: useful for obtaining config, stashing transformed files
242511 * @param $repo FileRepo: repository where we should find the path
243512 * @param $path String: path to file
244513 * @param $key String: key to store the path and any stashed data under
245 - * @param $data String: any other data we want stored with this file
246514 * @throws UploadStashBadPathException
247515 * @throws UploadStashFileNotFoundException
248516 */
249 - public function __construct( $stash, $repo, $path, $key, $data ) {
250 - $this->sessionStash = $stash;
251 - $this->sessionKey = $key;
252 - $this->sessionData = $data;
 517+ public function __construct( $repo, $path, $key ) {
 518+ $this->fileKey = $key;
253519
254520 // resolve mwrepo:// urls
255521 if ( $repo->isVirtualUrl( $path ) ) {
256522 $path = $repo->resolveVirtualUrl( $path );
257 - }
 523+ } else {
258524
259 - // check if path appears to be sane, no parent traversals, and is in this repo's temp zone.
260 - $repoTempPath = $repo->getZonePath( 'temp' );
261 - if ( ( ! $repo->validateFilename( $path ) ) ||
262 - ( strpos( $path, $repoTempPath ) !== 0 ) ) {
263 - wfDebug( "UploadStash: tried to construct an UploadStashFile from a file that should already exist at '$path', but path is not valid\n" );
264 - throw new UploadStashBadPathException( 'path is not valid' );
265 - }
 525+ // check if path appears to be sane, no parent traversals, and is in this repo's temp zone.
 526+ $repoTempPath = $repo->getZonePath( 'temp' );
 527+ if ( ( ! $repo->validateFilename( $path ) ) ||
 528+ ( strpos( $path, $repoTempPath ) !== 0 ) ) {
 529+ wfDebug( "UploadStash: tried to construct an UploadStashFile from a file that should already exist at '$path', but path is not valid\n" );
 530+ throw new UploadStashBadPathException( 'path is not valid' );
 531+ }
266532
267 - // check if path exists! and is a plain file.
268 - if ( ! $repo->fileExists( $path, FileRepo::FILES_ONLY ) ) {
269 - wfDebug( "UploadStash: tried to construct an UploadStashFile from a file that should already exist at '$path', but path is not found\n" );
270 - throw new UploadStashFileNotFoundException( 'cannot find path, or not a plain file' );
 533+ // check if path exists! and is a plain file.
 534+ if ( ! $repo->fileExists( $path, FileRepo::FILES_ONLY ) ) {
 535+ wfDebug( "UploadStash: tried to construct an UploadStashFile from a file that should already exist at '$path', but path is not found\n" );
 536+ throw new UploadStashFileNotFoundException( 'cannot find path, or not a plain file' );
 537+ }
271538 }
272539
273540
@@ -351,7 +618,7 @@
352619 * Get a URL to access the thumbnail
353620 * This is required because the model of how files work requires that
354621 * the thumbnail urls be predictable. However, in our model the URL is not based on the filename
355 - * (that's hidden in the session)
 622+ * (that's hidden in the db)
356623 *
357624 * @param $thumbName String: basename of thumbnail file -- however, we don't want to use the file exactly
358625 * @return String: URL to access thumbnail, or URL with partial path
@@ -369,7 +636,7 @@
370637 */
371638 public function getUrlName() {
372639 if ( ! $this->urlName ) {
373 - $this->urlName = $this->sessionKey;
 640+ $this->urlName = $this->fileKey;
374641 }
375642 return $this->urlName;
376643 }
@@ -399,12 +666,12 @@
400667
401668
402669 /**
403 - * Getter for session key (the session-unique id by which this file's location & metadata is stored in the session)
 670+ * Getter for file key (the unique id by which this file's location & metadata is stored in the db)
404671 *
405 - * @return String: session key
 672+ * @return String: file key
406673 */
407 - public function getSessionKey() {
408 - return $this->sessionKey;
 674+ public function getFileKey() {
 675+ return $this->fileKey;
409676 }
410677
411678 /**
@@ -412,15 +679,25 @@
413680 * @return Status: success
414681 */
415682 public function remove() {
 683+ if ( !$this->repo->fileExists( $this->path, FileRepo::FILES_ONLY ) ) {
 684+ // Maybe the file's already been removed? This could totally happen in UploadBase.
 685+ return true;
 686+ }
 687+
416688 return $this->repo->freeTemp( $this->path );
417689 }
418690
 691+ public function exists() {
 692+ return $this->repo->fileExists( $this->path, FileRepo::FILES_ONLY );
 693+ }
 694+
419695 }
420696
421697 class UploadStashNotAvailableException extends MWException {};
422698 class UploadStashFileNotFoundException extends MWException {};
423699 class UploadStashBadPathException extends MWException {};
424 -class UploadStashBadVersionException extends MWException {};
425700 class UploadStashFileException extends MWException {};
426701 class UploadStashZeroLengthFileException extends MWException {};
427 -
 702+class UploadStashNotLoggedInException extends MWException {};
 703+class UploadStashWrongOwnerException extends MWException {};
 704+class UploadStashNoSuchKeyException extends MWException {};
Property changes on: branches/wmf/1.17wmf1/includes/upload/UploadStash.php
___________________________________________________________________
Modified: svn:mergeinfo
428705 Merged /trunk/phase3/includes/upload/UploadStash.php:r91022,91679,92009,92030,92035,92039,92043,92081,92200,92213,92247,92250,92269,92459,92815,93065,93137,93476,93778,94536,94539-94540,94592,94594,94670
Index: branches/wmf/1.17wmf1/includes/upload/UploadFromFile.php
@@ -32,6 +32,13 @@
3333 # because a post_max_size or upload_max_filesize overflow
3434 return true;
3535 }
 36+
 37+ /**
 38+ * @return string
 39+ */
 40+ public function getSourceType() {
 41+ return 'file';
 42+ }
3643
3744 public function verifyUpload() {
3845 # Check for a post_max_size or upload_max_size overflow, so that a
Property changes on: branches/wmf/1.17wmf1/includes/upload/UploadFromFile.php
___________________________________________________________________
Modified: svn:mergeinfo
3946 Merged /trunk/phase3/includes/upload/UploadFromFile.php:r93476,93778,94536,94539-94540,94592,94594,94670
Index: branches/wmf/1.17wmf1/includes/installer/MysqlUpdater.php
@@ -174,6 +174,7 @@
175175 array( 'dropIndex', 'archive', 'ar_page_revid', 'patch-archive_kill_ar_page_revid.sql' ),
176176 array( 'addIndex', 'archive', 'ar_revid', 'patch-archive_ar_revid.sql' ),
177177 array( 'doLangLinksLengthUpdate' ),
 178+ array( 'addTable', 'uploadstash', 'patch-uploadstash.sql' ),
178179 );
179180 }
180181
Property changes on: branches/wmf/1.17wmf1/includes/installer/MysqlUpdater.php
___________________________________________________________________
Modified: svn:mergeinfo
181182 Merged /trunk/phase3/includes/installer/MysqlUpdater.php:r91022,91679,92009,92030,92035,92039,92043,92081,92200,92213,92247,92250,92269,92459,92815,93065,93137,93476,93778,94536,94539-94540,94592,94594,94670
Index: branches/wmf/1.17wmf1/includes/installer/SqliteUpdater.php
@@ -51,6 +51,7 @@
5252 array( 'doCollationUpdate' ),
5353 array( 'addTable', 'msg_resource', 'patch-msg_resource.sql' ),
5454 array( 'addTable', 'module_deps', 'patch-module_deps.sql' ),
 55+ array( 'addTable', 'uploadstash', 'patch-uploadstash.sql' ),
5556 );
5657 }
5758
Index: branches/wmf/1.17wmf1/includes/api/ApiQueryStashImageInfo.php
@@ -41,16 +41,25 @@
4242
4343 $result = $this->getResult();
4444
 45+ if ( !$params['filekey'] && !$params['sessionkey'] ) {
 46+ $this->dieUsage( "One of filekey or sessionkey must be supplied", 'nofilekey');
 47+ }
 48+
 49+ // Alias sessionkey to filekey, but give an existing filekey precedence.
 50+ if ( !$params['filekey'] && $params['sessionkey'] ) {
 51+ $params['filekey'] = $params['sessionkey'];
 52+ }
 53+
4554 try {
4655 $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash();
47 -
48 - foreach ( $params['sessionkey'] as $sessionkey ) {
49 - $file = $stash->getFile( $sessionkey );
 56+
 57+ foreach ( $params['filekey'] as $filekey ) {
 58+ $file = $stash->getFile( $filekey );
5059 $imageInfo = self::getInfo( $file, $prop, $result, $scale );
5160 $result->addValue( array( 'query', $this->getModuleName() ), null, $imageInfo );
5261 $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), $modulePrefix );
5362 }
54 -
 63+ //TODO: update exception handling here to understand current getFile exceptions
5564 } catch ( UploadStashNotAvailableException $e ) {
5665 $this->dieUsage( "Session not available: " . $e->getMessage(), "nosession" );
5766 } catch ( UploadStashFileNotFoundException $e ) {
@@ -81,11 +90,15 @@
8291
8392 public function getAllowedParams() {
8493 return array(
85 - 'sessionkey' => array(
 94+ 'filekey' => array(
8695 ApiBase::PARAM_ISMULTI => true,
87 - ApiBase::PARAM_REQUIRED => true,
8896 ApiBase::PARAM_DFLT => null
8997 ),
 98+ 'sessionkey' => array(
 99+ ApiBase::PARAM_ISMULTI => true,
 100+ ApiBase::PARAM_DEPRECATED => true,
 101+ ApiBase::PARAM_DFLT => null
 102+ ),
90103 'prop' => array(
91104 ApiBase::PARAM_ISMULTI => true,
92105 ApiBase::PARAM_DFLT => 'timestamp|url',
@@ -121,7 +134,8 @@
122135 ' metadata - Lists EXIF metadata for the version of the image',
123136 ' bitdepth - Adds the bit depth of the version',
124137 ),
125 - 'sessionkey' => 'Session key that identifies a previous upload that was stashed temporarily.',
 138+ 'filekey' => 'Key that identifies a previous upload that was stashed temporarily.',
 139+ 'sessionkey' => 'Alias for filekey, for backward compatibility.',
126140 'urlwidth' => "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.",
127141 'urlheight' => "Similar to {$p}urlwidth. Cannot be used without {$p}urlwidth"
128142 );
@@ -139,8 +153,8 @@
140154
141155 protected function getExamples() {
142156 return array(
143 - 'api.php?action=query&prop=stashimageinfo&siisessionkey=124sd34rsdf567',
144 - 'api.php?action=query&prop=stashimageinfo&siisessionkey=b34edoe3|bceffd4&siiurlwidth=120&siiprop=url',
 157+ 'api.php?action=query&prop=stashimageinfo&siifilekey=124sd34rsdf567',
 158+ 'api.php?action=query&prop=stashimageinfo&siifilekey=b34edoe3|bceffd4&siiurlwidth=120&siiprop=url',
145159 );
146160 }
147161
Index: branches/wmf/1.17wmf1/includes/api/ApiUpload.php
@@ -53,6 +53,11 @@
5454 $request = $this->getMain()->getRequest();
5555 // Add the uploaded file to the params array
5656 $this->mParams['file'] = $request->getFileName( 'file' );
 57+
 58+ // Copy the session key to the file key, for backward compatibility.
 59+ if( !$this->mParams['filekey'] && $this->mParams['sessionkey'] ) {
 60+ $this->mParams['filekey'] = $this->mParams['sessionkey'];
 61+ }
5762
5863 // Select an upload module
5964 if ( !$this->selectUploadModule() ) {
@@ -98,7 +103,8 @@
99104 // in case the warnings can be fixed with some further user action, let's stash this upload
100105 // and return a key they can use to restart it
101106 try {
102 - $result['sessionkey'] = $this->performStash();
 107+ $result['filekey'] = $this->performStash();
 108+ $result['sessionkey'] = $result['filekey']; // backwards compatibility
103109 } catch ( MWException $e ) {
104110 $result['warnings']['stashfailed'] = $e->getMessage();
105111 }
@@ -107,7 +113,8 @@
108114 // In this case, a failure to stash ought to be fatal
109115 try {
110116 $result['result'] = 'Success';
111 - $result['sessionkey'] = $this->performStash();
 117+ $result['filekey'] = $this->performStash();
 118+ $result['sessionkey'] = $result['filekey']; // backwards compatibility
112119 } catch ( MWException $e ) {
113120 $this->dieUsage( $e->getMessage(), 'stashfailed' );
114121 }
@@ -128,21 +135,22 @@
129136 }
130137
131138 /**
132 - * Stash the file and return the session key
 139+ * Stash the file and return the file key
133140 * Also re-raises exceptions with slightly more informative message strings (useful for API)
134141 * @throws MWException
135 - * @return {String} session key
 142+ * @return String file key
136143 */
137144 function performStash() {
138145 try {
139 - $sessionKey = $this->mUpload->stashSessionFile()->getSessionKey();
 146+ $fileKey = $this->mUpload->stashFile()->getFileKey();
140147 } catch ( MWException $e ) {
141 - throw new MWException( 'Stashing temporary file failed: ' . get_class($e) . ' ' . $e->getMessage() );
 148+ $message = 'Stashing temporary file failed: ' . get_class( $e ) . ' ' . $e->getMessage();
 149+ wfDebug( __METHOD__ . ' ' . $message . "\n");
 150+ throw new MWException( $message );
142151 }
143 - return $sessionKey;
 152+ return $fileKey;
144153 }
145154
146 -
147155 /**
148156 * Select an upload module and set it to mUpload. Dies on failure. If the
149157 * request was a status request and not a true upload, returns false;
@@ -156,7 +164,7 @@
157165
158166 // One and only one of the following parameters is needed
159167 $this->requireOnlyOneParameter( $this->mParams,
160 - 'sessionkey', 'file', 'url', 'statuskey' );
 168+ 'filekey', 'file', 'url', 'statuskey' );
161169
162170 if ( $wgAllowAsyncCopyUploads && $this->mParams['statuskey'] ) {
163171 // Status request for an async upload
@@ -180,17 +188,25 @@
181189 }
182190
183191
184 - if ( $this->mParams['sessionkey'] ) {
 192+ if ( $this->mParams['filekey'] ) {
185193 // Upload stashed in a previous request
186 - $sessionData = $request->getSessionData( UploadBase::getSessionKeyName() );
187 - if ( !UploadFromStash::isValidSessionKey( $this->mParams['sessionkey'], $sessionData ) ) {
188 - $this->dieUsageMsg( array( 'invalid-session-key' ) );
 194+ if ( !UploadFromStash::isValidKey( $this->mParams['filekey'] ) ) {
 195+ $this->dieUsageMsg( 'invalid-file-key' );
189196 }
190197
191 - $this->mUpload = new UploadFromStash();
192 - $this->mUpload->initialize( $this->mParams['filename'],
193 - $this->mParams['sessionkey'],
194 - $sessionData[$this->mParams['sessionkey']] );
 198+ if( class_exists( 'RequestContext' ) ) {
 199+ // context allows access to the current user without creating new $wgUser references
 200+ $context = $this->createContext();
 201+ $this->mUpload = new UploadFromStash( $context->getUser() );
 202+ } else {
 203+ // this is here to maintain 1.17 compatibility, so these changes can
 204+ // be merged into production
 205+ // remove this after we've moved to 1.18
 206+ global $wgUser;
 207+ $this->mUpload = new UploadFromStash( $wgUser );
 208+ }
 209+
 210+ $this->mUpload->initialize( $this->mParams['filekey'], $this->mParams['filename'] );
195211
196212
197213 } elseif ( isset( $this->mParams['file'] ) ) {
@@ -417,7 +433,11 @@
418434 'ignorewarnings' => false,
419435 'file' => null,
420436 'url' => null,
421 - 'sessionkey' => null,
 437+ 'filekey' => null,
 438+ 'sessionkey' => array(
 439+ ApiBase::PARAM_DFLT => null,
 440+ ApiBase::PARAM_DEPRECATED => true,
 441+ ),
422442 'stash' => false,
423443 );
424444
@@ -443,7 +463,8 @@
444464 'ignorewarnings' => 'Ignore any warnings',
445465 'file' => 'File contents',
446466 'url' => 'Url to fetch the file from',
447 - 'sessionkey' => 'Session key that identifies a previous upload that was stashed temporarily.',
 467+ 'filekey' => 'Key that identifies a previous upload that was stashed temporarily.',
 468+ 'sessionkey' => 'Same as filekey, maintained for backward compatibility.',
448469 'stash' => 'If set, the server will not add the file to the repository and stash it temporarily.'
449470 );
450471
@@ -465,32 +486,31 @@
466487 'Upload a file, or get the status of pending uploads. Several methods are available:',
467488 ' * Upload file contents directly, using the "file" parameter',
468489 ' * Have the MediaWiki server fetch a file from a URL, using the "url" parameter',
469 - ' * Complete an earlier upload that failed due to warnings, using the "sessionkey" parameter',
 490+ ' * Complete an earlier upload that failed due to warnings, using the "filekey" parameter',
470491 'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
471 - 'sending the "file". Note also that queries using session keys must be',
472 - 'done in the same login session as the query that originally returned the key (i.e. do not',
473 - 'log out and then log back in). Also you must get and send an edit token before doing any upload stuff'
 492+ 'sending the "file". Also you must get and send an edit token before doing any upload stuff'
474493 );
475494 }
476495
477496 public function getPossibleErrors() {
478 - return array_merge( parent::getPossibleErrors(), array(
479 - array( 'uploaddisabled' ),
480 - array( 'invalid-session-key' ),
481 - array( 'uploaddisabled' ),
482 - array( 'badaccess-groups' ),
483 - array( 'mustbeloggedin', 'upload' ),
484 - array( 'badaccess-groups' ),
485 - array( 'badaccess-groups' ),
486 - array( 'code' => 'fetchfileerror', 'info' => '' ),
487 - array( 'code' => 'nomodule', 'info' => 'No upload module set' ),
488 - array( 'code' => 'empty-file', 'info' => 'The file you submitted was empty' ),
489 - array( 'code' => 'filetype-missing', 'info' => 'The file is missing an extension' ),
490 - array( 'code' => 'filename-tooshort', 'info' => 'The filename is too short' ),
491 - array( 'code' => 'overwrite', 'info' => 'Overwriting an existing file is not allowed' ),
492 - array( 'code' => 'stashfailed', 'info' => 'Stashing temporary file failed' ),
493 - array( 'code' => 'internal-error', 'info' => 'An internal error occurred' ),
494 - ) );
 497+ return array_merge( parent::getPossibleErrors(),
 498+ $this->getRequireOnlyOneParameterErrorMessages( array( 'filekey', 'file', 'url', 'statuskey' ) ),
 499+ array(
 500+ array( 'uploaddisabled' ),
 501+ array( 'invalid-file-key' ),
 502+ array( 'uploaddisabled' ),
 503+ array( 'mustbeloggedin', 'upload' ),
 504+ array( 'badaccess-groups' ),
 505+ array( 'code' => 'fetchfileerror', 'info' => '' ),
 506+ array( 'code' => 'nomodule', 'info' => 'No upload module set' ),
 507+ array( 'code' => 'empty-file', 'info' => 'The file you submitted was empty' ),
 508+ array( 'code' => 'filetype-missing', 'info' => 'The file is missing an extension' ),
 509+ array( 'code' => 'filename-tooshort', 'info' => 'The filename is too short' ),
 510+ array( 'code' => 'overwrite', 'info' => 'Overwriting an existing file is not allowed' ),
 511+ array( 'code' => 'stashfailed', 'info' => 'Stashing temporary file failed' ),
 512+ array( 'code' => 'internal-error', 'info' => 'An internal error occurred' )
 513+ )
 514+ );
495515 }
496516
497517 public function needsToken() {
@@ -506,7 +526,7 @@
507527 'Upload from a URL:',
508528 ' api.php?action=upload&filename=Wiki.png&url=http%3A//upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png',
509529 'Complete an upload that failed due to warnings:',
510 - ' api.php?action=upload&filename=Wiki.png&sessionkey=sessionkey&ignorewarnings=1',
 530+ ' api.php?action=upload&filename=Wiki.png&filekey=filekey&ignorewarnings=1',
511531 );
512532 }
513533
Property changes on: branches/wmf/1.17wmf1/includes/api/ApiUpload.php
___________________________________________________________________
Modified: svn:mergeinfo
514534 Merged /trunk/phase3/includes/api/ApiUpload.php:r91022,91679,92009,92030,92035,92039,92043,92081,92200,92213,92247,92250,92269,92459,92815,93065,93137,93476,93778,94536,94539-94540,94592,94594,94670
Index: branches/wmf/1.17wmf1/includes/job/UploadFromUrlJob.php
@@ -54,24 +54,24 @@
5555 if ( !$this->params['ignoreWarnings'] ) {
5656 $warnings = $this->upload->checkWarnings();
5757 if ( $warnings ) {
58 - wfSetupSession( $this->params['sessionId'] );
5958
 59+ # Stash the upload
 60+ $key = $this->upload->stashFile();
 61+
6062 if ( $this->params['leaveMessage'] ) {
6163 $this->user->leaveUserMessage(
6264 wfMsg( 'upload-warning-subj' ),
6365 wfMsg( 'upload-warning-msg',
64 - $this->params['sessionKey'],
 66+ $key,
6567 $this->params['url'] )
6668 );
6769 } else {
 70+ wfSetupSession( $this->params['sessionId'] );
6871 $this->storeResultInSession( 'Warning',
6972 'warnings', $warnings );
 73+ session_write_close();
7074 }
7175
72 - # Stash the upload in the session
73 - $this->upload->stashSession( $this->params['sessionKey'] );
74 - session_write_close();
75 -
7676 return true;
7777 }
7878 }
Index: branches/wmf/1.17wmf1/includes/DefaultSettings.php
@@ -207,6 +207,11 @@
208208 $wgUploadPath = false;
209209
210210 /**
 211+ * The maximum age of temporary (incomplete) uploaded files
 212+ */
 213+$wgUploadStashMaxAge = 6 * 3600; // 6 hours
 214+
 215+/**
211216 * The filesystem path of the images directory. Defaults to "{$IP}/images".
212217 */
213218 $wgUploadDirectory = false;
Property changes on: branches/wmf/1.17wmf1/includes/DefaultSettings.php
___________________________________________________________________
Modified: svn:mergeinfo
214219 Merged /trunk/phase3/includes/DefaultSettings.php:r93476,93778,94536,94539-94540,94592,94594,94670

Follow-up revisions

RevisionCommit summaryAuthorDate
r98153Bug 31169 - Paraminfo for upload module is brokenreedy18:22, 26 September 2011

Status & tagging log