Jump to content

User:Gary/userinfo.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.
// Original: [[User:PleaseStand/userinfo.js]]

if (typeof(unsafeWindow) != 'undefined')
{
	var console = unsafeWindow.console;
	var mw = unsafeWindow.mw;
}

function UserinfoJsParseDate(utcDate) {
    // The ISO 8601 date format used by MediaWiki
    var s = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/.exec(utcDate);
    if(s === null) {
        return null;
    }
    var d = new Date();
    d.setUTCFullYear(s[1], s[2] - 1, s[3]);
    d.setUTCHours(s[4], s[5], s[6]);
    return d;
}

function UserinfoJsValidateIp(ip) {
    var ipSplit = ip.split(".");
    if(ipSplit.length != 4) {
        return false;
    }
    if($.map(ipSplit, function(s){return parseInt(s,10);}).join(".") != ip) {
        return false;
    }
    return true;
}

function UserinfoJsFormatQty(qty, singular, plural) {
    return String(qty).replace(/\d{1,3}(?=(\d{3})+(?!\d))/g, "$&,") + "\u00a0" + (qty == 1 ? singular : plural);
}

function UserinfoJsFormatDateRel(old) {
// The code below requires the computer's clock to be set correctly.
            var age = new Date().getTime() - old.getTime();
            var ageNumber, ageRemainder, ageWords;
            if(age < 60000) {
                // less than one minute old
                ageNumber = Math.floor(age / 1000);
                ageWords = UserinfoJsFormatQty(ageNumber, "second", "seconds");
            } else if(age < 3600000) {
                // less than one hour old
                ageNumber = Math.floor(age / 60000);
                ageWords = UserinfoJsFormatQty(ageNumber, "minute", "minutes");
            } else if(age < 86400000) {
                // less than one day old
                ageNumber = Math.floor(age / 3600000);
                ageWords = UserinfoJsFormatQty(ageNumber, "hour", "hours");
                ageRemainder = Math.floor((age - ageNumber * 3600000) / 60000);
            } else if(age < 604800000) {
                // less than one week old
                ageNumber = Math.floor(age / 86400000);
                ageWords = UserinfoJsFormatQty(ageNumber, "day", "days");
            } else if(age < 2592000000) {
                // less than one month old
                ageNumber = Math.floor(age / 604800000);
                ageWords = UserinfoJsFormatQty(ageNumber, "week", "weeks");
            } else if(age < 31536000000) {
                // less than one year old
                ageNumber = Math.floor(age / 2592000000);
                ageWords = UserinfoJsFormatQty(ageNumber, "month", "months");
            } else {
                // one year or older
                ageNumber = Math.floor(age / 31536000000);
                ageWords = UserinfoJsFormatQty(ageNumber, "year", "years");
                ageRemainder =
                    Math.floor((age - ageNumber * 31536000000) / 2592000000);
                if(ageRemainder) {
                    ageWords += " " +
                        UserinfoJsFormatQty(ageRemainder, "month", "months");
                }
           }
           return ageWords;
}

// If on a user or user talk page, and not a subpage...
if (mw.config.get('wgCanonicalNamespace') == 'User' || mw.config.get('wgCanonicalNamespace') == 'User_talk' || mw.config.get('wgCanonicalSpecialPageName') == 'Contributions')
	$(userInfoScript);

function userInfoScript()
{
    // Request the user's information from the API.
    // Note that this is allowed to be up to 5 minutes old.
    
    // But if the user is an IP, do not look up. --PS 2010-05-16
    // Commented out to allow "last edit" lookups --PS 2010-06-27
    /* if(UserinfoJsValidateIp(mw.config.get('wgTitle'))) {
        // Code copied from bottom of callback function --PS 2010-05-16
        var fh = window.document.getElementById("firstHeading");
        var stDiv = window.document.createElement("div");
        stDiv.innerHTML = "An anonymous user";
        fh.parentNode.insertBefore(stDiv, fh.nextSibling);
        return;
    } */
    
    var et = mw.config.get('wgTitle');
	
	if (mw.config.get('wgCanonicalSpecialPageName') == 'Contributions') et = $('#contentSub').children().eq(0).text();
	else et = et.split('/')[0];
	
	$.get(mw.config.get('wgScriptPath') + '/api.php', { format: 'json', maxage: 300, action: 'query', list: 'users|usercontribs', usprop: 'blockinfo|editcount|gender|registration|groups', uclimit: 1, ucprop: 'timestamp', ususers: et, ucuser: et }, showUserInfo);
}

function showUserInfo(query)
{
	if (!query) return false;
	var query = query.query;
	
    var user, invalid, missing, groups, editcount, registration, blocked, gender, lastEdited;
    try 
	{
        user = query.users[0];
        invalid = typeof user.invalid != "undefined";
        missing = typeof user.missing != "undefined";
        groups = (typeof user.groups == "object") ? user.groups : [];
        editcount = (typeof user.editcount == "number") ? user.editcount : null;
        registration = (typeof user.registration == "string") ?
            UserinfoJsParseDate(user.registration) : null;
        blocked = typeof user.blockedby != "undefined";
        gender = (typeof user.gender == "string") ? user.gender : null;
        lastEdited = (typeof query.usercontribs[0] == "object") &&
            (typeof query.usercontribs[0].timestamp == "string") ?
            UserinfoJsParseDate(query.usercontribs[0].timestamp) : null;
    } 
	catch (e)
	{
        return false; // Not much to do if the server is returning an error (e.g. if the username is malformed).
    }

    // Format the information for on-screen display
    
    var statusText = "";
    var ipUser = false;

    // User status
    if(blocked) {
        statusText += "<a href=\"" + mw.config.get('wgScriptPath') +
            "/index.php?title=Special:Log&amp;page=" + 
            encodeURIComponent(mw.config.get('wgFormattedNamespaces')[2] + ":" + user.name) +
            "&amp;type=block\">blocked</a> ";
    }
    if (missing) {
        statusText += "username not registered";
    } else if (invalid) {
        statusText += (ipUser = UserinfoJsValidateIp(user.name)) ? "anonymous user" : "invalid username";
    } else {
        // User is registered and may be in a privileged group. Below we have a list of user groups.
        // Only need the ones different from the software's name (or ones to exclude), though.
        var friendlyGroupNames = {
            // Exclude implicit user group information provided by MW 1.17 --PS 2010-02-17
            '*': false,
            'user': false,
            'autoconfirmed': false,
            sysop: "administrator",
            accountcreator: "account creator",
            "import": "importer",
            transwiki: "transwiki importer",
            "ipblock-exempt": "IP block exemption",
            oversight: "oversighter",
            confirmed: "confirmed user",
            abusefilter: "edit filter manager",
            autoreviewer: "autopatrolled user" // Group has been renamed --PS 2010-07-06
        };
        
        
        var friendlyGroups = [];
        for(var i = 0; i < groups.length; ++i) {
            var s = groups[i];
            if(friendlyGroupNames.hasOwnProperty(s)) {
                if(friendlyGroupNames[s]) {
                    friendlyGroups.push(friendlyGroupNames[s]);
                }
            } else {
                friendlyGroups.push(s);
            }
        }
        switch(friendlyGroups.length) {
            case 0:
                // User not in a privileged group
                // Changed to "registered user" by request of [[User:Svanslyck]]
                // --PS 2010-05-16
                
                // statusText += "user";
                if(blocked) {
                    statusText += "user";
                } else {
                    statusText += "registered user";
                }
                break;
            case 1:
                statusText += friendlyGroups[0];
                break;
            case 2:
                statusText += friendlyGroups[0] + " and " + friendlyGroups[1];
                break;
            default:
                statusText += friendlyGroups.slice(0, -1).join(", ") +
                    ", and " + friendlyGroups[friendlyGroups.length - 1];
                break;
        }
    }
        
    // Registration date
    if(registration) {
        statusText += ", " + UserinfoJsFormatDateRel(registration) + " old";
    }
    
    // Edit count
    if (editcount !== null)
	{
        statusText += ", with " + "<a href=\"http://toolserver.org/~tparis/count/index.php?lang=en&wiki=wikipedia&name=" + encodeURIComponent(user.name) + "\">" + UserinfoJsFormatQty(editcount, "edit", "edits") + "</a>";
    }
    
    // Prefix status text with correct article
    if("AEIOaeio".indexOf(statusText.charAt(0)) >= 0) {
        statusText = "An " + statusText;
    } else {
        statusText = "A " + statusText;
    }

    // Add full stop to status text
    statusText += ".";

    // Last edited --PS 2010-06-27
    // Added link to contributions page --PS 2010-07-03
    if(lastEdited) {
        statusText += " Last edited <a href=\"" + mw.config.get('wgArticlePath').replace("$1", "Special:Contributions/" + encodeURIComponent(user.name)) + "\">" + UserinfoJsFormatDateRel(lastEdited) + " ago</a>.";
    }

    // Show the correct gender symbol
	var firstHeading = $('#firstHeading');
	var section0 = $('#section-0');
	
	if (firstHeading.length) var fh = firstHeading;
	else var fh = section0;

    // Add classes for blocked, registered, and anonymous users
    var newClasses = [];
    if(blocked) {
        newClasses.push("ps-blocked");
    }
    if(ipUser) {
        newClasses.push("ps-anonymous");
    } else if(invalid) {
        newClasses.push("ps-invalid");
    } else {
        newClasses.push("ps-registered");
    }
    fh.addClass($.map(groups, function(s) {
        return "ps-group-" + s;
    }).concat(newClasses).join(" "));

	var genderSpan = $('<span id="ps-gender-' + (gender || 'unknown') + '" style="font-family: Lucida Grande, Lucida Sans Unicode, sans-serif; font-size: 75%; padding-left: 0.25em;"></span>');
    var genderSymbol;
    switch(gender) 
	{
        case "male": genderSymbol = "\u2642"; break;
        case "female": genderSymbol = "\u2640"; break;
        default: genderSymbol = ""; break;
    }
	genderSpan.append(genderSymbol);
	fh.append(genderSpan);

    // Now show the other information. Non-standard? Yes, but it gets the job done.
    // Add a period after the tagline when doing so. --PS 2010-07-03
	var ss = $('#siteSub');
	ss.html(ss.html() + ' <span id="ps-userinfo">' + statusText + '</span>');
}