// ==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); }