User:Perhelion/problemImages.js

From Meta, a Wikimedia project coordination wiki

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/** [[File:User:Perhelion/problemImages.js]]
* @Description:
* Eng: Mark images (which are either at Commons or on Wikipedia) staying for deletion or maintenance.
* Deu: Markiere Bilder (die entweder auf Commons oder der lokalen Wikipedia) zur Löschung oder Wartung stehen.
* 			window.autorunPI = true; // runs problemImages.js automatic on article namespace
* 			window.localProbCats = '…'; // you can specify a custom category (without namespace)
* @Revision: 13:44, 9 November 2017 (UTC)
* @Authors:
* created 28.04.2016 [[:de:User:Perhelion]], partial code taken from de:Benutzer:Magnus_Manske/rotbilder.js
* tested only on modern browsers <nowiki>
* required modules: mediawiki.api, mediawiki.util
* ToDo:
* Make the queries in batches, to avoid tripping API and prevent freezing the browser or a 500 server error due to a overlong query.
**/
/*global mediaWiki:false, jQuery:false*/
/*jshint bitwise:true, curly:false, eqeqeq:true, forin:false, laxbreak:true,
trailing:true, undef:true, unused:true, white:false, smarttabs:true */

(function ($, mw) { //problemImages
'use strict';
var l10n = {
	en: {
		pe_search: "Searching…",
		pe_link: "Files-check",
		pe_file: '$1 {{PLURAL:$1|file|files}} of $2 marked',
		pe_nofile: "No file found!"
	},
	de: {
		pe_search: "Suche läuft…",
		pe_link: "Dateien-Check",
		pe_file: '$1 {{PLURAL:$1|Datei|Dateien}} von $2 markiert',
		pe_nofile: "Keine Datei gefunden!"
	}
};

function initL10N(l10n) {
	var i,
	chain = mw.language.getFallbackLanguageChain();
	for (i = chain.length - 1; i >= 0; i--) {
		if (chain[i]in l10n) {
			mw.messages.set(l10n[chain[i]]);
		}
	}
}
var r = 0; // result image count
var a = 0; // all image count
var c = 0; // complete image count
var file2links = {};
var files = []; // Commons files
var l_files = []; // local Wikipedia
var portletLink;
var project = mw.config.get('wgDBname');
var ns = mw.config.get('wgNamespaceNumber');
var speedy = 'Candidates for speedy deletion';
var seriousCatRe = /^(Deletion requests |Other speedy deletions$|Media without a source|OTRS pending |Media missing permission|Media (?:uploaded )without a license|No OTRS permission$|Copyright violations|Items with disputed copyright information)/;
var supComRe = /^((?:(?:Superior )?[Vv]ector|Bitmap) version available|Superseded)$/;
var lesserCatRe = /(Media (?:data without source|missing infobox template)|Special or fictional|Disputed |Images requiring an update|needing categories)/;
var lesserMarker = '3px dotted #db0';
var superRe;
var bCommons = {
	border: '1px dotted #E95'
}; /* Simply mark images not on Commons */
var localProbCats = window.localProbCats || {
	'dewiki': 'Wikipedia:Dateiüberprüfung|Wikipedia:Schnelllöschen',
	'enwiki': 'Wikipedia files for discussion|' + speedy,
	'etwiki': 'Kustutamiseks esitatud pildid',
	'ptwiki': '!Ficheiros para eliminação semirrápida|!Páginas para eliminação rápida',
	'ruwiki': 'Файлы:К удалению|Википедия:К быстрому удалению',
	'zhwiki': '文件删除候选|快速删除候选',
	// speedy
	'azwiki': 'Vikipediya:Silinəcək səhifələr',
	'cswiki': 'Stránky ke smazání',
	'dawiki': 'Sider der er foreslået slettet hurtigt',
	'eswiki': 'Wikipedia:Borrar \(definitivo\)',
	'fiwiki': 'Pikapoisto',
	'frwiki': 'Wikipédia:Suppression immédiate demandée',
	'huwiki': 'Azonnali törlésre váró lapok',
	'itwiki': 'Cancellare subito',
	'jawiki': '即時削除対象のページ',
	'nlwiki': 'Wikipedia:Nuweg',
	'plwiki': 'Ekspresowe kasowanie',
	'skwiki': 'Wikipédia:Kandidáti na rýchle zmazanie',
	'svwiki': 'Snabbraderingar',
	'trwiki': 'Vikipedi silinecek sayfalar',
	// small Wikipedias
	'kowiki': '삭제 신청 파일|삭제 신청 문서',
	'bswiki': 'Slike predložene za brisanje|Kandidati za brisanje',
	'eowiki': 'Forigendaj dosieroj|Tujforigendaj artikoloj',
	'mkwiki': 'Слики за бришење|Страници за брзо бришење',
	'ocwiki': 'Imatge prepausat a la supression',
	'sahwiki': 'Билэлэр:Соторго|Бикипиэдьийэ:Түргэнник соторго',
	'shwiki': 'Slike predložene za brisanje|Kandidati za brzo brisanje',
	'siwiki': 'මකාදැමීමට ඇති විකිපීඩියා ගොනු' + '|' + speedy,
	'tlwiki': 'Images and media for deletion|Mga pahinang mabilisang buburahin',
	'zh_yuewiki': '檔案刪除候選|即刻刪除候選'
};

if (project === "commonswiki") {
	localProbCats = seriousCatRe;
	superRe = supComRe;
	bCommons = {};
} else {
	localProbCats = localProbCats[project] || localProbCats[mw.config.get('wgContentLanguage') + 'wiki']; // fallback
	if (!localProbCats && $.inArray(mw.config.get('wgContentLanguage'), ['ab', 'ady', 'ak', 'ang', 'arc', 'as', 'av', 'bi', 'bo', 'bpy', 'br', 'bxr', 'ch', 'chr', 'chy', 'cr', 'dv', 'dz', 'ee', 'ff', 'fj', 'frp', 'gd', 'glk', 'gn', 'gom', 'got', 'ha', 'hak', 'haw', 'ie', 'ig', 'ik', 'kaa', 'kab', 'kg', 'ki', 'kn', 'koi', 'ks', 'lg', 'lij', 'ln', 'lo', 'lrc', 'ltg', 'mdf', 'mrj', 'myv', 'new', 'nov', 'nrm', 'ny', 'or', 'pag', 'pam', 'pcd', 'pih', 'rn', 'rw', 'sa', 'sco', 'sg', 'si', 'sm', 'sn', 'srn', 'ss', 'st', 'stq', 'te', 'ti', 'ts', 'tum', 'tw', 'ty', 'tyv', 'ug', 've', 'war', 'xal', 'xh', 'xmf', 'za', 'zu']) !== -1)
		localProbCats = speedy;
	localProbCats = localProbCats ? new RegExp('^(' + localProbCats + ')') : '';
}
// console.log("localProbCats2", localProbCats);

function check(cat, title, seriousCatRe, supRe) {
	c--;
	var cc = 0; // current cat counter;
	if (!cat || !title)
		return;
	// Erfolgreich. Ergebnis analysieren
	// console.log("json", title, c, file2links);
	for (var i = 0; i < cat.length; i++) {
		var caTi = cat[i].title.replace(/_/g, ' ');
		// console.log("d cat", d, cat[i].title, seriousCatRe, supRe);
		if (supRe && supRe.test(caTi)) {
			cc++;
			file2links[title].css({
				border: '2px dotted green'
			}).prop("title", RegExp.$1);
			// console.log("%s ist evtl. durch eine SVG ersetzbar.", title);
		}
		if (seriousCatRe.test(caTi)) {
			cc++;
			file2links[title].css({
				border: '5px dotted red'
			}).prop("title", RegExp.$1);
			// console.log("%s steht zur Löschung: %s", title, RegExp.$1);
			break;
		} else if (lesserCatRe.test(caTi)) {
			cc++;
			file2links[title].css({
				border: lesserMarker
			}).prop("title", RegExp.$1);
			// console.log("%s besteht ein Problem: %s", title, RegExp.$1);
		}
	}
	if (cc)
		r++;
	if (!c)
		portletLink.html(mw.msg("pe_file", r, a));
} // check()

function fault(f, uf) {
	console.log("API-Abfrage für %s hat nicht gefunzt.", f, uf);
} // fault()

//commons.wikimedia.org/w/api.php?action=query&format=json&prop=templates&list=&titles=File%3ASuperman-facebook.jpg&formatversion=latest
function getCOM(file) {
	// Löse eine Abfrage aus: Steht ein Bild auf Commons zur Löschung?
	// Category:Vector version available // could be usfull marked too
	// Category:Copyright violations$  // not needed
	// Template:Deletion template tag
	var api = new mw.ForeignApi('https://commons.wikimedia.org/w/api.php');
	api.getCategories(file).done(function (json) {
		check(json, file, seriousCatRe, supComRe);
	}).fail(function (fail) {
		fault(file, fail);
	});
} // getCOM()

function getWP(file) {
	// Steht ein Bild auf Wikipedia zur Löschung?
	new mw.Api().getCategories(file).done(function (json) {
		check(json, file, localProbCats, superRe);
	}).fail(function (fail) {
		fault(file, fail);
	});
} // getWP()

function run() {
	// var filePath = new RegExp('(?:' + mw.util.wikiUrlencode(mw.config.get('wgFormattedNamespaces')[6]) + '|File):(.*)$');
	portletLink.html(mw.msg("pe_search"));
	$('#mw-content-text').find("a[href]").not('.noviewer').has("img").each(function (i, o) {
		o = $(this).find('img');
		var title = mw.Title.newFromImg(o).toString();
		if (file2links[title]) return; // every file only once
		file2links[title] = o;
		if (/^\/\/upload\.wikimedia\.org\/wikipedia\/commons/.test(o.attr('src'))) {
			files.push(title);
		} else {
			l_files.push(title);
			file2links[title].css(bCommons); /* Mark local images */
		}
		c++;
	});
	//console.log(files.length, l_files.length);
	if (!files.length && !l_files.length) {
		return portletLink.html(mw.msg("pe_nofile"));
	}
	for (var i = 0; i < files.length; i++) {
		getCOM(files[i]);
	}
	if (localProbCats) // only if we have some to check
		for (i = 0; i < l_files.length; i++) {
			getWP(l_files[i]);
		}
	else
		c -= l_files.length;
	a = c;
}

function init(e) {
	initL10N(l10n);
	mw.loader.using(["mediawiki.api", "mediawiki.util", "mediawiki.Title"], function () {
		portletLink = $(mw.util.addPortletLink('p-tb', '#', mw.msg("pe_link"), 't-problemImages')).find('a').css('background','#ffa');
		portletLink.on('click', function () {
			run();
			return false;
		});
		if (e)
			$(portletLink.click());
	});
}
if (mw.config.get('wgAction') === 'view' && mw.config.get('wgPageContentModel') === 'wikitext' && ns !== -1)
	mw.loader.using(["mediawiki.ForeignApi", "mediawiki.api.category", "mediawiki.language", "mediawiki.jqueryMsg"], function () {
		var e = window.autoFileCheck || false; // Run automatic on articles?
		if (ns)
			e = false;
		return init(e);
	});
}(jQuery, mediaWiki));
// EOF </nowiki>