您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
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>'); }