// ==UserScript==
// @name turkopticon
// @version 2014.08.20.1512
// @description Review requesters on Amazon Mechanical Turk
// @author Lilly Irani and Six Silberman
// @homepage http://turkopticon.ucsd.edu
// @include http://*.mturk.com/*
// @include https://*.mturk.com/*
// @namespace https://greasyfork.org/users/4606
// @downloadURL none
// ==/UserScript==
var TURKOPTICON_BASE = "http://turkopticon.ucsd.edu/";
var API_BASE = "http://turkopticon.ucsd.edu/api/";
var API_MULTI_ATTRS_URL = API_BASE + "multi-attrs.php?ids=";
function getRequesterAnchorsAndIds(a) {
//a is a list of anchor DOM elements derived in the previous function
var rai = {};
var re = new RegExp(/requesterId/);
var rf = new RegExp(/contact/);
var isContactLink = new RegExp(/Contact/);
var isImgButton = new RegExp(/img/);
var requestersHere = false;
for(var i = 0; i < a.length; i++) {
var href = a[i].getAttribute('href');
if (re.test(href) /*&& !rf.test(href)*/) {
var innards = a[i].innerHTML;
if (!isContactLink.test(innards) && !isImgButton.test(innards)) {
var id = a[i].href.split('requesterId=')[1].split('&')[0]
if (!rai.hasOwnProperty(id)) {
rai[id] = []; }
rai[id].push(a[i]);
requestersHere = true;
}
}
}
rai = (requestersHere)? rai : null;
return rai;
}
function buildXhrUrl(rai) {
var url = API_MULTI_ATTRS_URL;
var ri = Object.keys(rai);
for(var i = 0; i < ri.length; i++) {
url += ri[i];
if (i < ri.length - 1) { url += ","; } }
return url; }
function makeXhrQuery(url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send(null);
var resp = JSON.parse(xhr.response);
return resp; }
function ul(cl, inner) {
return "
"; }
function li(cl, inner) {
return "" + inner + ""; }
function span(cl, inner) {
return "" + inner + ""; }
function strmul(str, num) {
return Array(num + 1).join(str); }
function pad(word, space) {
if (word.length >= space) { return word; }
else { return word + strmul(" ", space - word.length); } }
function long_word(word) {
switch(word) {
case "comm": return "communicativity"; break;
case "pay" : return "generosity"; break;
case "fair": return "fairness"; break;
case "fast": return "promptness"; break; } }
function visualize(i, max, size) {
var color;
if (i / max <= 2 / 5) { color = 'red'; }
else if (i / max <= 3 / 5) { color = 'yellow'; }
else { color = 'green'; }
var filled = Math.round((i / max) * size);
var unfilled = size - filled;
var bar = span("bar", span(color, strmul(" ", filled)) + span("unf", strmul(" ", unfilled)));
return bar; }
function attr_html(n, i) {
return pad(long_word(n), 15) + ": " + visualize(i, 5, 30) + " " + i + " / 5"; }
function ro_html(ro) {
var rohtml = "";
if (typeof ro.attrs != 'undefined') {
var keys = Object.keys(ro.attrs);
for (var i = 0; i < keys.length; i++) {
rohtml += li("attr", attr_html(keys[i], ro.attrs[keys[i]])); } }
return rohtml; }
function what(ro) {
var str = "";
if (typeof ro.attrs != 'undefined') {
str = li("gray_link", "What do these scores mean?"); }
return str; }
function nrs(rid, nrevs) {
var str = "";
if (typeof nrevs === 'undefined') {
str = "No reviews for this requester"; }
else { str = "Scores based on " + nrevs + " reviews"; }
return str; }
function tos(tosflags) {
var str = "Terms of Service violation flags: " + tosflags + "";
return str; }
function rl(rid, name) {
var rl = "";
rl += "Report your experience with this requester »";
return rl; }
function dropDown(ro, rid) {
var n = ro.name;
var arrcls = "";
if (typeof ro.attrs != 'undefined') { arrcls = "toc"; }
var dd = ul("tob", li(arrcls, "▼") + ul("tom", ro_html(ro) + what(ro) + nrs(rid, ro.reviews) + tos(ro.tos_flags) + rl(rid, n)));
return dd; }
function insertInlineCss() {
var css = "";
var head = document.getElementsByTagName("head")[0];
head.innerHTML = css + head.innerHTML;
}
function getNames(rai, resp) {
for(var rid in rai) {
if (rai.hasOwnProperty(rid)) {
if (resp[rid] == "") { // empty response, no data in Turkopticon DB for this ID
resp[rid] = JSON.parse('{"name": "' + rai[rid][0].innerHTML.split("")[0].split(">")[1] + '"}');
}
resp[rid].name = rai[rid][0].innerHTML.split("")[0].split(">")[1]; } } // overwrite name attribute of response object from page
return resp; }
function insertDropDowns(rai, resp) {
for(var rid in rai) {
if (rai.hasOwnProperty(rid)) {
for(var i = 0; i < rai[rid].length; i++) {
var td = rai[rid][i].parentNode;
td.innerHTML = dropDown(resp[rid], rid) + " " + td.innerHTML; } } } }
insertInlineCss();
var a = document.getElementsByTagName('a');
var reqAnchors = getRequesterAnchorsAndIds(a);
if (reqAnchors) {
var url = buildXhrUrl(reqAnchors);
var resp = makeXhrQuery(url);
resp = getNames(reqAnchors, resp);
insertDropDowns(reqAnchors, resp);
}