Bug 20489 Configure illegal file characters https://bugzilla.wikimedia.org/show_bug...
[mediawiki.git] / js2 / mwEmbed / libAddMedia / mvBaseUploadInterface.js
bloba800bd2b4b308310a9cdbb4a3fff01374dd392d8
1 /**
2  * the base Upload Interface for uploading.
3  *
4  * this base uploader is optionally extended by Firefogg
5  *
6  * @@todo: checkme: gM 'thumbnail-more' is used; only defined in MediaWiki core. Will that work properly?
7  */
8 loadGM({
9         "mwe-upload-transcode-in-progress" : "Transcode and upload in progress (do not close this window)",
10         "mwe-upload-in-progress" : "Upload in progress (do not close this window)",
11         "mwe-upload-transcoded-status" : "Transcoded",
12         "mwe-uploaded-status" : "Uploaded",
13         "mwe-upload-stats-fileprogres" : "$1 of $2",
14         "mwe-upload_completed" : "Your upload is complete",
15         "mwe-upload_done" : "<a href=\"$1\">Your upload <i>should be<\/i> accessible<\/a>.",
16         "mwe-upload-unknown-size" : "Unknown size",
17         "mwe-cancel-confim" : "Are you sure you want to cancel?",
18         "mwe-successfulupload" : "Upload successful",
19         "mwe-uploaderror" : "Upload error",
20         "mwe-uploadwarning" : "Upload warning",
21         "mwe-unknown-error" : "Unknown error:",
22         "mwe-return-to-form" : "Return to form",
23         "mwe-file-exists-duplicate" : "This file is a duplicate of the following file:",
24         "mwe-fileexists" : "A file with this name exists already. Please check <b><tt>$1<\/tt><\/b> if you are not sure if you want to change it.",
25         "mwe-fileexists-thumb" : "<center><b>Existing file<\/b><\/center>",
26         "mwe-ignorewarning" : "Ignore warning and save file anyway",
27         "mwe-file-thumbnail-no" : "The filename begins with <b><tt>$1<\/tt><\/b>",
28         "mwe-go-to-resource" : "Go to resource page",
29         "mwe-upload-misc-error" : "Unknown upload error",
30         "mwe-wgfogg_warning_bad_extension" : "You have selected a file with an unsuported extension (<a href=\"http:\/\/commons.wikimedia.org\/wiki\/Commons:Firefogg#Supported_File_Types\">more information<\/a>).",
31         "mwe-cancel-button" : "Cancel",
32         "mwe-ok-button" : "OK"
33 });
35 var default_bui_options = {
36         'api_url':null,
37         'parent_uploader':null,
38         'edit_from':null,
39         'done_upload_cb': null,
40         'target_edit_from':null,
42         //default upload mode is 'api' but if no api_url will try tp post
43         'upload_mode': 'api'
46 var mvBaseUploadInterface = function( iObj ){
47         return this.init( iObj );
49 mvBaseUploadInterface.prototype = {
50         parent_uploader:false,
51         formData:{}, //the form to be submitted
52         warnings_sessionkey:null,
53         chunks_supported:false,
54         form_post_override:false,
55         action_done:false,
56         //the edit token:
57         etoken:false,
58         init: function( iObj ){
59                 if(!iObj)
60                         iObj = {};
61                 //inherit iObj properties:
62                 for(var i in default_bui_options){
63                         if(iObj[i]){
64                                 this[i] = iObj[i];
65                         }else{
66                                 this[i] = default_bui_options[i];
67                         }
68                 }
69         },
70         setupForm:function(){
71                 var _this = this;
72                 //set up the local pointer to the edit form:
73                 _this.editForm = _this.getEditForm();
74                 if( _this.editForm ){
75                                         
76                         //if in api re-map the upload form to api: (we have to do this BEFORE the users selects a file) 
77                         if(_this.upload_mode == 'api'){
78                                 _this.doRemapFormToApi();
79                         }
80                         
81                         //set up the org_onsubmit if not set:
82                         if( typeof( _this.org_onsubmit ) == 'undefined' &&  _this.editForm.onsubmit )
83                                 _this.org_onsubmit = _this.editForm.onsubmit;
85                         //set up the submit action:
86                         $j( _this.editForm ).submit( function(){
87                                 js_log('setupForm.onSubmit:');
88                                 //run the original onsubmit (if not run yet set flag to avoid excessive chaining )
89                                 if( typeof( _this.org_onsubmit ) == 'function' ){
90                                         if( ! _this.org_onsubmit() ){
91                                                 //error in org submit return false;
92                                                 return false;
93                                         }
94                                 }
95                                 //check for post action override:
96                                 if( _this.form_post_override ){
97                                         js_log('form_post_override is true do form proccessing:');
98                                         return true;
99                                 }
100                                 //get the input form data in flat json:
101                                 js_log('update formData::');
102                                 var tmpAryData = $j( _this.editForm ).serializeArray();
103                                 for(var i=0; i < tmpAryData.length; i++){
104                                         if( tmpAryData[i]['name'] )
105                                                 _this.formData[ tmpAryData[i]['name'] ] = tmpAryData[i]['value'];
106                                 }
107                                 //put into a try catch so we are sure to return false:
108                                 try{
109                                         //get a clean loader:
110                                         _this.dispProgressOverlay();
112                                         //for some unknown reason we have to drop down the #p-search z-index:
113                                         $j('#p-search').css('z-index', 1);
115                                         //select upload mode:                                   
116                                         _this.detectUploadMode();
117                                 }catch(e){
118                                         js_log('::error in dispProgressOverlay or detectUploadMode');
119                                 }
121                                 //don't submit the form we will do the post in ajax
122                                 return false;
123                         });
124                 }
126         },
127         detectUploadMode:function( callback ){
128                 var _this = this;
129                 js_log('detectUploadMode::' +  _this.upload_mode);
130                 //check the upload mode:
131                 if( _this.upload_mode == 'autodetect' ){
132                         js_log('detectUploadMode::' + _this.upload_mode + ' api:' + _this.api_url);
133                         if( ! _this.api_url )
134                                 return js_error( 'Error: can\'t autodetect mode without api url' );
135                         do_api_req( {
136                                 'data': { 'action' : 'paraminfo', 'modules' : 'upload' },
137                                 'url' : _this.api_url
138                         }, function(data){
139                                 if( typeof data.paraminfo == 'undefined' || typeof data.paraminfo.modules == 'undefined' )
140                                         return js_error( 'Error: bad api results' );
141                                 if( typeof data.paraminfo.modules[0].classname == 'undefined'){
142                                         js_log( 'Autodetect Upload Mode: \'post\' ');
143                                         _this.upload_mode = 'post';
144                                 }else{
145                                         js_log( 'Autodetect Upload Mode: api ' );
146                                         _this.upload_mode = 'api';
147                                         //check to see if chunks are supported:
148                                         for( var i in data.paraminfo.modules[0].parameters ){
149                                                 var pname = data.paraminfo.modules[0].parameters[i].name;
150                                                 if( pname == 'enablechunks' ){
151                                                         js_log( 'this.chunks_supported = true' );
152                                                         _this.chunks_supported = true;
153                                                         break;
154                                                 }
155                                         }
156                                 }
157                                 js_log("do call: doUploadSwitch");
158                                 _this.doUploadSwitch();
159                         });
160                 }else{
161                         _this.doUploadSwitch();
162                 }
163         },
164         //@@NOTE this could probably be depricated to just have a special:upload page that uses api keys? 
165         // or maybe its usefull to seperate js and non-js submits
166         doRemapFormToApi:function(){
167                 var _this = this;
168                 if( !_this.api_url )
169                         return false;
170                         
171                 //add the action api 
172                 $j(_this.editForm).attr('action', _this.api_url);
173                 
174                 //add api url 
175                 //add api action:
176                 if( $j(_this.editForm).find("[name='action']").length == 0)
177                         $j(_this.editForm).append('<input type="hidden" name="action" value="upload">');
179                 //add json format
180                 if( $j(_this.editForm).find("[name='format']").length == 0)
181                         $j(_this.editForm).append('<input type="hidden" name="format" value="jsonfm">');
183                 //map a new hidden form
184                 $j(_this.editForm).find("[name='wpUploadFile']").attr('name', 'file');
185                 $j(_this.editForm).find("[name='wpDestFile']").attr('name', 'filename');
186                 $j(_this.editForm).find("[name='wpUploadDescription']").attr('name', 'comment');
187                 $j(_this.editForm).find("[name='wpEditToken']").attr('name', 'token');
188                 $j(_this.editForm).find("[name='wpIgnoreWarning']").attr('name', 'ignorewarnings');
189                 $j(_this.editForm).find("[name='wpWatchthis']").attr('name', 'watch');
191                 //update the status to 100% progress bar (no status in iframe submit)
192                 $j('#up-progressbar' ).progressbar( 'value', parseInt( 100 ) );
193                 $j('#up-status-container').html( gM('mwe-upload-in-progress') );                
194         },
195         doUploadSwitch:function(){
196                 var _this = this;
197                 js_log('mvUPload:doUploadSwitch():' + _this.upload_mode);
198                 //issue a normal post request
199                 if( _this.upload_mode == 'post' ) {
200                         //we don't support the upload api
201                         //trick the browser into thinking the wpUpload button was pressed (there might be a cleaner way to do this)
202                         $j(_this.editForm).append(
203                                 '<input type="hidden" name="wpUpload" value="' + $j('input[name=\'wpUpload\']').val() + '"/>'
204                         );
205                         //do normal post
206                         _this.form_post_override = true;
207                         js_log('doUploadSwitch:: submit call');
208                         //do the submit :
209                         _this.editForm.submit();
210                 }else if(
211                         _this.upload_mode == 'api' &&
212                         ( $j('#wpSourceTypeFile').length ==  0 || $j('#wpSourceTypeFile').get(0).checked )
213                 ){
214                         //@@TODO check for sendAsBinnary to support firefox 3.5 progress
216                         //set the form target to iframe target: 
217                         _this.iframeId = 'f_' + ($j('iframe').length + 1);                                      
218                         //add the iframe
219                         $j("body").append('<iframe src="javascript:false;" id="' + _this.iframeId + '" ' +
220                                 'name="' + _this.iframeId + '" style="display:none;" ></iframe>');      
221                         $j(_this.editForm).attr('target', _this.iframeId);
223                         //set up the done binding
224                         $j('#' + _this.iframeId).load(function(){
225                                 _this.proccessIframeResult(  $j(this).get(0) );
226                         });
227                         //set the action to the api url:
228                         $j(_this.editForm).attr('action', _this.api_url );
229                         
230                         js_log('do iframe form submit to: ' +  $j(_this.editForm).attr('target') 
231                                         + ' destName:' + $j(_this.editForm).find("[name='filename']").val() );                                  
232                         
233                         
234                         //do post override
235                         _this.form_post_override = true;
236                         //reset the done with action flag:
237                         _this.action_done = false;
238                         
239                         /*js_log('run editForm submit()');
240                         var tmpAryData = $j(_this.editForm).serializeArray();
241                         for(var i=0; i < tmpAryData.length; i++){
242                                 if( tmpAryData[i]['name'] )
243                                         js_log('name: ' + tmpAryData[i]['name'] + ' = ' + tmpAryData[i]['value']);
244                         }*/
245                         $j(_this.editForm).submit();
247                         return false;
248                 }else if( _this.upload_mode == 'api' && $j('#wpSourceTypeURL').get(0).checked){
249                         js_log('doHttpUpload (no form submit) ');
250                         //if the api is supported.. && source type is http do upload with http status updates
251                         var httpUpConf ={
252                             'url'               : $j('#wpUploadFileURL').val(),
253                             'filename'  : $j('#wpDestFile').val(),
254                             'comment'   : $j('#wpUploadDescription').val(),
255                                 'watch'         : ($j('#wpWatchthis').is(':checked'))?'true':'false'
256                         }
257                         //set up ignore warnings and watch arguments:
258                         if( $j('#wpIgnoreWarning').is(':checked') ){
259                                 httpUpConf[ 'ignorewarnings'] =  'true';
260                         }
261                         if( $j('#wpWatchthis').is(':checked') ){
262                                 httpUpConf[ 'watch'] =  'true';
263                         }
264                         //check for editToken
265                         _this.etoken = $j("#wpEditToken").val();
266                         _this.doHttpUpload( httpUpConf );
267                 }else{
268                         js_error( 'Error: unrecongized upload mode: ' + _this.upload_mode );
269                 }
270                 return false;
271         },
272         proccessIframeResult:function(iframe){
273                 var _this = this;
274                 var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;
275                 // fixing Opera 9.26
276                 if (doc.readyState && doc.readyState != 'complete'){
277                         return;
278                 }
279                 // fixing Opera 9.64
280                 if (doc.body && doc.body.innerHTML == "false"){
281                         return;
282                 }
283                 var response;
284                 if (doc.XMLDocument){
285                         // response is a xml document IE property
286                         response = doc.XMLDocument;
287                 } else if (doc.body){
288                         // get the json str:
289                         json_str = $j(doc.body).find('pre').html();
290                         js_log('iframe:json::' + json_str + "\nbody:" + $j(doc.body).html() );
291                         //htmlentties
292                         if (json_str) {
293                                 response = window["eval"]("(" +json_str + ")");
294                         } else {
295                                 response = {};
296                         }
297                 } else {
298                         // response is a xml document
299                         var response = doc;
300                 }
301                 //do proccess the api result
302                 _this.processApiResult( response );
303         },
304         doHttpUpload:function( opt ){
305                 var _this = this;
306                 //set the http box to loading (in case we don't get an update for some time)
307                 $j('#dlbox-centered').html( '<h5>' + _this.getProgressTitle() + '</h5>' +
308                         mv_get_loading_img( 'left:40%;top:20%')
309                 );
310                 //setup request:
311                 var req = {
312                         'action'                : 'upload',
313                         'asyncdownload' : true  //do a s
314                 };
315                 //set config from options:
316                 for(var i in opt){
317                         req[i]= opt[i];
318                 }
320                 //else try and get a token:
321                 if(!_this.etoken  && _this.api_url){
322                         js_log('Error:doHttpUpload: missing token');
323                 }else{
324                         req['token'] =_this.etoken;
325                 }
326                 //reset the done with action flag:
327                 _this.action_done = false;
328                 //do the api req
329                 do_api_req({
330                         'data': req,
331                         'url' : _this.api_url
332                 }, function( data ){
333                         _this.processApiResult( data );
334                 });
335         },
336         doAjaxWarningIgnore:function(){
337                 var _this = this;
338                 if( !_this.upload_session_key )
339                         return js_error('missing upload_session_key (can\'t ignore warnigns');
340                 //do the ignore warnings submit to the api:
341                 var req = {
342                                 'ignorewarnings' : 'true',
343                                 'sessionkey'     :!_this.upload_session_key
344                         };
345                 //add token if present:
346                 if(this.etoken)
347                         req['token'] = this.etoken;
349                 do_api_req({
350                         'data':req,
351                         'url': _this.api_url
352                 },function(data){
353                         _this.processApiResult(data);
354                 });
355         },
356         doAjaxUploadStatus:function() {
357                 var _this = this;       
358                 
359                 //set up the progress display for status updates:
360                 _this.dispProgressOverlay();
361                 var req = {
362                         'action'         : 'upload',
363                         'httpstatus' : 'true',
364                         'sessionkey' : _this.upload_session_key
365                 };
366                 //add token if present:
367                 if(this.etoken)
368                         req['token'] = this.etoken;
370                 var uploadStatus = function(){
371                         //do the api request:
372                         do_api_req({
373                                 'data':req,
374                                 'url' : _this.api_url
375                         }, function( data ){
376                                 //@@check if we are done
377                                 if( data.upload['apiUploadResult'] ){
378                                         //update status to 100%
379                                         _this.updateProgress( 1 );
380                                         if(typeof JSON == 'undefined'){
381                                                 //we need to load the jQuery json parser: (older browsers don't have JSON.parse
382                                                 mvJsLoader.doLoad([
383                                                         '$j.secureEvalJSON'
384                                                 ],function(){
385                                                         var  apiResult = $j.secureEvalJSON( data.upload['apiUploadResult'] );
386                                                         _this.processApiResult( apiResult );
387                                                 });
388                                         }else{
389                                                 var apiResult = {};
390                                                 try{
391                                                         apiResult = JSON.parse ( data.upload['apiUploadResult'] ) ;
392                                                 }catch (e){
393                                                         //could not parse api result
394                                                         js_log('errro: could not parse apiUploadResult ')
395                                                 }
396                                                 _this.processApiResult( apiResult );
397                                         }
398                                         return ;
399                                 }
401                                 //@@ else update status:
402                                 if( data.upload['content_length'] &&  data.upload['loaded'] ){
403                                         //we have content length we can show percentage done:
404                                         var perc =  data.upload['loaded'] / data.upload['content_length'];
405                                         //update the status:
406                                         _this.updateProgress( perc );
407                                         //special case update the file progress where we have data size:
408                                         $j('#up-status-container').html(
409                                                 gM('mwe-upload-stats-fileprogres', [
410                                                         formatSize( data.upload['loaded'] ),
411                                                         formatSize( data.upload['content_length'] )
412                                                         ]
413                                                 )
414                                         );
415                                 }else if( data.upload['loaded'] ){
416                                         _this.updateProgress( 1 );
417                                         js_log('just have loaded (no cotent length: ' + data.upload['loaded']);
418                                         //for lack of content-length requests:
419                                         $j('#up-status-container').html(
420                                                 gM('mwe-upload-stats-fileprogres', [
421                                                         formatSize( data.upload['loaded'] ),
422                                                         gM('mwe-upload-unknown-size')
423                                                         ]
424                                                 )
425                                         );
426                                 }
427                                 //(we got a result) set it to 100ms + your server update interval (in our case 2s)
428                                 setTimeout(uploadStatus, 2100);
429                         });
430                 }
431                 uploadStatus();
432         },
433         apiUpdateErrorCheck:function( apiRes ){
434                 var _this = this;
435                 if( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ){
436                         //gennerate the error button:
437                         var bObj = {};
438                         bObj[ gM('mwe-return-to-form') ] = function(){
439                                         _this.form_post_override = false;
440                                         $j(this).dialog('close');
441                          };
443                         //@@TODO should be refactored to more specialUpload page type error handling
445                         //check a few places for the error code:
446                         var error_code=0;
447                         var errorReplaceArg='';
448                         if( apiRes.error && apiRes.error.code ){
449                                 error_code = apiRes.error.code;
450                         }else if( apiRes.upload.code ){
451                                 if(typeof apiRes.upload.code == 'object'){
452                                         if(apiRes.upload.code[0]){
453                                                 error_code = apiRes.upload.code[0];
454                                         }
455                                         if(apiRes.upload.code['status']){
456                                                 error_code = apiRes.upload.code['status'];
457                                                 if(apiRes.upload.code['filtered'])
458                                                         errorReplaceArg =apiRes.upload.code['filtered'];
459                                         }
460                                 }else{
461                                         apiRes.upload.code;
462                                 }
463                         }
465                         var error_msg = '';
466                         if(typeof apiRes.error == 'string')
467                                 error_msg = apiRes.error;
468                         //error space is too large so we don't front load it
469                         //this upload error space replicates code in: SpecialUpload.php::processUpload()
470                         //would be nice if we refactored that to the upload api.(problem is some need special actions)
471                         var error_msg_key = {
472                                 '2' : 'largefileserver',
473                                 '3' : 'emptyfile',
474                                 '4' : 'minlength1',
475                                 '5' : 'illegalfilename'
476                         };
478                         //@@todo: need to write conditionals that mirror SpecialUpload for handling these error types:
479                         var error_onlykey = {
480                                 '1': 'BEFORE_PROCESSING',
481                                 '6': 'PROTECTED_PAGE',
482                                 '7': 'OVERWRITE_EXISTING_FILE',
483                                 '8': 'FILETYPE_MISSING',
484                                 '9': 'FILETYPE_BADTYPE',
485                                 '10': 'VERIFICATION_ERROR',
486                                 '11': 'UPLOAD_VERIFICATION_ERROR',
487                                 '12': 'UPLOAD_WARNING',
488                                 '13': 'INTERNAL_ERROR',
489                                 '14': 'MIN_LENGHT_PARTNAME'
490                         }
492                         //do a remote call to get the error msg:
493                         if(!error_code || error_code == 'unknown-error'){
494                                 if(typeof JSON != 'undefined'){
495                                         js_log('Error: apiRes: ' + JSON.stringify( apiRes) );
496                                 }
497                                 if( apiRes.upload.error == 'internal-error'){
498                                         errorKey = apiRes.upload.details[0];
499                                         gMsgLoadRemote(errorKey, function(){
500                                                 _this.updateProgressWin( gM( 'mwe-uploaderror' ), gM( errorKey ), bObj );
502                                         });
503                                         return false;
504                                 }
506                                 _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + '<br>' + error_msg, bObj );
507                                 return false;
508                         }else{
509                                 if(apiRes.error && apiRes.error.info ){
510                                         _this.updateProgressWin(  gM('mwe-uploaderror'), apiRes.error.info ,bObj);
511                                         return false;
512                                 }else{
513                                         if(typeof error_code == 'number' && typeof error_msg_key[error_code] == 'undefined' ){
514                                                 if(apiRes.upload.code.finalExt){
515                                                         _this.updateProgressWin(  gM('mwe-uploaderror'), gM('mwe-wgfogg_warning_bad_extension', apiRes.upload.code.finalExt) , bObj);
516                                                 }else{
517                                                         _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + ' : ' + error_code, bObj);
518                                                 }
519                                         }else{
520                                                 js_log('get key: ' + error_msg_key[ error_code ])
521                                                 gMsgLoadRemote( error_msg_key[ error_code ], function(){
522                                                         _this.updateProgressWin(  gM('mwe-uploaderror'), gM(  error_msg_key[ error_code ], errorReplaceArg ), bObj);
523                                                 });
524                                                 js_log("api.error");
525                                         }
526                                         return false;
527                                 }
528                         }
529                 }
530                 //check for upload.error type erros.
531                 if( apiRes.upload && apiRes.upload.error){
532                         js_log(' apiRes.upload.error: ' +  apiRes.upload.error );
533                         _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + '<br>', bObj);
534                         return false;
535                 }
536                 //check for known warnings:
537                 if(apiRes.upload && apiRes.upload.warnings ){
538                         //debugger;
539                         var wmsg = '<ul>';
540                         for(var wtype in apiRes.upload.warnings){
541                                 var winfo = apiRes.upload.warnings[wtype]
542                                 wmsg+='<li>';
543                                 switch(wtype){
544                                         case 'duplicate':
545                                         case 'exists':
546                                                 if(winfo[1] && winfo[1].title && winfo[1].title.mTextform){
547                                                         wmsg += gM('mwe-file-exists-duplicate') +' '+
548                                                                         '<b>' + winfo[1].title.mTextform + '</b>';
549                                                 }else{
550                                                         //misc error (weird that winfo[1] not present
551                                                         wmsg += gM('mwe-upload-misc-error') + ' ' + wtype;
552                                                 }
553                                         break;
554                                         case 'file-thumbnail-no':
555                                                 wmsg += gM('mwe-file-thumbnail-no', winfo);
556                                         break;
557                                         default:
558                                                 wmsg += gM('mwe-upload-misc-error') + ' ' + wtype;
559                                         break;
560                                 }
561                                 wmsg+='</li>';
562                         }
563                         wmsg+='</ul>';
564                         if( apiRes.upload.warnings.sessionkey)
565                                 _this.warnings_sessionkey = apiRes.upload.warnings.sessionkey;
566                         var bObj = {};
567                         bObj[ gM('mwe-ignorewarning') ] =       function() {
568                                 js_log('ignorewarning req:')
569                                 //re-inciate the upload proccess
570                                 $j('#wpIgnoreWarning').attr('checked', true);
571                                 $j( _this.editForm ).submit();
572                         };
573                         bObj[ gM('mwe-return-to-form') ] = function(){
574                                 $j(this).dialog('close');
575                                 _this.form_post_override = false;
576                         }
577                         _this.updateProgressWin( gM('mwe-uploadwarning'),  '<h3>' + gM('mwe-uploadwarning') + '</h3>' +wmsg + '<p>',bObj);
578                         return false;
579                 }
580                 //should be "OK"
581                 return true;
582         },
583         processApiResult: function( apiRes ){
584                 var _this = this;
585                 js_log('processApiResult::');           
586                 //check for upload api error:
587                 // {"upload":{"result":"Failure","error":"unknown-error","code":{"status":5,"filtered":"NGC2207%2BIC2163.jpg"}}}
588                 if( _this.apiUpdateErrorCheck(apiRes) === false){
589                         //error returned false (updated and
590                         return false;
591                 }else{
592                         //check for upload_session key for async upload:
593                         if( apiRes.upload && apiRes.upload.upload_session_key ){
594                                 //set the session key
595                                 _this.upload_session_key = apiRes.upload.upload_session_key;
597                                 //do ajax upload status:
598                                 _this.doAjaxUploadStatus();
599                                 js_log("set upload_session_key: " + _this.upload_session_key);
600                                 return ;
601                         }
603                         if( apiRes.upload.imageinfo &&  apiRes.upload.imageinfo.descriptionurl ){
604                                 var url = apiRes.upload.imageinfo.descriptionurl;
605                                 //check done action:
606                                 if( _this.done_upload_cb && typeof _this.done_upload_cb == 'function'){
607                                         js_log("call done_upload_cb");
608                                         //close up shop:
609                                         $j('#upProgressDialog').dialog('close');
610                                         //call the callback:
611                                         _this.done_upload_cb( apiRes.upload );
612                                         return false;
613                                 }else{
614                                         var bObj = {};
615                                         bObj[ gM('mwe-return-to-form')] = function(){
616                                                 $j(this).dialog('close');
617                                                 _this.form_post_override = false;
618                                         }
619                                         bObj[ gM('mwe-go-to-resource') ] = function(){
620                                                         window.location = url;
621                                         };
622                                         _this.action_done = true;
623                                         _this.updateProgressWin( gM('mwe-successfulupload'),  gM( 'mwe-upload_done', url), bObj);
624                                         js_log('apiRes.upload.imageinfo::'+url);
625                                         return true;
626                                 }
627                         }
628                 }
629         },
630         updateProgressWin:function(title_txt, msg, buttons){
631                 var _this = this;
632                  if(!title_txt)
633                    title_txt = _this.getProgressTitle();
634                  if(!msg)
635                    msg = mv_get_loading_img( 'left:40%;top:40px;');
636                  $j( '#upProgressDialog' ).dialog('option', 'title',  title_txt );
637                  $j( '#upProgressDialog' ).html( msg );
638                  if(buttons){
639                          $j('#upProgressDialog').dialog('option','buttons', buttons);
640                  }else{
641                          //@@todo should convice the jquery ui people to not use object keys as user msg's
642                          var bObj = {};
643                          bObj[ gM('mwe-ok-button') ] =  function(){
644                                   $j(this).dialog('close');
645                          };
646                          $j('#upProgressDialog').dialog('option','buttons', bObj);
647                  }
648         },
649         getProgressTitle:function(){
650                 return gM('mwe-upload-in-progress');
651         },
652         getEditForm:function(){
653                 if( this.target_edit_from && $j( this.target_edit_from ).length != 0){
654                         return $j( this.target_edit_from ).get(0);
655                 }
656                 //just return the first form fond on the page.
657                 return $j('form :first').get(0);
658         },
659         updateProgress:function( perc ){
660                 //js_log('update progress: ' + perc);
661                 $j( '#up-progressbar' ).progressbar('value', parseInt( perc * 100 ) );
662                 $j( '#up-pstatus' ).html( parseInt( perc * 100 ) + '% - ' );
663         },
664         /*update to jQuery.ui progress display type */
665         dispProgressOverlay:function(){
666           var _this = this;
667           
668           //remove old instance:
669           if($j('#upProgressDialog').length!=0){
670                  $j('#upProgressDialog').dialog( 'destroy' ).remove();
671           }
672           //re add it:
673           $j('body').append('<div id="upProgressDialog" ></div>');
675           $j('#upProgressDialog').dialog({
676                   title:_this.getProgressTitle(),
677                   bgiframe: true,
678                   modal: true,
679                   width:400,
680                   heigh:200,
681                   beforeclose: function(event, ui) {
682                           if( event.button==0 && _this.action_done === false){
683                                 return _this.cancel_action();
684                           }else{
685                                  //click on button (dont do close action);
686                                  return true;
687                           }
688                   },
689                   buttons: _this.cancel_button()
690           });
691           $j('#upProgressDialog').html(
692                 //set initial content:
693                 '<div id="up-pbar-container" style="width:90%;height:15px;" >' +
694                 '<div id="up-progressbar" style="height:15px;"></div>' +
695                         '<div id="up-status-container">'+
696                                 '<span id="up-pstatus">0% - </span> ' +
697                                 '<span id="up-status-state">' + gM('mwe-uploaded-status') + '</span> ' +
698                         '</div>'+
699                 '</div>'
700           )
701           //just display an empty progress window
702           $j('#upProgressDialog').dialog('open');
704           //setup progress bar:
705           $j('#up-progressbar').progressbar({
706                   value:0
707           });
709         },
710         cancel_button:function(){
711            var _this = this;
712            var cancelBtn = new Array();
713            cancelBtn[ gM('mwe-cancel-button') ] =  function(){
714                         return _this.cancel_action(this)
715            };
716            return cancelBtn;
717         },
718         cancel_action : function( dlElm ){
719                 //confirm:
720                 if( confirm( gM('mwe-cancel-confim') )){
721                         //@@todo (cancel the encode / upload)
722                         $j(this).dialog('close');
723                         return false;
724                 }else{
725                         return true;
726                 }
727         }
730 //add some jquery binding helpers
731 (function($) {
732         /**
733          * doDestCheck checks the destination
734          */
735         $.fn.doDestCheck = function( opt ){
736                 var _this = this;
737                 js_log('doDestCheck::' + _this.selector);
739                 //set up option defaults;
740                 if(!opt.warn_target)
741                         opt.warn_target = '#wpDestFile-warning';
743                 //empty target warn:
744                 $j( opt.warn_target ).empty();
745                 
746                 //show loading          
747                 $j( _this.selector ).append('<img id="mw-spinner-wpDestFile" src ="'+ stylepath + '/common/images/spinner.gif" />');
748                 
749                 //try and get a thumb of the current file (check its destination)
750                 do_api_req({
751                         'data':{
752                                 'titles': 'File:' + $j(_this.selector).val(),//@@todo we may need a more clever way to get a the filename
753                                 'prop':  'imageinfo',
754                                 'iiprop':'url|mime|size',
755                                 'iiurlwidth': 150
756                         }
757                 },function(data){       
758                         //remove spinner:
759                         $j('#mw-spinner-wpDestFile').remove();
760                         if(data && data.query && data.query.pages){
761                                 if( data.query.pages[-1] ){
762                                         //all good no file there
763                                 }else{
764                                         for(var page_id in data.query.pages){
765                                                 var ntitle = ( data.query.normalized)? data.query.normalized[0].to : data.query.pages[ page_id ].title
766                                                 var img = data.query.pages[ page_id ].imageinfo[0];
767                                                 $j('#wpDestFile-warning').html(
768                                                         '<ul>' +
769                                                                 '<li>'+
770                                                                         gM('mwe-fileexists', ntitle) +
771                                                                 '</li>'+
772                                                                 '<div class="thumb tright">' +
773                                                                         '<div style="width: ' + ( parseInt(img.thumbwidth)+2 ) + 'px;" class="thumbinner">' +
774                                                                                 '<a title="' + ntitle + '" class="image" href="' + img.descriptionurl + '">' +
775                                                                                         '<img width="' + img.thumbwidth + '" height="' + img.thumbheight + '" border="0" class="thumbimage" ' +
776                                                                                         'src="' + img.thumburl + '"' +
777                                                                                         '        alt="' + ntitle + '"/>' +
778                                                                                 '</a>' +
779                                                                                 '<div class="thumbcaption">' +
780                                                                                         '<div class="magnify">' +
781                                                                                                 '<a title="' + gM('thumbnail-more') + '" class="internal" ' +
782                                                                                                         'href="' + img.descriptionurl +'"><img width="15" height="11" alt="" ' +
783                                                                                                         'src="' + stylepath + "/common/images/magnify-clip.png\" />" +
784                                                                                                 '</a>'+
785                                                                                         '</div>'+
786                                                                                         gM('mwe-fileexists-thumb') +
787                                                                                 '</div>' +
788                                                                         '</div>'+
789                                                                 '</div>' +
790                                                         '</ul>'
791                                                 );
792                                         }
793                                 }
794                         }
795                 });
796         }
797 })(jQuery);