//Mass rollback with extra tools
//Written by Bellezzasolo based on User:Writ Keeper/Scripts/massRollback.js
//Written by John254 and modified/rewritten by Writ Keeper with modifications by TheDJ; original is at https://en.wikipedia.org/wiki/User:John ... ollback.js
//Adapted from User:Mr.Z-man/rollbackSummary.js
//Instructions: Selecting the "Nuke" option under Twinkle when viewing a user's contributions history
//will revert all contributions within a specified timeframe
//Also provides admin tools like revdel and [[Special:Nuke]]
var Nuke = {};
const RESCAN_PERIOD = 25; //Milliseconds
Nuke.nuke = function()
{
return new Promise(function(resolve, reject){
mw.loader.using(['mediawiki.api', 'mediawiki.util', 'mediawiki.api.rollback']).then(function()
{
var api = new mw.Api({ajax: {
headers: { 'Api-User-Agent': 'Nuke/Bellezzasolo/0.9.0' }
}});
Nuke.api = api;
resolve();
});
});
};
Nuke.promise = Nuke.nuke();
Nuke.rollback = function (title, username, summary) {
var rollbackQuery = {
action: "rollback",
title: title,
user: username,
reason: summary
};
console.log("Edit summary: " + summary);
if(summary !== "")
{
rollbackQuery = $.extend(rollbackQuery, { reason: summary});
}
Nuke.api.postWithToken('rollback', rollbackQuery).then(function(e){}, function(e){mw.notify("Rollback on " + title + " failed");});
};
Nuke.rollbackPast = function (editSummary, revdel, starttime)
{
if(editSummary === null)
{
return false;
}
var uccontinue = null;
var query = {
action: "query",
list: "usercontribs",
uclimit: "100",
ucuser: mw.config.get("wgRelevantUserName"),
ucprop:"title|ids",
ucshow:"top",
ucend:starttime
};
var handlerfunc = function(apiobj)
{
for (var i = 0; i < apiobj.query.usercontribs.length; i++) {
var contrib = apiobj.query.usercontribs[i];
Nuke.rollback(contrib.title, mw.config.get("wgRelevantUserName"), editSummary);
}
if(!('batchcomplete' in apiobj))
{
var contquery = $.extend(query, { uccontinue: apiobj.continue.uccontinue});
Nuke.api.get(contquery).then(handlerfunc);
}
};
Nuke.api.get(query).then(handlerfunc);
if(revdel)
{
Nuke.revdelpast(starttime);
}
};
Nuke.adminnuke = function (logcomment) {
var query = {
action: 'query',
list: 'logevents',
letype: 'create',
leprop: 'ids',
lelimit: 500,
leuser: mw.config.get('wgRelevantUserName')
};
Nuke.api.get(query).then(Nuke.adminnuke.callback);
};
Nuke.adminnuke.callback = function (apiobj) {
for (var entry in apiobj.query.logevents)
{
var creation = apiobj.query.logevents[entry];
var deletionQuery = {
action: "delete",
pageid: creation.pageid,
reason: Twinkle.nuke.editsummary
};
Nuke.api.postWithEditToken(deletionQuery);
}
};
Nuke.revdel = function (revision) {
var deletionQuery = {
action: "revisiondelete",
type: "revision",
ids: revision,
hide: "content|comment|user",
reason: Twinkle.nuke.editsummary
};
Nuke.api.postWithEditToken(deletionQuery);
};
Nuke.revdelpast = function (starttime) {
var uccontinue = null;
var query = {
action: "query",
list: "usercontribs",
uclimit: "100",
ucuser: mw.config.get("wgRelevantUserName"),
ucend: starttime,
ucprop:"title|ids"
};
var handlerfunc = function(apiobj)
{
for (var i = 0; i < apiobj.query.usercontribs.length; i++) {
var contrib = apiobj.query.usercontribs[i];
Nuke.revdel(contrib.revid);
}
if(!('batchcomplete' in apiobj))
{
var contquery = $.extend(query, { uccontinue: apiobj.continue.uccontinue});
Nuke.api.get(contquery).then(handlerfunc);
}
};
Nuke.api.get(query).then(handlerfunc);
};
//Twinkle dependent code
mw.loader.using(['ext.gadget.Twinkle', 'mediawiki.api']).then(function(){
Nuke.promise.then(function(){
(function($){
Twinkle.nuke = function() {
if ( !mw.config.get('wgRelevantUserName') ) {
return;
}
Twinkle.addPortletLink( Twinkle.nuke.callback, "Nuke", "cont-nuke", "Contributions reverter" );
};
Twinkle.nuke.callback = function( ) {
if( mw.config.get('wgRelevantUserName') === mw.config.get("wgUserName") && !confirm("Is it really so bad that you're nuking yourself?") ){
return;
}
var Window = new Morebits.simpleWindow( 600, 350 );
//Ugly hack to disable scrollbar
$(Window.content).css('overflow-x', 'hidden');
Window.setTitle("Contributions Nuke");
Window.setScriptName("Twinkle+");
Window.addFooterLink( "Nuke help", "User:Bellezzasolo/Scripts/nuke" );
Window.addFooterLink( "Rollback policy", "WP:Rollback" );
Window.addFooterLink( '\u2230Bellezzasolo\u2721', "User talk:Bellezzasolo" );
var form = new Morebits.quickForm( Twinkle.nuke.callback.evaluate );
//Now display the options
var actionfield = form.append({ type: "field", label:"Nuke Options"});
var nukeoptions = [{checked: true, label: 'Revert past contributions', name: 'pastrevert', value: '1'}];
//If the user is an administrator, show blocking options. Also, if the user is me, because I have to test this!
if ( Morebits.userIsInGroup('sysop') || mw.config.get("wgUserName") == "Bellezzasolo")
{
actionfield.append({
type: "button", label: "Block",
event: Twinkle.block.callback
});
nukeoptions.push({checked: false, label: 'Delete created pages (NUKE)', name: 'adminnuke', value: '1'});
nukeoptions.push({checked: false, label: 'RevisionDelete user\'s edits', name: 'revdelconts', value: '1'});
}
actionfield.append({
type: 'checkbox',
name: 'nukeoptions',
list: nukeoptions
});
actionfield.append({
type: "input", label: "Start time",
name: 'starttime',
tooltip: 'Absolute timestamps, "yyyymmddhhmm" (e.g. "200602011405" is Feb 1, 2006, at 14:05 UTC).'
});
actionfield.append({
type: 'input',
name: 'editsummary',
label: 'Edit Summary',
tooltip: 'Optional edit summary for reversions',
value: Twinkle.nuke.editsummary
});
form.append({ type: "submit", label:"Nuke User" });
var result = form.render();
Window.setContent( result );
Window.display();
result.root = result;
};
Twinkle.nuke.callback.evaluate = function( e ) {
var nukePast = e.target.getChecked("pastrevert")[0];
var adminNuke = e.target.getChecked("adminnuke")[0];
var revdel = e.target.getChecked("revdelconts")[0];
var starttime = e.target.starttime.value;
Twinkle.nuke.editsummary = e.target.editsummary.value;
if (nukePast == 1)
{
Nuke.rollbackPast(Twinkle.nuke.editsummary, revdel, starttime);
}
if(adminNuke == 1)
{
Nuke.adminnuke(Twinkle.nuke.editsummary);
}
};
if (Morebits.userIsInGroup('rollbacker'))
{
Twinkle.nuke();
}
else
{
mw.notify("You must have rollback privileges to use Nuke");
}
})(jQuery);
})});