User:Interiot/Tool2/code.js'
// see http://paperlined.org/apps/wikipedia/Tool2/ for instructions on adding this to your monobook.js
// To run this tool on other servers:
// 1. copy this script to the target server (this is required because of javascript cross-site security restrictions)
// 2. update the following URL
// for example: "User:Interiot/Tool2/code.js"
var tool2_url = "User:Interiot/Tool2/code.js";
// 3. update this namespace list, extracted from something like http://en.wikiquote.org/wiki/Special:Export//
// These *should not* have colons after them.
var namespaces = [
"Talk",
"User",
"User talk",
"Wikiquote",
"Wikiquote talk",
"Image",
"Image talk",
"MediaWiki",
"MediaWiki talk",
"Template",
"Template talk",
"Help",
"Help talk",
"Category",
"Category talk",
// 3b. these two project project entries are not added by Special:Export, and might or might not need to be updated
"Wikipedia",
"Wikipedia talk"
];
namespaces[100] = "Portal";
namespaces[101] = "Portal talk";
// 4. update this date-parser to match the format and language of your specific wiki. Feel free to contact Interiot regarding this, if you can't find another
// copy of this script that uses the same language.
// input: a text string from Special:Contributions. output: a javascript Date object
// documentation: http://www.quirksmode.org/js/introdate.html#parse, http://www.elated.com/tutorials/programming/javascript/dates/
function date_parse(text) {
var matches = text.match(/^([0-9:]+), +([0-9]+) +([a-z]+) +([0-9]+)$/i);
if (!matches) {
//dump_text("XXX"); // for debugging
return matches;
}
parseme = matches[3] + ", " + matches[2] + " " + matches[4] + " " + matches[1] + ":00";
//dump_text(parseme); // for debugging
var dt = new Date();
dt.setTime( Date.parse(parseme));
//dump_text(dt.toLocaleString()); // for debugging
return dt;
}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ end of server-specific configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// TODO:
// - the current document.location method doesn't work when the page is accessed sans-mod_rewrite
// - test with non-ASCII characters
// - non-ascii usernames
// - ??
var prefix = "";
var params = parse_params();
addOnloadFunction(function() {
var path_len = document.location.pathname.length;
// trigger once we view the right page
if (document.location.pathname.substring(path_len - tool2_url.length, path_len) == tool2_url) {
// get the prefix (needs to be fixed to work sans-mod_rewrite
prefix = document.location.protocol + "//" + document.location.host + "/"
+ document.location.pathname.substring(1, path_len - tool2_url.length);
// blank the inner contents of the page
var bodyContent = document.getElementById("bodyContent");
while (bodyContent.childNodes.length > 0) bodyContent.removeChild(bodyContent.lastChild);
if (document.location.search.length == 0) {
generate_input_form(bodyContent);
} else {
generate_main_report(bodyContent);
}
}
});
function generate_input_form(bodyContent) {
if (navigator.userAgent.toLowerCase().indexOf('msie')+1)
{
bodyContent.innerHTML = "This counter does not currently work in Internet Explorer. Please get Firefox or use Flcelloguy's Tool instead.";
}
else
{
bodyContent.innerHTML =
"
";var form = bodyContent.getElementsByTagName("form")[0];
form.method = "get";
form.action = document.location;
document.getElementById("username").focus();
}
}
function generate_main_report() {
fetch_data(params["username"].replace(/\+/g, " "),
"", output_main_report, 0, []);
}
function add_stats_row(left_col, right_col) {
var row = document.createElement("tr");
var left = document.createElement("td");
var right = document.createElement("td");
document.getElementById("basic_stats").appendChild(row);
row.appendChild(left);
row.appendChild(right);
//left.innerHTML = left_col;
left.appendChild( document.createTextNode(left_col) );
right.appendChild( document.createTextNode(right_col) );
return row;
}
function output_main_report(history) {
// -- generate summary statistics
var unique_articles = new Array();
var namespace_numedits = new Array();
for (var i=0; i namespace_numedits[ namespaces[i] ] = 0; } namespace_numedits[""] = 0; for (var i=0; i var h = history[i]; unique_articles[ h["title"] ]++; namespace_numedits[ h["namespace"] ]++; } var unique_articles_keys = keys(unique_articles); // -- output report var table = document.createElement("table"); table.id = "basic_stats"; document.getElementById("bodyContent").appendChild(table); add_stats_row("Username", params["username"].replace(/\+/g, " ")); add_stats_row("Total edits", history.length); add_stats_row("Distinct pages edited", unique_articles_keys.length); add_stats_row("Average edits/page", new Number(history.length / unique_articles_keys.length).toFixed(3)); add_stats_row("First edit", history[ history.length-1 ]["date_text"] ); // add a blank row add_stats_row("", "").childNodes[0].style.height = "1em"; add_stats_row("(main)", namespace_numedits[""]); for (var i=0; i var nmspc = namespaces[i]; if (namespace_numedits[nmspc]) { add_stats_row(nmspc, namespace_numedits[nmspc]); } } } // ===================================== HTML-scraping backend ========================================= function add_loading_notice() { if (document.getElementById("loading_notice")) return; var loading = document.createElement("div"); loading.id = "loading_notice"; loading.innerHTML = " document.getElementById("bodyContent").appendChild(loading); } function remove_loading_notice() { var loading = document.getElementById("loading_notice"); if (!loading) return; loading.parentNode.removeChild(loading); } var offset_regexp = /href="[^"]+:Contributions[^"]+offset=(\d+)/gi; function fetch_data(username, end_date, handler, offset, page_list) { add_loading_notice(); var url = prefix + "Special:Contributions/" + username + "?offset=" + offset + "&limit=5000"; loadXMLDoc(url, function (request) { var next_offset = 0; if (request.readyState != 4) return; if (request.status == 200) { page_list.push(request.responseText); //dump_text(request.responseText); // see if there's another pageful to get var matches = map( function(p){ return p.match( /(\d+)$/ )[0]; }, request.responseText.match( offset_regexp ) ); for (var i=0; i var v = matches[i] * 1; if (v != 0 && (offset == 0 || v < offset)) { next_offset = v; break; } } } //next_offset = 0; // for testing only, retrieve just the first page of results if (next_offset == 0) { parse_data(page_list, handler); } else { // tail recurse fetch_data(username, end_date, handler, next_offset, page_list); } }); } // input: a list of strings, each string containing the HTML from a single page // output: a list, where each individual entry is a specific edit from history function parse_data(page_list, handler) { //var total_len = 0;
Retrieving data";