Record how long each HIT took to complete. Lists results on status_details page.
// ==UserScript==
// @name HowLongDidITake
// @namespace https://greasyfork.org/en/users/6503-turk05022014
// @description Record how long each HIT took to complete. Lists results on status_details page.
// Has the ability to Export Times to clipboard in json format.
// Has the ability to Import Times in json format.
// When updating or switching browsers, exporting a backup may be beneficial.
// @match https://worker.mturk.com/status_details/*
// @match https://worker.mturk.com/projects/*/tasks/*?assignment_id=*
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js
// @version 3.0.20180210
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_setClipboard
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
var startTime = Date.now();
var rgxID = /assignment_id[^=]*?=([^&]+)/i;
var hits = JSON.parse(GM_getValue("hits", "{}"));
if (Object.keys(hits).length == 0)
convert();
$(function () {
if (location.pathname.indexOf("/status_details/") >= 0) {
if ((Date.now()-(1000*60*60*24)) > GM_getValue("checkedCache", 0)) {
GM_setValue("checkedCache", Date.now());
setTimeout(checkCache, 1000);
}
$(".table-row").on('click', insertTime);
$('.expand-projects-button').on('click', function () {
$(".table-row").each(insertTime);
});
addBorder();
addButton("Import Times", importTimes);
addButton("Export Times", exportTimes);
} else {
var match = rgxID.exec(location.search);
if (!match)
return;
$(window).on('unload', function () {
var endTime = Date.now();
hits = JSON.parse(GM_getValue("hits", "{}"));
hits[match[1]] = { time: parseInt((endTime-startTime)/1000), added: endTime };
GM_setValue("hits", JSON.stringify(hits));
});
}
});
function convert() {
GM_listValues().forEach(function (key) {
if (key == "checkedCache" || key == "hits")
return;
var value = JSON.parse(GM_getValue(key));
hits[key] = value;
});
GM_setValue("hits", JSON.stringify(hits));
}
function checkCache() {
for (var key in hits)
if (hits[key].added < (Date.now() - (1000 * 60 * 60 * 24 * 151)))
delete hits[key];
GM_setValue("hits", JSON.stringify(hits));
}
function importTimes() {
if ($("#hlditimportbox").length > 0) {
$("#hlditimportbox").remove();
return;
}
$(".status-details-controls").after('<div id="hlditimportbox">' +
'<textarea rows="12" style="resize:none;width:100%;" id="hlditimporttxt"></textarea><br>' +
'<input id="hlditimportbtn" class="btn btn-secondary" type="button" value="Import">' +
'</div>');
$("#hlditimportbtn").on('click', function () {
hits = JSON.parse(GM_getValue("hits", "{}"));
try {
var times = JSON.parse($("#hlditimporttxt").val());
for (var key in times)
hits[key] = times[key];
GM_setValue("hits", JSON.stringify(hits));
$("#hlditimportbox").append("<br>Imported.<br>");
} catch(e) {
$("#hlditimportbox").append("<br>" + e.name + ":" + e.message + "<br>");
}
});
}
function exportTimes() {
hits = JSON.parse(GM_getValue("hits", "{}"));
GM_setClipboard(JSON.stringify(hits), "text");
}
function insertTime() {
var row = this;
var match = rgxID.exec($(row).find('.desktop-row a:contains("Contact Requester")').first().attr("href"));
if (match && hits[match[1]]) {
setTimeout(function () {
if ($(row).find(':contains("Time to complete")').length > 0)
return;
$(row).find(".expanded-row-content").append(
'<h6>Time to complete</h6>' + hms(parseInt(hits[match[1]].time)) +
'<h6 style="margin-top:14px;">Completed</h6>' + (new Date(hits[match[1]].added)).toLocaleTimeString()
);
}, 500);
}
}
function hms(seconds) {
var hours = Math.floor(seconds/(60*60));
seconds -= (hours*60*60);
var minutes = Math.floor(seconds/60);
seconds -= (minutes*60);
return (hours < 10 ? "0" : "") + hours + ":" +
(minutes < 10 ? "0" : "") + minutes + ":" +
(seconds < 10 ? "0" : "") + seconds;
}
function addButton(title, func) {
$(".status-details-controls").append(
'<div style="float:left; margin-left: 10px; margin-top: 2px;">\
<input id="hlditbtn'+func.name+'" class="btn btn-secondary" type="button" value="'+title+'"></div>');
$("#hlditbtn"+func.name).on('click', func);
}
function addBorder() {
$(".status-details-controls").append('<div style="border-left: 1px solid rgb(220, 140, 27); float: left; margin-top: 6px; margin-left: 14px;"> </div>');
}