MediaWiki:Gadget-libCommons.js

Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
/**
 * <nowiki>
 * This is a library for containing common used functions on Commons.
 * Inclusion-scope: 
 *   "used by one or better more of the default or in one of the 5 most popular gadgets"
 *   "and is potentially useful for other tools on Commons"
 * Keep in mind: It's a library. Do not change any variable-state or the UI until a method is called.
 *
 * All things that aren't specific to Commons (as a media hoster) should go into an other module.
 * 
 * Coding convetion:
 * Do not self-refer inside a function using "this"; instead use "lc"
 * to allow reusing these functions in an altered scope
 *
 * Derived from [[MediaWiki:Gadgetprototype.js]]
 *
 * @rev 1 (2012-05-01)
 * @author Rillke, 2012
 */

// Invoke automated jsHint-validation on save: A feature on WikimediaCommons
// Interested? See [[:commons:MediaWiki:JSValidator.js]].

/*global jQuery:false, mediaWiki:false*/
/*jshint curly:false*/

( function ( $, mw ) {
"use strict";

if (!mw.libs.commons) mw.libs.commons = {};
var lc = mw.libs.commons;

$.extend(mw.libs.commons, {
	/**
	* In the past some bots were buggy and double-encoded their operators. 
	* This has to be fixed in order to e.g. notify them correctly.
	* @author
	*      Lupo
	*
	* @example
	*      mw.libs.commons.fixDoubleEncoding( authorString );
	*
	* @param s {string} String that's possible double-encoding should be fixed.
	* @context {mw.libs.commons} or any other
	* @return {string} The fixed encoding-fixed string.
	*/
	fixDoubleEncoding: function(s) {
		if (!s) return s;
		var utf8 = /[u00C2-u00F4][u0080-u00BF][u0080-u00BF]?[u0080-u00BF]?/g;
		if (!utf8.test(s)) return s;
		// Looks like we have a double encoding. At least it contains character
		// sequences that might be legal UTF-8 encodings. Translate them into %-
		// syntax and try to decode again.
		var temp = "",
			curr = 0,
			m, hex_digit = "0123456789ABCDEF";
		var str = s.replace(/%/g, '%25');
		utf8.lastIndex = 0;
		// Reset regexp to beginning of string
		try {
			while ((m = utf8.exec(str)) !== null) {
				temp += str.substring(curr, m.index);
				m = m[0];
				for (var i = 0; i < m.length; i++) {
					temp += '%' + hex_digit.charAt(m.charCodeAt(i) / 16) + hex_digit.charAt(m.charCodeAt(i) % 16);
				}
				curr = utf8.lastIndex;
			}
			if (curr < str.length) temp += str.substring(curr);
			temp = decodeURIComponent(temp);
			return temp;
		} catch (e) {}
		return s;
	},
	smallChangesBots: [
		'FlickreviewR', 
		'Rotatebot', 
		'Cropbot', 
		'Picasa Review Bot', 
		'Reedy RotateBot',
		'OgreBot',
		'Panoramio Review Bot',
		'Picasa Review Bot 2',
		'FlickreviewR 2',
		'SteinsplitterBot',
		'Embedded Data Bot',
	],
	/**
	* At Commons there are bots that are controlled via [[TUSC]] and 
	* allow arbitrary people to operate them or are invoked by a template.
	* Some of them only upload full resolutions from source or 
	* do minor changes like changing the orientation.
	*
	* @example
	*      if (mw.libs.commons.isSmallChangesBot( "RillkeBot" )) { ... }
	*
	* @param name {string} User name to check against the list.
	* @context {mw.libs.commons} or any other
	* @return {boolean} Returns true if the bot usually does only small changes
	*  and neither its operator nor the TUSC user should be notified in case of
	*  deletion requests etc.
	*/
	isSmallChangesBot: function(name) {
		return ($.inArray(name, lc.smallChangesBots) > -1);
	},
	
	/**
	* At Commons there are bots that are controlled via [[TUSC]] and 
	* allow arbitrary people to operate them.
	* If, for example one upload issued by a user has to be nominated for deletion, 
	* not the bot should be notified but the user who used the bot
	*
	* @author
	*      Lupo; rewritten by Rillke
	*
	* @example
	*      mw.libs.commons.getUploadBotUser( 
	*             "File Upload Bot (Magnus Manske)", 
	*             "== {{int:file-desc}} ==\n{{Information\n....}}", 
	*             "Transfered from Flickr by [[User:Lupo|Lupo]] using CommonsHelper" 
	*      );
	*
	* @param bot {string} Uploader (maybe a bot).
	* @param content {string} The file desctiption page's content.
	* @param comment {string} The comment the uploader left.
	* @context {mw.libs.commons} or any other
	* @return {string} The uploader or the bot's operator.
	*/
	getUploadBotUser: function(bot, content, comment, firstTextRevisionUser) {
		var match;
		switch (bot) {
			case 'Upload Bot (Rich Smith)':
			case 'File Upload Bot (Magnus Manske)':
				// CommonsHelper
				match = /^[Tt]ransferr?e?d from .+? by \[\[User:([^\]\|]*)(\|([^\]]*))?\]\] using/.exec(comment);
				var reOldCH = /[Tt]ransferred to Commons by \[\[User:([^\]\|]+)(?:\|(?:[^\]]*))?\]\] using/;
				if (!match) match = reOldCH.exec(comment);
				if (!match) match = reOldCH.exec(content);
				if (!match) match = /\{\{transferred from\|[^\}\|]+\|([^\}\|]+)\|[^\}\|]+\}\}/.exec(content);

				// geograph_org2commons, regex accounts for typo ("transferd") and it's possible future correction
				var oldGeograph = /geograph.org.uk\]; transferr?e?d by \[\[User:([^\]\|]+)(?:\|(?:[^\]]*))?\]\] using/;
				if (!match) match = oldGeograph.exec(comment);
				if (!match) match = oldGeograph.exec(content);

				// flickr2commons
				if (!match) match = /\* Uploaded by \[\[User:([^\]\|]+)\|(?:(?:[^\]]*))?/.exec(comment);
				if (!match) match = /\* Uploaded by \[\[User:([^\]\|]+)(?:\|(?:[^\]]*))?\]\]/.exec(content);
				if (match) match = match[1];

				// Really necessary?
				match = lc.fixDoubleEncoding(match);
				break;

			case 'FlickrLickr':
				match = /\n\|reviewer=\s*(.+)\n/.exec(content);
				if (match) match = match[1];
				break;

			case 'Flickr upload bot':
				// Check for the bot's upload template
				match = /\{\{User:Flickr upload bot\/upload(?:-pd)?(?:\|[^\|\}]*)?\|reviewer=([^\}]+)\}\}/.exec(content);
				if (match) match = match[1];
				if (!match) match = firstTextRevisionUser;
				break;
			default: return bot;
		}
		if (match) {
			// Make sure the username is in canonical form ("wikitrim", normalizing)
			match = match.replace(/^[\s_]+/, '').replace(/[\s_]+$/, '').replace(/[\s_]+/g, ' ');
			match = match.substr(0, 1).toUpperCase() + match.substr(1);
			bot = match;
		}
		return bot;
	}
});

}( jQuery, mediaWiki ));
// </nowiki>