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.

//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 /info/en/?search=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.usercontribsi];

			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.logeventsentry];

		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.usercontribsi];

			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);

})});