From: Mark Holmquist Date: Wed, 26 Aug 2015 19:42:21 +0000 (-0500) Subject: Add ForeignUpload and ForeignStructuredUpload X-Git-Tag: 1.31.0-rc.0~10193^2 X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22articles_versions%22%2C%22id_article=%24id_article%22%29%20.%20%22?a=commitdiff_plain;h=85a580452813291f391bf672d54b8af3ae81277e;p=lhc%2Fweb%2Fwiklou.git Add ForeignUpload and ForeignStructuredUpload These classes will be used to send uploads from one wiki to another, and the latter includes (partial) adherence to the Commons structured data system [0]. [0] https://commons.wikimedia.org/wiki/Commons:Structured_data Change-Id: I96fcb862eb854d23b6f9f553a87fa7ca65bf5a93 Bug: T105071 --- diff --git a/maintenance/jsduck/categories.json b/maintenance/jsduck/categories.json index d547b7bde6..5b9f339af4 100644 --- a/maintenance/jsduck/categories.json +++ b/maintenance/jsduck/categories.json @@ -60,7 +60,9 @@ "name": "Interfaces", "classes": [ "mw.Feedback*", - "mw.Upload*" + "mw.Upload*", + "mw.ForeignUpload", + "mw.ForeignStructuredUpload" ] }, { diff --git a/resources/Resources.php b/resources/Resources.php index 8e7e368a9b..851dfa3a55 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1127,6 +1127,20 @@ return array( 'mediawiki.api.upload', ), ), + 'mediawiki.ForeignUpload' => array( + 'scripts' => 'resources/src/mediawiki/mediawiki.ForeignUpload.js', + 'dependencies' => array( + 'mediawiki.ForeignApi', + 'mediawiki.Upload', + 'oojs', + ), + ), + 'mediawiki.ForeignStructuredUpload' => array( + 'scripts' => 'resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js', + 'dependencies' => array( + 'mediawiki.ForeignUpload', + ), + ), 'mediawiki.Upload.Dialog' => array( 'scripts' => 'resources/src/mediawiki/mediawiki.Upload.Dialog.js', 'dependencies' => array( diff --git a/resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js b/resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js new file mode 100644 index 0000000000..be639367f8 --- /dev/null +++ b/resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js @@ -0,0 +1,162 @@ +( function ( mw, OO ) { + /** + * @class mw.ForeignStructuredUpload + * @extends mw.ForeignUpload + * + * Used to represent an upload in progress on the frontend. + * + * This subclass will upload to a wiki using a structured metadata + * system similar to (or identical to) the one on Wikimedia Commons. + * + * See for + * a more detailed description of how that system works. + * + * TODO this currently only supports uploads under CC-BY-SA 4.0, + * and should really have support for more licenses. + * + * @inheritdoc + */ + function ForeignStructuredUpload( targetHost, apiconfig ) { + this.date = undefined; + this.descriptions = []; + this.categories = []; + + mw.ForeignUpload.call( this, targetHost, apiconfig ); + } + + OO.inheritClass( ForeignStructuredUpload, mw.ForeignUpload ); + + /** + * Add categories to the upload. + * @param {string[]} categories Array of categories to which this upload will be added. + */ + ForeignStructuredUpload.prototype.addCategories = function ( categories ) { + var i, category; + + for ( i = 0; i < categories.length; i++ ) { + category = categories[i]; + this.categories.push( category ); + } + }; + + /** + * Add a description to the upload. + * @param {string} language The language code for the description's language. Must have a template on the target wiki to work properly. + * @param {string} description The description of the file. + */ + ForeignStructuredUpload.prototype.addDescription = function ( language, description ) { + this.descriptions.push( { + language: language, + text: description + } ); + }; + + /** + * Set the date of creation for the upload. + * @param {Date} date + */ + ForeignStructuredUpload.prototype.setDate = function ( date ) { + this.date = date; + }; + + /** + * Get the text of the file page, to be created on upload. Brings together + * several different pieces of information to create useful text. + * @return {string} + */ + ForeignStructuredUpload.prototype.getText = function () { + return ( + '{{' + + this.getTemplateName() + + '\n|description=' + + this.getDescriptions() + + '\n|date=' + + this.getDate() + + '\n|source=' + + this.getUser() + + '\n|author=' + + this.getUser() + + '\n}}\n\n' + + this.getLicense() + + '\n\n' + + this.getCategories() + ); + }; + + /** + * Gets the wikitext for the creation date of this upload. + * @private + * @return {string} + */ + ForeignStructuredUpload.prototype.getDate = function () { + if ( !this.date ) { + return ''; + } + + return this.date.toString(); + }; + + /** + * Gets the name of the template to use for creating the file metadata. + * Override in subclasses for other templates. + * @private + * @return {string} + */ + ForeignStructuredUpload.prototype.getTemplateName = function () { + return 'Information'; + }; + + /** + * Fetches the wikitext for any descriptions that have been added + * to the upload. + * @private + * @return {string} + */ + ForeignStructuredUpload.prototype.getDescriptions = function () { + var i, desc, templateCalls = []; + + for ( i = 0; i < this.descriptions.length; i++ ) { + desc = this.descriptions[i]; + templateCalls.push( '{{' + desc.language + '|' + desc.text + '}}' ); + } + + return templateCalls.join( '\n' ); + }; + + /** + * Fetches the wikitext for the categories to which the upload will + * be added. + * @private + * @return {string} + */ + ForeignStructuredUpload.prototype.getCategories = function () { + var i, cat, categoryLinks = []; + + for ( i = 0; i < this.categories.length; i++ ) { + cat = this.categories[i]; + categoryLinks.push( '[[Category:' + cat + ']]' ); + } + + return categoryLinks.join( '\n' ); + }; + + /** + * Gets the wikitext for the license of the upload. Abstract for now. + * @private + * @return {string} + */ + ForeignStructuredUpload.prototype.getLicense = function () { + return ''; + }; + + /** + * Get the username. + * @private + * @return {string} + */ + ForeignStructuredUpload.prototype.getUser = function () { + return mw.config.get( 'wgUserName' ); + }; + + mw.ForeignStructuredUpload = ForeignStructuredUpload; +}( mediaWiki, OO ) ); diff --git a/resources/src/mediawiki/mediawiki.ForeignUpload.js b/resources/src/mediawiki/mediawiki.ForeignUpload.js new file mode 100644 index 0000000000..0929661648 --- /dev/null +++ b/resources/src/mediawiki/mediawiki.ForeignUpload.js @@ -0,0 +1,58 @@ +( function ( mw, OO ) { + /** + * @class mw.ForeignUpload + * @extends mw.Upload + * + * Used to represent an upload in progress on the frontend. + * + * Subclassed to upload to a foreign API, with no other goodies. Use + * this for a generic foreign image repository on your wiki farm. + * + * Note you can provide the {@link #targetHost targetHost} or not - if the first argument is + * an object, we assume you want the default, and treat it as apiconfig + * instead. + * + * @constructor + * @param {string} [targetHost="commons.wikimedia.org"] Used to set up the target + * wiki. If not remote, this class behaves identically to mw.Upload (unless further subclassed) + * @param {Object} [apiconfig] Passed to the constructor of mw.ForeignApi or mw.Api, as needed. + */ + function ForeignUpload( targetHost, apiconfig ) { + var api; + + if ( typeof targetHost === 'object' ) { + // targetHost probably wasn't passed in, it must + // be apiconfig + apiconfig = targetHost; + } else { + // targetHost is a useful string, set it here + this.targetHost = targetHost || this.targetHost; + } + + if ( location.host !== this.targetHost ) { + api = new mw.ForeignApi( + location.protocol + '//' + this.targetHost + '/w/api.php', + apiconfig + ); + } else { + // We'll ignore the CORS and centralauth stuff if we're on Commons already + api = new mw.Api( apiconfig ); + } + + mw.Upload.call( this, api ); + } + + OO.inheritClass( ForeignUpload, mw.Upload ); + + /** + * @property targetHost + * Used to specify the target repository of the upload. + * + * You could override this to point at something that isn't Commons, + * but be sure it has the correct templates and is CORS and CentralAuth + * ready. + */ + ForeignUpload.prototype.targetHost = 'commons.wikimedia.org'; + + mw.ForeignUpload = ForeignUpload; +}( mediaWiki, OO ) ); diff --git a/tests/qunit/QUnitTestResources.php b/tests/qunit/QUnitTestResources.php index 60b2802cd8..ae2cc73ed0 100644 --- a/tests/qunit/QUnitTestResources.php +++ b/tests/qunit/QUnitTestResources.php @@ -71,6 +71,8 @@ return array( 'tests/qunit/suites/resources/mediawiki/mediawiki.storage.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.template.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.test.js', + 'tests/qunit/suites/resources/mediawiki/mediawiki.ForeignUpload.test.js', + 'tests/qunit/suites/resources/mediawiki/mediawiki.ForeignStructuredUpload.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.toc.test.js', 'tests/qunit/suites/resources/mediawiki/mediawiki.track.test.js', @@ -113,6 +115,8 @@ return array( 'mediawiki.api.upload', 'mediawiki.api.watch', 'mediawiki.ForeignApi.core', + 'mediawiki.ForeignUpload', + 'mediawiki.ForeignStructuredUpload', 'mediawiki.jqueryMsg', 'mediawiki.messagePoster', 'mediawiki.RegExp', diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.ForeignStructuredUpload.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.ForeignStructuredUpload.test.js new file mode 100644 index 0000000000..3007416f35 --- /dev/null +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.ForeignStructuredUpload.test.js @@ -0,0 +1,30 @@ +( function ( mw ) { + QUnit.module( 'mediawiki.ForeignStructuredUpload', QUnit.newMwEnvironment( {} ) ); + + QUnit.test( 'Constructor check', function ( assert ) { + QUnit.expect( 3 ); + var upload = new mw.ForeignStructuredUpload(); + + assert.ok( upload, 'The ForeignUpload constructor is working.' ); + assert.ok( upload.descriptions, 'The descriptions array was initialized properly' ); + assert.ok( upload.categories, 'The categories array was initialized properly' ); + } ); + + QUnit.test( 'getText', function ( assert ) { + QUnit.expect( 1 ); + + var upload = new mw.ForeignStructuredUpload(); + + // Set basic information + upload.addDescription( 'en', 'Test description one two three' ); + upload.addDescription( 'en-x-piglatin', 'Esttay escriptionday unway ootay eethray' ); + upload.setDate( '1776-07-04' ); + upload.addCategories( [ 'Test 1', 'Test 2' ] ); + upload.addCategories( [ 'Test 3' ] ); + + // Fake the user + this.sandbox.stub( upload, 'getUser' ).returns( 'Test user' ); + + assert.strictEqual( upload.getText().trim(), '{{Information\n|description={{en|Test description one two three}}\n{{en-x-piglatin|Esttay escriptionday unway ootay eethray}}\n|date=1776-07-04\n|source=Test user\n|author=Test user\n}}\n\n\n\n[[Category:Test 1]]\n[[Category:Test 2]]\n[[Category:Test 3]]' ); + } ); +}( mediaWiki ) ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.ForeignUpload.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.ForeignUpload.test.js new file mode 100644 index 0000000000..98b9678142 --- /dev/null +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.ForeignUpload.test.js @@ -0,0 +1,12 @@ +( function ( mw ) { + QUnit.module( 'mediawiki.ForeignUpload', QUnit.newMwEnvironment( {} ) ); + + QUnit.test( 'Constructor check', function ( assert ) { + QUnit.expect( 3 ); + var upload = new mw.ForeignUpload(); + + assert.ok( upload, 'The ForeignUpload constructor is working.' ); + assert.strictEqual( upload.targetHost, 'commons.wikimedia.org', 'Default target host is correct' ); + assert.ok( upload.api instanceof mw.ForeignApi, 'API is correctly configured to point at a foreign wiki.' ); + } ); +}( mediaWiki ) );