User:Glaisher/countCUStats.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.
/**
 * Parses Special:CheckUserLog to count the number of times a steward has used
 * CheckUser on a given wiki.
 * 
 * This script allows to count the number of times a steward has used CheckUser on a wiki.
 * It was written in response in to [[Talk:Stewards/CheckUser_statistics_for_loginwiki#Update_required]]
 * but can be used for other wikis too.
 *
 * To run the script, change the month as needed (see queryCheckUserLog() function) and run
 * it on your browser console on Special:BlankPage.
 *
 * Caveats:
 *  - Only *current stewards* are counted. Previous stewards' stats have to be counted manually.
 *  - It assumes that the number of CUs per steward is maximum 4000 (can be easily changed if needed).
 *  - It assumes that the maximum number of stewards is 150 (also changeable)
 * 
 * Original author
 * @author Glaisher <https://meta.wikimedia.org/wiki/User:Glaisher>
 * @link https://meta.wikimedia.org?oldid=15206551
 * 
 * Fixes on July 2019
 * @author Kunal Mehta <https://meta.wikimedia.org/wiki/User:Legoktm>
 * @author Scott Bassett <https://meta.wikimedia.org/wiki/User:SBassett_(WMF)>
 * 
 */

var api = new mw.Api();

function getStewards() {
	return api.get( {
		format: 'json',
		action: 'query',
		list: 'globalallusers',
		agugroup: 'steward',
		agulimit: 150 // We probably won't have stewards more than this anytime soon
	} );
}

function queryCheckUserLog( username ) {
	return api.get( {
		format: 'json',
		list: 'checkuserlog',
		culuser: username,
		cullimit: 4000, // Hopefully no one has to do more than this in a month.
		culdir: 'newer',
		// Please don't change the format unless you know what you're doing or it might break
		culfrom: new Date( '1 January 2019 UTC' ).toISOString(), // Start date
		culto: new Date( '1 February 2019 UTC' ).toISOString() // End date
	} );
}

function appendToPage( text ) {
	// Note: text must be trusted!
	$( '#mw-content-text' ).append( text + '<br/>' );
}

function getStatsTable( entries ) {
	var html =
        '<table class="wikitable sortable">\n'
        + '<tr>'
        + '<th> Username </th>'
        + '<th> Count </th>'
        + '</tr>\n';

    $.each( entries, function( i, entry ) {
    	var name = (typeof entry.name == "string") ? entry.name : JSON.stringify(entry.name);
        var count = (typeof entry.count == "string") ? parseInt(entry.count).toString() :
            (typeof entry.count == "number") ? entry.count.toString() : JSON.stringify(entry.count);
    	
        html += '<tr>'
            + '<td>' + mw.html.escape( name ) + '</td>'
            + '<td>' + mw.html.escape( count ) + '</td>'
            + '</tr>\n';
    } );

    html += '</table>';

    return html;
}

function init() {
	getStewards().done( function( data ) {
		var stewards = data.query.globalallusers,
		    stewardCount = stewards.length,
		    totalCount = 0,
		    stats = [];
		    promises = []; // promise for all query api requests

		appendToPage( '<span id="cu-status">Querying... Please wait.</span>' );
		var $status = $( '#cu-status' );

        $.each( stewards, function( i, info ) {
            var username = info.name;
            var queryPromise = queryCheckUserLog( username );
            promises.push( queryPromise );
            queryPromise.done( function( data ) {
                if ( !data.query ) {
                    onError( data );
                }

                var cuCount = data.query.checkuserlog.entries.length;
                stats.push( {
                    name: username,
                    count: cuCount
                } );
                totalCount += cuCount;

            } ).fail( function( data ) {
                onError( data );
            } );

            function onError( data ) {
                $status.text( 'Error occured in querying.' );
                throw 'Error while querying ' + mw.html.escape( username ) + ' details: ' + JSON.stringify( data );
            }

        } );

        $.when.apply( $, promises ).done( function() {
            // Output table once we've the all stats data needed
            $status.text( 'Total: ' + totalCount);
            appendToPage( getStatsTable( stats ) );
            mw.loader.using( 'jquery.tablesorter', function() {
                $( 'table' ).tablesorter();
            } );
        });

	} );
}

init();