User:Void/findInactiveSysops.js

From TestWiki
Revision as of 00:22, 8 May 2020 by Void (talk | contribs) (add shiny new interface)

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.
//<nowiki>
//This script automates the process of finding inactive sysops.
//Warning: the script will replace the contents of the page you are currently viewing when you click the link at the top right of the page.
//Output is in the format of "[[User:Example|Example]] || [[Special:PermanentLink/1234|timestamp]] || [[Special:Log/Example|timestamp]]"
mw.loader.using(['oojs-ui', 'mediawiki.util']).done( function () {

var scriptActivationLink = mw.util.addPortletLink(
    'p-tb',
    '#',
    'Find Inactive Sysops',
    'pt-testscript',
    'Replaces the contents of the current page with a list of inactive sysops',
    null,
    '#pt-adminlinks'
);

$( scriptActivationLink ).click( function () {
	var progressBar = new OO.ui.ProgressBarWidget();
	var progressField = new OO.ui.FieldLayout(
		progressBar,
		{
			label: "Fetching users...",
			align: 'top'
		}
	);
	var textPanel = new OO.ui.PanelLayout( {
		expanded: false,
		framed: false,
		padded: false,
	} );
	var canSave = false;
	
	function InactiveUsersProc( config ) {
		InactiveUsersProc.super.call( this, config );
	}
	OO.inheritClass( InactiveUsersProc, OO.ui.ProcessDialog );
	InactiveUsersProc.static.name = "Inactive Users Process";
	InactiveUsersProc.static.title = "List of Inactive Users:";
	InactiveUsersProc.static.actions = [
		{
			action: "save",
			label: "Update",
			flags: "primary"
		},
		{
			label: "Cancel",
			flags: "safe"
		}
	];
	
	InactiveUsersProc.prototype.initialize = function() {
		InactiveUsersProc.super.prototype.initialize.apply( this, arguments );
		this.content = new OO.ui.FieldsetLayout();
		this.content.addItems([ progressField ]);
		this.content.$element.css( 'padding', '1em' );
		this.$body.append( this.content.$element );
	};
	
	InactiveUsersProc.prototype.getActionProcess = function( action ) {
		var dialog = this;
		if( action && canSave ) {
			return new OO.ui.Process( function() {
				if( action == "save" ) {
					updList();
				}
				dialog.close( { action: action } );
			});
		}
		return InactiveUsersProc.super.prototype.getActionProcess.call( this, action );
	};
	
	InactiveUsersProc.prototype.getBodyHeight = function() {
		return this.content.$element.outerHeight( true );
	};
	
	var windowManager = new OO.ui.WindowManager();
	var inactiveUsersProc = new InactiveUsersProc( {
		size: "large"
	} );
	windowManager.addWindows([ inactiveUsersProc ]);
	$('#bodyContent').append(windowManager.$element);
	windowManager.openWindow(inactiveUsersProc);
	var checked = 0;
	var inactive = [];
	
	$.getJSON(
		//Get userlist
        mw.util.wikiScript( 'api' ),
        {
            format: 'json',
            action: 'query',
            list: 'allusers',
            augroup: 'bot|sysop|bureaucrat|consul|autopatrolled|rollbacker|interface-admin|flow-bot',
            aulimit: 150, //Unlikely to be more than 150 privilged users
        }
    ).done( function ( data ) {
        try {
        	var users = data.query.allusers;
        	var userlist = [];
        	users.forEach( function( object ) {
        		userlist.push( object.name );
        	});
        	filterUsers( userlist );
        }
    	catch ( e ) {
        	console.log( "Content request error: " + e.message );
        	console.log( "Content request response: " + JSON.stringify( data ) );
    	}
	} ).fail( function () {
    	console.log( "While getting the userlist, there was an AJAX error." );
	} );
	
	function filterUsers ( userlist ) {
		var userstring = userlist.toString();
		var exempt = ["John", "Void", "NDKilla", "Reception123", "Revi", "Southparkfan", "Abuse filter", "Void-bot", "Voidwalker", "Paladox", "Zppix", "ZppixBot", "RhinosF1", "MediaWiki message delivery", "ZI Jony", "Bonnedav", "Babel AutoCreate", "HeartsDo"];
		for ( i = 0; i < exempt.length; i++ ) {
			userstring = userstring.replace( exempt[i] + ",", "" );
		}
		var reducedList = userstring.split( "," );
		for ( x = 0; x < reducedList.length; x++ ) {
			checkUser( reducedList[x], reducedList.length );
		}
	}
	
	function checkUser( user, total ) {
		$.getJSON(
	        mw.util.wikiScript( 'api' ),
	        {
	            format: 'json',
	            action: 'query',
	            list: 'logevents|usercontribs',
	            leprop: 'timestamp',
	            ledir: 'older',
	            leuser: user,
	            lelimit: 1, //We only need the most recent log action/edit
	            uclimit: 1,
	            ucuser: user,
	            ucdir: 'older',
	            ucprop: 'timestamp|ids'
	        }
	    ).done( function ( data ) {
	        try {
	        	var tribsData = data.query.usercontribs;
	        	var logsData = data.query.logevents;
	           	var activeLogs, activeTribs, active;
	           	var tribsInfo;
	
	           	if( typeof( logsData[0].timestamp ) != "undefined" ) {
	           		activeLogs = compareDates( logsData[0].timestamp, "logs" );
	           	}
	           	else {
	           		activeLogs = false;
	           	}
	           	if( typeof( tribsData[0] ) != "undefined" ) {
	           		tribsInfo = tribsData[0].revid + "|" + tribsData[0].timestamp;
	           		activeTribs = compareDates( tribsInfo, "tribs" );
	           	}
	           	else {
	           		activeTribs = false;
	           	}
	           	if( activeLogs === false && activeTribs === false ) {
	           		inactive.push([user, tribsData, logsData]);
	           	}
	           	checked++;
	           	progressBar.setProgress( parseInt(checked / total) * 100 );
	           	if( checked == total ) {
	           		listInactiveUsers();
	           	}
	        }
	    	catch ( e ) {
	        	console.log( "Content request error: " + e.message );
	        	console.log( "Content request response: " + JSON.stringify( data ) );
	    	}
	    } );
	}
	
	function compareDates ( data, dataType ) {
		//Gets current date in yyyymmdd
		var today = new Date();
		var dd = today.getDate();
		var mm = today.getMonth() + 1; //January is 0!
		var yyyy = today.getFullYear();
		//Set back 3 months
		mm -= 3;
		if( mm < 0 ) {
			mm += 12;
			yyyy -= 1;
		}
		
		if( dd < 10 ) {
	    	dd = '0' + dd;
		} 
	
		if( mm<10 ) {
		    mm = '0' + mm;
		} 
		today = '' + yyyy + mm + dd; //This is a string
	
		var date;
		var isActive;
		if( dataType === "logs" ) {
			date = data.slice( 0, data.indexOf('T') );
			date = date.replace( "-", "" );
		}
		else if( dataType === "tribs" ) {
			date = data.slice( data.indexOf('|') + 1, data.indexOf('T') );
			date = date.replace( "-", "" );
		}
		if ( date < today ) {
			isActive = false;
		}
		else {
			isActive = true;
		}
		return isActive;
	}
	
	function listInactiveUsers() {
		sorted = inactive.sort( function( a, b ) {
			return a[0].localeCompare( b[0] );
		} );
		for( var i in sorted ) {
			var userName = sorted[i][0];
			var tribsArray = sorted[i][1];
			var logsArray = sorted[i][2];
			var userLink = "[[User:<a href=\"https://publictestwiki.com/wiki/Special:Contribs/" + userName + "\">" + userName + "</a>|" + userName + "]]";
			var tribsInfo;
			if( tribsArray[0] !== undefined ) {
				tribsInfo = tribsArray[0].timestamp;
				tribsInfo = tribsInfo.slice( 0, tribsInfo.indexOf("T") );
				tribsInfo = tribsArray[0].revid + "|" + tribsInfo;
				tribsInfo = "[[Special:PermanentLink/" + tribsInfo + "]]";
			}
			else {
				tribsInfo = 'None';
			}
			var logsInfo = logsArray[0].timestamp;
			logsInfo = logsInfo.slice( 0, logsInfo.indexOf("T") );
			logsInfo = "[[Special:Log/" + userName + "|" + logsInfo + "]]";
			textPanel.$element.append( "<li>" + userLink + " || " + tribsInfo + " || " + logsInfo + "</li>" );
		}
		inactiveUsersProc.content.clearItems();
		inactiveUsersProc.content.addItems([textPanel]);
		inactiveUsersProc.updateSize();
		canSave = true;
	}
	
	function updList() {
		var list = textPanel.$element[0].innerText;
		list = '|-\n|' + list;
		while( list.indexOf("\n[[User:") > 0 ) {
			list = list.substr( 0, list.indexOf( "\n[[User:" ) ) + '\n|-\n|' + list.substr( list.indexOf( "\n[[User:" ) + 1 );
		}
		$.getJSON(
			mw.util.wikiScript( 'api' ),
	        {
	            format: 'json',
	            action: 'query',
	            pageids: 238,
	            prop: 'revisions',
	            rvprop: 'content'
	        }
	    ).done( function ( data ) {
	        try {
	           	var wtext = data.query.pages[238].revisions[0]['*'];
	           	wtext = wtext.substr( 0, wtext.indexOf("|-") ) + list + '\n' + wtext.substr( wtext.indexOf( "|}" ) );
	           	$.ajax( {
	       			url: mw.util.wikiScript( 'api' ),
			        type: 'POST',
			        dataType: 'json',
			        data: {
			            format: 'json',
			            action: 'edit',
			            title: 'TestWiki:Inactivity/Inactive administrators',
			            text: wtext,
			            summary: '[[User:Void/findInactiveSysops.js|Automatically]] updating list',
			            token: mw.user.tokens.get( 'csrfToken' ),
			        }
	   			} ).done( function() {
	   				alert( "Updated TestWiki:Inactivity/Inactive administrators" );
	   				var reload = new OO.ui.ButtonWidget( { label: 'Load original page' } );
	   				$('#upd-inactive-bttn').replaceWith( reload.$element.click( function() { window.location.reload(); } ) );
	   			} ).fail( function ( e, data ) {
	   				console.log( e.message );
	   				console.log( JSON.stringify( data ) );
	   			} );
	        }
	        catch( e ) {
	          	// ignore
	        }
	    } ).fail( function ( e, data ) {
	    	console.log( e.message );
	    	console.log( JSON.stringify( data ) );
	    } );
	}
} );

});
//</nowiki>