MarkTraceur has uploaded a new change for review. https://gerrit.wikimedia.org/r/234086
Change subject: Add ForeignUpload and ForeignStructuredUpload ...................................................................... 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 --- M resources/Resources.php A resources/src/mediawiki/mediawiki.ForeignStructuredUpload.js A resources/src/mediawiki/mediawiki.ForeignUpload.js M tests/qunit/QUnitTestResources.php A tests/qunit/suites/resources/mediawiki/mediawiki.ForeignStructuredUpload.test.js A tests/qunit/suites/resources/mediawiki/mediawiki.ForeignUpload.test.js 6 files changed, 278 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/86/234086/1 diff --git a/resources/Resources.php b/resources/Resources.php index 8e7e368..fbcc441 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1127,6 +1127,19 @@ 'mediawiki.api.upload', ), ), + 'mediawiki.ForeignUpload' => array( + 'scripts' => 'resources/src/mediawiki/mediawiki.ForeignUpload.js', + 'dependencies' => array( + '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 0000000..2541df0 --- /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 https://commons.wikimedia.org/wiki/Commons:Structured_data 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. + * + * @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 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(), + '|description=', + this.getDescriptions(), + '|date=', + this.getDate(), + '|source=', + this.getUser(), + '|author=', + this.getUser(), + '}}\n\n', + this.getLicense(), + '\n\n', + this.getCategories() + ].join( '' ); + }; + + /** + * Gets the wikitext for the creation date of this upload. + * @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. + * @return {string} + */ + ForeignStructuredUpload.prototype.getTemplateName = function () { + return 'Information'; + }; + + /** + * Fetches the wikitext for any descriptions that have been added + * to the upload. + * @return {string} + */ + ForeignStructuredUpload.prototype.getDescriptions = function () { + var i, desc, + desctext = ''; + + for ( i = 0; i < this.descriptions.length; i++ ) { + desc = this.descriptions[i]; + desctext += '{{' + desc.language + '|' + desc.text + '}}'; + } + + return desctext; + }; + + /** + * Fetches the wikitext for the categories to which the upload will + * be added. + * @return {string} + */ + ForeignStructuredUpload.prototype.getCategories = function () { + var i, cat, + cattext = ''; + + for ( i = 0; i < this.categories.length; i++ ) { + cat = this.categories[i]; + cattext += '[[Category:' + cat + ']]'; + } + + return cattext; + }; + + /** + * Gets the wikitext for the license of the upload. Abstract for now. + * @abstract + * @return {string} + */ + ForeignStructuredUpload.prototype.getLicense = function () { + return ''; + }; + + /** + * Get the username. + * @return {string} + */ + ForeignStructuredUpload.prototype.getUser = function () { + return mw.user.getName(); + }; + + 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 0000000..d790ea3 --- /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 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 ( document.location.host !== this.targetHost ) { + api = new mw.ForeignApi( + document.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 60b2802..ae2cc73 100644 --- a/tests/qunit/QUnitTestResources.php +++ b/tests/qunit/QUnitTestResources.php @@ -71,6 +71,8 @@ '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 @@ '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 0000000..cc78267 --- /dev/null +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.ForeignStructuredUpload.test.js @@ -0,0 +1,29 @@ +( 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 1 2 3' ); + 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|description={{en|Test description 1 2 3}}|date=1776-07-04|source=Test user|author=Test user}}\n\n\n\n[[Category:Test 1]][[Category:Test 2]][[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 0000000..98b9678 --- /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 ) ); -- To view, visit https://gerrit.wikimedia.org/r/234086 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I96fcb862eb854d23b6f9f553a87fa7ca65bf5a93 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: MarkTraceur <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
