Jump to content

User:Evad37/EditWarChecker.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/* jshint esversion: 5, laxbreak: true, undef: true, eqnull: true, maxerr: 999 */
/* globals console, window, $, mw */
$.when(
    mw.loader.using([ "mediawiki.api"]),
    $.ready
).then(function() {

	var config = mw.config.get(['wgPageName', 'wgArticleId', 'wgNamespaceNumber']);
	if (config.wgNamespaceNumber !== 0 || config.wgArticleId === 0) {
		return;
	}

	var minMax = function(number, min, max) {
		if (number < min) {
			return min;
		} else if (number > max) {
			return max;
		}
		return number;
	};

	config.hours = minMax(window.EWC_hours || 24, 2, 72);
		
	var api = new mw.Api({
		ajax: {
			headers: { 
				"Api-User-Agent": "EditWarChecker ( https://en.wikipedia.org/wiki/User:Evad37/EditWarChecker )"
			}
		}
	});
	
	api.get({
		"action": "query",
		"format": "json",
		"prop": "revisions",
		"titles": config.wgPageName,
		"rvprop": "ids|timestamp|flags|comment|user|tags|size",
		"rvslots": "*",
		"rvlimit": "max",
		"rvend": new Date(Date.now() - config.hours*60*60*1000).toISOString()
	})
	.then(function(response) {
	    var revertUsers = {};
	    var maxUserReverts = 0;
	    function addRevert(user) {
	        if (revertUsers[user]) {
	            revertUsers[user] = revertUsers[user]++;
	        } else {
	            revertUsers[user] = 1;
	        }
	        if (revertUsers[user] > maxUserReverts) {
	            maxUserReverts = revertUsers[user] ;
	        }
	    }
	    var reverts = (response.query.pages[config.wgArticleId].revisions || [])
	        .filter(function(revision, index, arr) {
	            // Edits tagged by system
	            if (revision.tags.includes("mw-undo") || revision.tags.includes("mw-rollback")) {
	                addRevert(revision.user);
	                return true;
	            }
	            // Edits with undo/revert comment
	            if (/(?:undo|undid|revert)/i.test(revision.comment)) {
	                addRevert(revision.user);
	                return true;
	            }
	            // Edits with same kB change but opposite signs
	            var thisEditDiffSize = revision.size - (arr[index+1] ? arr[index+1].size : NaN);
	            var prevEditDiffSize = (arr[index+1] ? arr[index+1].size : NaN) - (arr[index+2] ? arr[index+2].size : NaN);
	            var minDiffSize = 10; // prevent false positives from minor copyedits
	            if (thisEditDiffSize && prevEditDiffSize && thisEditDiffSize > minDiffSize && thisEditDiffSize === prevEditDiffSize * -1) {
	                addRevert(revision.user);
	                return true;
	            }
	            
	            return false;
	        });
	    
	    var revertCount = reverts.length;
	    var revertUsersCount = Object.keys(revertUsers).length;
	    var usersToList = $.map(revertUsers, function(reverts, user) {
	        return reverts > 3 ? user + " (" + reverts + ")" : null;
	    }).join(", ");
	    
	    var message = "Approximately " + revertCount +
	        (revertCount===1
	            ? " revert"
	            : " reversions"
	        ) +
	        (revertUsersCount>0
	            ? " by " + revertUsersCount +
	                (revertUsersCount===1
	                    ? " user"
	                    : " users"
	                )
	            : ""
	        ) +
	        " in the last " + config.hours + " hours." + 
	        (usersToList
	            ? "\nUsers with 4+ reverts: " + usersToList
	            : ""
	        );
	    
	    var $symbol = $("<img width='20' height='20' style='float:right;cursor:pointer;' title='Edit war checker'>");
	
	    switch(true) {
	        // Grey (non-alert): No reverts, or single revert
	        case revertCount <= 1:
	            $symbol.attr("src", "https://upload.wikimedia.org/wikipedia/commons/e/e1/ButtonGray.svg");
	            break;
	        // Green alert: Everyone well within 3RR; not too many total reverts
	        case maxUserReverts <= 2 && revertCount <= 5:
	            $symbol.attr("src", "https://upload.wikimedia.org/wikipedia/commons/3/3c/ButtonGreen.svg");
	            break;
	        // Orange alert: One or more users at the 3RR limit; and/or quite a few reverts
	        case maxUserReverts <= 3 && revertCount <= 10:
	            $symbol.attr("src", "https://upload.wikimedia.org/wikipedia/commons/a/a6/ButtonOrange.svg");
	            break;
	        // Red alert: One or more users are passed the 3RR limit; and/or there are a lot of reverts
	        default:
	            $symbol.attr("src", "https://upload.wikimedia.org/wikipedia/commons/9/97/ButtonRed.svg");
	            break;
	    }
	
	    $symbol.click(function() {
	        mw.notify( message, { title: "Edit war checker", tag: "editWarCheck" } ); 
	    });
	
	    $('h1').append($symbol);
	
	})
	.catch(function(code, errorInfo) {
		console.error("EditWarChecker error", errorInfo || code || "Unknown error");
		var message = errorInfo && errorInfo.info || code.toString() || "Unknown error";
		mw.notify(message, {title: "EditWarChecker failed to load"});
	});
});