MediaWiki:Gadget-readyAlert.js

Note: After saving, you may have to bypass your browser's cache to see the changes. Mozilla / Firefox / Safari: hold down Shift while clicking Reload, or press Ctrl-Shift-R (Cmd-Shift-R on Apple Mac); IE: hold Ctrl while clicking Refresh, or press Ctrl-F5; Konqueror: simply click the Reload button, or press F5; Opera users may need to completely clear their cache in Tools→Preferences. — More skins

try { // containerize gadget, to protect other gadgets if this one goes wrong

/* Known issue: Hopefully i fixed them. If you find something, please tell me. - bawolff */
/*extern jsMsg*/
/*Note: variable q is from me doing scewy things with eval()*/
/*jslint evil: true*/

/* What this does:
Gets a list of:
 * last 7 articles in category:Review that are in the main namespace
 * a maximun of 4 articles (ordered by hasn't matched for longest time) that stable version != latest version for at least 5 seconds

Displays them in note up top. It only gets the 4 oldest oldreviewed articles as not to overwhelm the list. It waits for 5 seconds so that articles being actively edited and flagged don't show up
*/
function readyAlert() {

/*    var curTime = new Date;
    var sma = new Date(curTime.getTime() - 1000*5); //five seconds
    var timeStamp = sma.getUTCFullYear() + "-" + readyAlert.pad((sma.getUTCMonth() + 1)) + "-" + readyAlert.pad(sma.getUTCDate()) + "T" + readyAlert.pad(sma.getUTCHours()) + ":" + readyAlert.pad(sma.getUTCMinutes()) + ":" + readyAlert.pad(sma.getUTCSeconds()) + "Z";
*/

    var x;

    try {
        x = new XMLHttpRequest();
        x.open("GET", mw.config.get('wgScriptPath') + "/api.php?action=query&list=oldreviewedpages&prop=categories&generator=categorymembers&clprop=timestamp&gcmtitle=Category:Review&clcategories=Category:Review|Category:Review-High%20Priority&gcmdir=asc&gcmsort=timestamp&gcmnamespace=0&ornamespace=0&format=json&ordir=newer&orlimit=4&gcmlimit=7", true);
        x.onreadystatechange = function () {
            if (x.readyState === 4 && x.status === 200) {
                var Ctype = x.getResponseHeader('Content-Type');
                if (Ctype.indexOf('application/json') !== 0) {
                    return false; //something bad happened
                }

                var resp = x.responseText;
                resp = "var q = " + resp;
                eval(resp);
                var catMem = q.query.pages;
                var oldRev = q.query.oldreviewedpages;
                var fwdSlash = /\%2F/g;  //only URI component separating character allowed should be /, so We encodeURIComponent, then dencode the /
    
                var res = document.createElement("ul");
                var tmpA, tmpLI, tmpMeta, tmpTime, i, count = 0;

                //go through things in cat:review
                for (i in catMem) {
                    if(catMem.hasOwnProperty(i)) {
                        tmpMeta = [];
                        tmpA = document.createElement('A');
                        tmpA.href = mw.config.get('wgArticlePath').replace("$1", encodeURIComponent(catMem[i].title).replace(fwdSlash, "/"));
                        tmpA.appendChild(document.createTextNode(catMem[i].title));
                        tmpLI = document.createElement("li");
                        tmpLI.appendChild(tmpA);
                        tmpTime = readyAlert.compareDate(catMem[i].categories[0].timestamp);
                        if (tmpTime) {
                            tmpMeta[tmpMeta.length] =  tmpTime;
                        }
                        if (catMem[i].categories.length === 2) {  //if both in review, and high priority review categories.
                            tmpMeta[tmpMeta.length] = "priority";
                        }
                        if (tmpMeta.length !== 0) {
                            tmpLI.appendChild(document.createTextNode(" (" + tmpMeta.join('; ') + ")" ));
                        }
                        res.appendChild(tmpLI);
                        count++; //count = to number of nodes in list
                    }
                }
                //Go through old reviewed pages
// http://en.wikinews.org/w/index.php?title=US_Supreme_Court_dismisses_appeal_on_Obama%27s_citizenship&diff=cur&oldid=739024&diffonly=0
                for (var j = 0; j < oldRev.length; j++) {
                    tmpA = document.createElement('A');
                    tmpA.href = mw.config.get('wgScript') + "?title=" + encodeURIComponent(oldRev[j].title).replace(fwdSlash, "/") + "&diffonly=0&diff=cur&oldid=" + encodeURIComponent(oldRev[j].stable_revid);
                    tmpA.appendChild(document.createTextNode(oldRev[j].title));
                    tmpLI = document.createElement("li");
                    tmpLI.appendChild(tmpA);
                    tmpTime = readyAlert.compareDate(oldRev[j].pending_since);
                    if (!tmpTime) {
                        tmpTime = "";
                    }
                    else {
                        tmpTime = "; " + tmpTime;
                    }
                    tmpLI.appendChild(document.createTextNode(' (re-flag' + tmpTime + ')'));
                    res.appendChild(tmpLI);
           
                }
                if (q['query-continue']) { //if there is more
                    tmpA = document.createElement('A');
                    tmpA.href = mw.config.get('wgScript') + "?title=" + encodeURIComponent('CAT:REV')
                    tmpA.appendChild(document.createTextNode("More »"));
                    tmpLI = document.createElement("li");
                    tmpLI.appendChild(tmpA);
                    res.appendChild(tmpLI);
                }
                var listLen = count+j;
                if (listLen > 0) {
                    readyAlert.Display(res, listLen);
                }
                x.onreadystatechange = null;
                x = null;
                return res;
        
            }
        }
        x.send(null);
    }
    catch (someDeadlyError) {
    //mostly to stop it taking down rest of site js (like it used to on secure)
    jsMsg(document.createTextNode("ReadyAlert gadget fails at life, please tell Bawolff. error: " + someDeadlyError.toString()));
    }
}
readyAlert.pad = function (n) {
/* takes String or number. If one digit long, pads with 0, returns as string
else return as is */
    if (n.toString().length === 1) {
        return ('0' + n);
    }
    
    return n;

}
readyAlert.Display = function (res, len) {
    var tmpB = document.createElement('b');
    var msg = document.createDocumentFragment();
    msg.appendChild(document.createTextNode("The following " + (len > 1 ? len.toString() + " articles need to be " : "article needs to be ")));
    tmpB.appendChild(document.createTextNode("reviewed:"));
    msg.appendChild(tmpB);
    msg.appendChild(res);

    jsMsg(msg, "readyArticles");
}

$(readyAlert);

readyAlert.compareDate = function(datestring) {
    //Takes a date (in api/UTC format), and tells approximantly how long ago it happend
    var date = Bawolff.mwapi.parseAPIDate(datestring);
    var today = new Date();
    var delta = today.valueOf() - date.valueOf(); //valueof not really needed...
    //delta in milliseconds
    if (delta < 0) {
        return "in the future?!";
    }
    if (delta > 1000*60*60*48) { //2 days
        var foo = Math.round(delta / (1000*60*60*24));
        return  foo + ((foo === 1) ? "day; Overdue" : " days; Overdue");
    }
    if (delta > 1000*60*60*12) { // > 12 hour
        return Math.round(delta / (1000*60*60)) + " hours; Overdue";
    }
    if (delta > 1000*60*60) { // > 1 hour
        var foo = Math.round(delta / (1000*60*60));
        return  foo +  ((foo === 1) ? " hour" : " hours");
    }
    if (delta > 1000*60*20) { // > 20 min
        return Math.round(delta / (1000*60)) + " minutes";
    }
    
    return false; //To short time
}

//Stolen from [[user:Bawolff/mwapilib.js]]
if (!window.Bawolff) {
var Bawolff = {};
}
if (!Bawolff.mwapi) {
Bawolff.mwapi = {};
}
/****
Takes a date in the form that api sends it (aka 2009-03-23T04:43:58Z )
and returns a js Date() object

depends on Bawolff.mwapi.parseAPIDate.regex and Bawolff.mwapi.parseAPIDate.func
to do grunt work.

****/

Bawolff.mwapi.parseAPIDate = function (datestring) {
    // + sign converts to number
    return new Date(+datestring.replace(Bawolff.mwapi.parseAPIDate.regex, Bawolff.mwapi.parseAPIDate.func));

}

Bawolff.mwapi.parseAPIDate.regex = /^([0-9]{4})-([0-1][0-9])-([0-3][0-9])T([0-2][0-9]):([0-5][0-9]):([0-5][0-9])Z$/;
Bawolff.mwapi.parseAPIDate.func = function (str, year, month, day, hour, min, sec) {
//Since JS and server form differ on month 0.

    month = parseInt(month, 10);
    month--;

    return Date.UTC(year, month, day, hour, min, sec);

}

} catch (e) { // containerize gadget, to protect other gadgets if this one goes wrong
  // ignore
}