Index: trunk/extensions/UploadWizard/UploadWizardHooks.php |
— | — | @@ -136,9 +136,9 @@ |
137 | 137 | 'mwe-upwiz-api-error-unknown-warning', |
138 | 138 | 'mwe-upwiz-api-error-timeout', |
139 | 139 | 'mwe-upwiz-api-error-noimageinfo', |
140 | | - |
141 | 140 | 'mwe-upwiz-api-error-fileexists-shared-forbidden', |
142 | | - |
| 141 | + 'mwe-upwiz-api-error-unclassified', |
| 142 | + 'mwe-upwiz-api-warning-was-deleted', |
143 | 143 | 'mwe-upwiz-api-warning-exists', |
144 | 144 | 'mwe-upwiz-tutorial-error-localized-file-missing', |
145 | 145 | 'mwe-upwiz-tutorial-error-file-missing', |
— | — | @@ -262,6 +262,8 @@ |
263 | 263 | 'mwe-upwiz-error-title-senselessimagename', |
264 | 264 | 'mwe-upwiz-error-title-hosting', |
265 | 265 | 'mwe-upwiz-error-title-thumbnail', |
| 266 | + 'mwe-upwiz-error-title-fileexists-shared-forbidden', |
| 267 | + 'mwe-upwiz-error-title-double-apostrophe', |
266 | 268 | 'mwe-upwiz-license-cc-by-sa-3.0', |
267 | 269 | 'mwe-upwiz-license-cc-by-3.0', |
268 | 270 | 'mwe-upwiz-license-cc-zero', |
Index: trunk/extensions/UploadWizard/UploadWizard.i18n.php |
— | — | @@ -23,6 +23,7 @@ |
24 | 24 | 'mwe-upwiz-step-thanks' => 'Use', |
25 | 25 | 'mwe-upwiz-api-error-http' => 'Internal error: unable to connect to server.', |
26 | 26 | 'mwe-upwiz-api-error-ok-but-empty' => 'Internal error: no response from server.', |
| 27 | + 'mwe-upwiz-api-error-unclassified' => 'An unknown error occurred', |
27 | 28 | 'mwe-upwiz-api-error-unknown-code' => 'Unknown error: "$1"', |
28 | 29 | 'mwe-upwiz-api-error-uploaddisabled' => 'Uploading is disabled on this wiki.', |
29 | 30 | 'mwe-upwiz-api-error-nomodule' => 'Internal error: no upload module set.', |
— | — | @@ -54,10 +55,10 @@ |
55 | 56 | 'mwe-upwiz-api-error-unknown-warning' => 'Unknown warning: $1', |
56 | 57 | 'mwe-upwiz-api-error-timeout' => 'The server did not respond within the expected time.', |
57 | 58 | 'mwe-upwiz-api-error-noimageinfo' => 'The upload succeeded, but the server did not give us any information about the file.', |
58 | | - 'mwe-upwiz-api-error-fileexists-shared-forbidden' => 'This filename is reserved by a file on a remote shared repository. Choose another name.', |
59 | 59 | |
60 | 60 | |
61 | 61 | 'mwe-upwiz-api-warning-exists' => 'There is [$1 another file] already on the wiki with the same filename', |
| 62 | + 'mwe-upwiz-api-warning-was-deleted' => 'There was a file by this name, "$1", but it was deleted and you can not reupload the file. If your file is different, try renaming it.', |
62 | 63 | 'mwe-upwiz-tutorial-error-localized-file-missing' => 'Sorry, we could not find a tutorial in your language. The English one is shown instead.', |
63 | 64 | 'mwe-upwiz-tutorial-error-file-missing' => 'Sorry, we could not find any files for the tutorial that is supposed to go here. Please contact the system administrators.', |
64 | 65 | 'mwe-upwiz-tutorial-error-cannot-transform' => 'Sorry, we could not get a scaled image of the tutorial to fit this screen. This may be a temporary problem with Wikimedia Commons; try again later.', |
— | — | @@ -182,6 +183,8 @@ |
183 | 184 | 'mwe-upwiz-error-title-senselessimagename' => 'Please make this title more meaningful.', |
184 | 185 | 'mwe-upwiz-error-title-hosting' => 'This looks like a file you obtained from another imagehost. Please make the title more meaningful. Also, double check that you have the rights to publish it on {{SITENAME}}.', |
185 | 186 | 'mwe-upwiz-error-title-thumbnail' => 'This looks like a thumbnail title. Please do not upload thumbnails back to the same wiki. Otherwise, please fix the filename so it is more meaningful, and does not have the thumbnail prefix.', |
| 187 | + 'mwe-upwiz-error-title-fileexists-shared-forbidden' => 'This title is reserved by a file on a remote shared repository. Choose another name.', |
| 188 | + 'mwe-upwiz-error-title-double-apostrophe' => 'This title contains a double apostrophe; please remove it.', |
186 | 189 | |
187 | 190 | /* LICENSES & combinations of licenses */ |
188 | 191 | /* may be a good idea to shift to WikimediaLicenseTexts? */ |
Index: trunk/extensions/UploadWizard/resources/uploadWizard.css |
— | — | @@ -597,12 +597,12 @@ |
598 | 598 | cursor: pointer; |
599 | 599 | } |
600 | 600 | |
601 | | -.mwe-error, .mwe-validator-error, .errorTitleUnique { |
| 601 | +.mwe-error, .mwe-validator-error { |
602 | 602 | color: #ff0000; |
603 | 603 | } |
604 | 604 | |
605 | 605 | .mwe-upwiz-deed-thirdparty .mwe-upwiz-deed-form-internal label.mwe-error, |
606 | | -.mwe-upwiz-deed-thirdparty .mwe-upwiz-deed-form-internal label.mwe-validator-error, label.errorTitleUnique { |
| 606 | +.mwe-upwiz-deed-thirdparty .mwe-upwiz-deed-form-internal label.mwe-validator-error { |
607 | 607 | margin-left: 0; |
608 | 608 | } |
609 | 609 | |
Index: trunk/extensions/UploadWizard/resources/mw.UploadWizardDetails.js |
— | — | @@ -62,8 +62,9 @@ |
63 | 63 | } ); |
64 | 64 | |
65 | 65 | _this.titleErrorDiv = $j('<div class="mwe-upwiz-details-input-error">' |
66 | | - + '<label class="mwe-validator-error" for="' + _this.titleId + '" generated="true"/>' |
67 | | - + '<label class="errorTitleUnique" for="' + _this.titleId + '" generated="true"/>' |
| 66 | + + '<label class="mwe-error mwe-validator-error" for="' + _this.titleId + '" generated="true"/>' |
| 67 | + + '<label class="mwe-error errorTitleUnique" for="' + _this.titleId + '" generated="true"/>' |
| 68 | + + '<label class="mwe-error errorRecovery" for="' + _this.titleId + '" generated="true"/>' |
68 | 69 | + '</div>'); |
69 | 70 | |
70 | 71 | var titleHintId = 'mwe-upwiz-title-hint-' + _this.upload.index; |
— | — | @@ -162,7 +163,7 @@ |
163 | 164 | |
164 | 165 | |
165 | 166 | /* Build the form for the file upload */ |
166 | | - _this.$form = $j( '<form></form>' ); |
| 167 | + _this.$form = $j( '<form></form>' ).addClass( 'detailsForm' ); |
167 | 168 | _this.$form.append( |
168 | 169 | titleContainerDiv, |
169 | 170 | _this.descriptionsDiv, |
— | — | @@ -702,8 +703,9 @@ |
703 | 704 | |
704 | 705 | var err = function( code, info ) { |
705 | 706 | _this.upload.state = 'error'; |
706 | | - _this.showError( code, info ); |
| 707 | + _this.processError( code, info ); |
707 | 708 | }; |
| 709 | + |
708 | 710 | |
709 | 711 | var ok = function( result ) { |
710 | 712 | if ( result && result.upload && result.upload.imageinfo ) { |
— | — | @@ -712,6 +714,22 @@ |
713 | 715 | _this.upload.state = 'complete'; |
714 | 716 | _this.showIndicator( 'uploaded' ); |
715 | 717 | _this.setStatus( gM( 'mwe-upwiz-published' ) ); |
| 718 | + } else if ( result && result.upload.warnings ) { |
| 719 | + var warnings = result.upload.warnings; |
| 720 | + if ( warnings['was-deleted'] ) { |
| 721 | + _this.recoverFromError( _this.titleId, gM( 'mwe-upwiz-api-warning-was-deleted' ) ); |
| 722 | + } else if ( warnings['thumb'] ) { |
| 723 | + _this.recoverFromError( _this.titleId, gM( 'mwe-upwiz-error-title-thumbnail' ) ); |
| 724 | + } else if ( warnings['bad-prefix'] ) { |
| 725 | + _this.recoverFromError( _this.titleId, gM( 'mwe-upwiz-error-title-senselessimagename' ) ); |
| 726 | + } else { |
| 727 | + var warningsKeys = []; |
| 728 | + $j.each( warnings, function( key, val ) { |
| 729 | + warningsKeys.push( key ); |
| 730 | + } ); |
| 731 | + _this.upload.state = 'error'; |
| 732 | + _this.showError( 'unknown', gM( 'mwe-upwiz-api-error-unknown-warning', warningsKeys.join( ', ' ) ) ); |
| 733 | + } |
716 | 734 | } else { |
717 | 735 | err( 'details-info-missing', result ); |
718 | 736 | } |
— | — | @@ -720,15 +738,59 @@ |
721 | 739 | _this.upload.api.postWithEditToken( params, ok, err ); |
722 | 740 | }, |
723 | 741 | |
724 | | - showError: function( code, result ) { |
| 742 | + |
| 743 | + /** |
| 744 | + * Create a recoverable error -- show the form again, and highlight the problematic field. Go to error state but do not block submission |
| 745 | + * @param {String} name of field |
| 746 | + * @param {String} error message to show |
| 747 | + */ |
| 748 | + recoverFromError: function( fieldname, errorMessage ) { |
| 749 | + this.upload.state = 'error'; |
| 750 | + this.dataDiv.morphCrossfade( '.detailsForm' ); |
| 751 | + this.$form.find( '[name=' + fieldname + ']' ).addClass( 'mwe-error' ); |
| 752 | + this.$form.find( 'label[for=' + fieldname + '].errorRecovery' ).html( errorMessage ).show(); |
| 753 | + }, |
| 754 | + |
| 755 | + /** |
| 756 | + * Show error state, possibly using a recoverable error form |
| 757 | + * @param {String} error code |
| 758 | + * @param {String} status line |
| 759 | + */ |
| 760 | + showError: function( code, statusLine ) { |
725 | 761 | this.showIndicator( 'error' ); |
726 | | - // types of errors we know about... |
727 | | - // recoverable by fixing title |
728 | | - // TODO unmask and fix the error on the title |
| 762 | + this.setStatus( statusLine ); |
| 763 | + }, |
729 | 764 | |
730 | | - // recoverable by trying again, or removing |
731 | | - // TODO removal / retry interface |
732 | | - this.setStatus( result.error.info ); |
| 765 | + |
| 766 | + /** |
| 767 | + * Decide how to treat various errors |
| 768 | + * @param {String} error code |
| 769 | + * @param {Mixed} result from ajax call |
| 770 | + */ |
| 771 | + processError: function( code, result ) { |
| 772 | + var statusLine = gM( 'mwe-upwiz-unclassified' ); |
| 773 | + var titleErrorMap = { |
| 774 | + 'senselessimagename': 'senselessimagename', |
| 775 | + 'fileexists-shared-forbidden': 'fileexists-shared-forbidden', |
| 776 | + 'titleblacklist-custom-filename': 'hosting', |
| 777 | + 'titleblacklist-custom-SVG-thumbnail': 'thumbnail', |
| 778 | + 'titleblacklist-custom-thumbnail': 'thumbnail', |
| 779 | + 'titleblacklist-custom-double-apostrophe': 'double-apostrophe' |
| 780 | + }; |
| 781 | + if ( result && result.error && result.error.code ) { |
| 782 | + if ( titleErrorMap[code] ) { |
| 783 | + _this.recoverFromError( _this.titleId, gM( 'mwe-upwiz-error-title-' + titleErrorMap[code] ) ); |
| 784 | + return; |
| 785 | + } else { |
| 786 | + statusKey = 'mwe-upwiz-api-error-' + code; |
| 787 | + if ( result.error.info ) { |
| 788 | + statusLine = gM( statusKey, result.error.info ); |
| 789 | + } else { |
| 790 | + statusLine = gM( statusKey, '[no error info]' ); |
| 791 | + } |
| 792 | + } |
| 793 | + } |
| 794 | + this.showError( code, statusLine ); |
733 | 795 | }, |
734 | 796 | |
735 | 797 | setStatus: function( s ) { |