| candidate |
support ratio |
oppose reasons |
result |
| Meno25 |
0.963, 96.3% (157/163) |
— |
elected |
| Erwin |
0.96, 96% (192/200) |
— |
elected |
| Kylu |
0.954, 95.4% (207/217) |
— |
elected |
| Laaknor |
0.944, 94.4% (119/126) |
— |
elected |
| Mike.lifeguard |
0.884, 88.4% (258/292) |
— |
elected |
| Leinad |
0.868, 86.8% (138/159) |
inexperience. |
elected |
| Dorgan |
0.844, 84.4% (141/167) |
inexperience. |
elected |
| Alexanderps |
0.817, 81.7% (125/153) |
too much access, allegations of canvassing and misuse of checkuser tool. |
elected |
| Mardetanha |
0.813, 81.3% (217/267) |
disputes on fawiki, fear that Iranian government will gain his access under torture. |
elected |
| putnik |
0.792, 79.2% (152/192) |
inexperience, unanswered questions, dispute on ruwiki. |
failed |
| Avraham |
0.785, 78.5% (150/191) |
inexperience, limited language skills. |
failed |
| Fabexplosive |
0.781, 78.1% (114/146) |
dispute on lmowiki, allegedly executes tasks without understanding them, unanswered questions (later answered). |
failed |
| Jredmond |
0.759, 75.9% (66/87) |
inexperience, too much access, unanswered questions (later answered). |
failed |
| PhiLiP |
0.71, 71% (66/93) |
inexperience, copyright issues with uploads, fear that Chinese government will gain his access under torture. |
failed |
| SpeedyGonsales |
0.696, 69.6% (87/125) |
inexperience, misunderstanding of steward role, disputes on hrwiki. |
failed |
| Mywood |
0.671, 67.1% (55/82) |
inexperience, copyright issues with uploads. |
failed |
| EVula |
0.546, 54.6% (77/141) |
inexperience, too much access, limited language skills, appearance of incivility. |
failed |
| avjoska |
0.4, 40% (38/95) |
inexperience, intent of inactivity as a steward. |
failed |
| Fadesga |
0.3, 30% (21/70) |
inexperience, no steward goals, unanswered questions. |
failed |
| Al Lemos |
0.255, 25.5% (35/137) |
inexperience, misunderstanding of steward role. |
failed |
| Pasquale |
0.19, 19% (12/63) |
inexperience, misunderstanding of steward role, unanswered questions, little activity. |
failed |
| Apteva |
0.016, 1.6% (2/124) |
inexperience, prior block, lack of steward goals, misunderstanding of steward role, little activity. |
failed |
| Loco085 |
0.646, 64.6% (42/65) |
inexperience, unanswered questions. |
withdrawn |
| Cometstyles |
0.598, 59.8% (76/127) |
alleged abuse of OTRS access, checkuser requests with insufficient reason. |
withdrawn |
| Orderinchaos |
0.265, 26.5% (13/49) |
inexperience, limited language skills. |
withdrawn |
| Gutza |
0.193, 19.3% (11/57) |
intent of inactivity as a steward, misunderstanding of steward role, unanswered questions. |
withdrawn |
| Chase me ladies, I'm the Cavalry |
0.000, — |
disqualified; not identified. |
disqualified |
| Drakesketchit |
0.000, — |
disqualified; not identified. |
disqualified |
| Fipplet |
0.000, — |
disqualified; not identified. |
disqualified |
| Jagwar |
0.000, — |
disqualified; not identified. |
disqualified |
| Wykypydya |
0.000, — |
disqualified; not identified, not linked to an account meeting account requirements. |
disqualified |
/*********************
** Functions
*********************/
// report to box
function ses_report(text) {
$('stewiestats').adopt(document.createTextNode(text));
}
/*********************
** Initialize
*********************/
function ses_initialize() {
// display status box
if(!document.getElementById('stewiestats')) {
// create box
var box = document.createElement('pre');
box.setAttribute('id', 'stewiestats');
box.setAttribute('style', 'margin:1em; padding:0.5em; border:1px solid #C00;');
box.appendChild(document.createTextNode('Loading required framework...\n'));
editbox.parentNode.insertBefore(box, editbox.parentNode.firstChild);
// jump to box
window.location.hash = "#stewiestats";
}
// wait until WikiMooTools loaded
if(!window.$chk) {
setTimeout('init_update()', 500);
return;
}
// reset box
$('stewiestats').set({'text':'Loading required framework...\n'});
// start script
ses_fetch_page();
}
/*********************
** Fetch page text
*********************/
function ses_fetch_page() {
/* update status box */
ses_report('Fetching elections page...\n');
/* grab page text */
var request = new Request({
url:'http://meta.wikimedia.org/wiki/Stewards/elections_2009/votes?action=render',
method: 'GET',
onSuccess:ses_parse_page,
onFailure: function(xhr) {
ses_report('AJAX error while fetching elections page: ' + xhr.status + ' (' + xhr.statusText + ')\n');
}
}).send();
}
/*********************
** Count unique participants
*********************/
function ses_count_participants(text) {
ses_report('Counting unique participants... ');
var links = text.match(/title="User:[^\/"]+/ig);
var names = {};
var count = 0;
if(links) {
for(var i=0, len=links.length; i<len; i++) {
var name = links[i].match(/User:(.+)/)[1];
if(!names[name]) {
names[name] = 1;
count++;
}
}
}
ses_report(count + '\n');
editbox.value = editbox.value.replace(/(<span id="ses_count">).*?(<\/span>)/, '$1' + count + '$2');
}
/*********************
** Extract data from page
*********************/
function ses_parse_page(text, xml) {
/* update status box */
ses_report('Extracting data...\n');
// strip out cruft
text = text.replace(/^[\s\S]+?<table id="toc"[\s\S]+?<\/table>/, ''); // introduction, TOC, etc
text = text.replace(/^(<h2.+?<\/h2>)[\s\S]+?<h3[\s\S]+?(<h3)/mg, '$1\n$2'); // statements, 'questions' header
text = text.replace(/<ul>[\s\S]+?<\/ul>/g, ''); // threaded bullets
text = text.replace(/^(<(?:h2|h3|li).+\n*)|^.+\n*/mg, '$1'); // everything else except headers and list items
text = text.replace(/^<h(\d)>.*<span class="mw-headline">.*?>\s*([^<>]+?)\s*<.+<\/h\1>/mg, '<h$1>$2</h$1>'); // simplify headers
// count participants
ses_count_participants(text);
// data
var names = []; // all candidate names
var votes = []; // all section titles
var counts = {}; // vote counts per section per candidate
var name = ''; // current candidate name
var vote = ''; // current section ('Yes', 'No', 'Neutral')
// parse text
text = text.split('\n');
var len = text.length;
var line;
for(var i=0; i<len; i++) {
line = text[i];
// li: new vote
if(line.match('<li')) {
counts[name][vote]++;
}
// h3: new vote section
else if(line.match('<h3')) {
vote = line.match(/<h3>(.+)<\/h3>/)[1];
votes.push(vote);
counts[name][vote] = 0;
}
// h2: new candidate
else if(line.match('<h2')) {
name = line.match(/<h2>(.+)<\/h2>/)[1];
names.push(name);
counts[name] = {};
}
}
// update table
ses_gen_table(names, votes, counts);
}
/*********************
** Return formatted date
*********************/
function ses_get_date() {
// zero pad
function zero_pad(num) {
if(num<10)
num = '0' + num;
return num;
}
// generate string
var d = new Date();
var str = d.getUTCFullYear() + '-' + zero_pad(d.getUTCMonth()+1) + '-' + zero_pad(d.getUTCDate()) + ' '
+ zero_pad(d.getUTCHours()) + ':' + zero_pad(d.getUTCMinutes()) + ' (UTC)';
return str;
}
/*********************
** Update table
*********************/
function ses_gen_table(names, votes, counts) {
/* update status box */
ses_report('Generating updated table...\n');
/***************
** Variables
***************/
// constants
var len = names.length; // number of candidates
var yes = votes[0]; // title of support headers
var no = votes[1]; // title of oppose headers
// data
var rows = {}; // all template texts
var ratios = {}; // all support ratios
var sorted = []; // candidate names, sorted by ratio
// other
var text = editbox.value;
/***************
** Regex to match candidate row template
***************/
function reg_candidate_template(name) {
return new RegExp('{{user[^}]+name *= *' + name + '[^}]+}}', 'mi');
}
/***************
** Fetch & update rows
***************/
for(var i=0; i<len; i++) {
// grab text
var name = names[i];
var row = text.match(reg_candidate_template(name)).toString();
// update
row = row.replace(/(support *=).*/, '$1 ' + counts[name][yes]);
row = row.replace(/(oppose *=).*/, '$1 ' + counts[name][no]);
// store
rows[name] = row;
ratios[name] = counts[name][yes]/(counts[name][yes]+counts[name][no]);
}
/***************
** Sort rows
***************/
for(var i=0; i<len; i++) {
var name = names[i];
var ratio = counts[name][yes]/(counts[name][yes]+counts[name][no]);
// insert into sorted position
for(var x=0; x<=sorted.length; x++) {
// end of array, just stick it in
if(x==sorted.length) {
sorted.push(name);
break;
}
else if(ratios[name]>ratios[sorted[x]]) {
sorted.splice(x, 0, name);
break;
}
}
}
/***************
** Update text
***************/
// date
text = text.replace(/(<span id="ses_date">).*?(<\/span>)/, '$1' + ses_get_date() + '$2');
// rows
var str = '';
for(var i=0; i<len; i++)
str += rows[sorted[i]] + '\n';
text = text.replace(/(<!--ses-start-->)[\s\S]+?(<!--ses-end-->)/i, '$1\n' + str + '$2');
// text
editbox.value = text;
/* update status box */
ses_report('Done.');
}
ses_initialize();