// ==UserScript==
// @name Mturk Hourly
// @namespace https://gf.qytechs.cn/users/11205
// @version 2.0.1
// @description Record time spent working on HITs. Forked from Mturk Dashboard.
// @author Kerek
// @include https://www.mturk.com/mturk/dashboard*
// @grant GM_log
// @grant GM_setClipboard
// @require https://code.jquery.com/jquery-3.0.0-beta1.min.js
// @include https://worker.mturk.com/dashboard*
// @include https://www.mturk.com/mturk/statusdetail*
// @include https://www.mturk.com/mturk/accept*
// @include https://www.mturk.com/mturk/preview*
// @include https://www.mturk.com/mturk/continue*
// @include https://www.mturk.com/mturk/submit
// @include https://www.mturk.com/mturk/return*
// @include https://worker.mturk.com/projects/*/tasks/*assignment_id=*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @connect mturk.com
// ==/UserScript==
if (location.href.indexOf(`https://www.mturk.com/mturk/dashboard`) !== -1) {
var LOADED = $("#total_earnings_amount").length;
if (LOADED){
// Functions that can be commented out if you don't want it to run.
Todays_Projected_Earnings();
Todays_Bonuses();
//Best_Worst_Case();
//Real_Stats();
//Changes();
//Yearly();
//Goal();
}
}
else if (location.href.indexOf(`https://worker.mturk.com/dashboard`) !== -1) {
initialize();
// Functions that can be commented out if you don't want it to run.
//allApprovedRate();
//allRejectedRate();
//fourDigitPercents();
//rejectionsBelow99();
//rejectionsBelow95();
//totalLast45Days();
//hitStatusChanges(); // partially working
todaysActivity();
}
else if (location.href.indexOf('worker.mturk.com') > -1){
var hit_returned = false;
if(typeof(Storage)!=="undefined")
{
$('button:contains("Return")').click(function(){
hit_returned = true;
});
store_data('openWorker');
window.addEventListener('beforeunload', function(){
store_data('closeWorker');
});
}
}
else{
var hit_returned = false;
if(typeof(Storage)!=="undefined")
{
$('img[src="/images/return_hit.gif"]').parent().click(function(){
hit_returned = true;
});
store_data('open');
window.addEventListener('beforeunload', function(){store_data('close');});
var $requesters = $('td[class="statusdetailRequesterColumnValue"]');
var gmHourlyLog = JSON.parse(GM_getValue('gmHourlyLog')) || {};
if ($requesters.length > 0)
{
$requesters.each(function(){
var hitId = $(this).find('a').attr('href').split('hitId=')[1].split('&')[0];
console.log(hitId);
var $feedback_value = $(this).parent().find('td[class="statusdetailStatusColumnValue"]').next();
var feedback_str = '';
var time_data = localStorage.getItem('time_data.' + hitId);
if (time_data === null){
time_data = gmHourlyLog[hitId];
}
if (time_data){
feedback_str = create_feedback_str(time_data);
}
var status_value = $feedback_value.html() + feedback_str;
$feedback_value.html(status_value);
});
}
}
}
// Don't touch anything below here.
function Todays_Projected_Earnings(){
var TPEhitLOG = {}; var TPEdetailsLOG = {}; var TPEhourlyLOG = {}; var pe = 0;
var today = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).prop("href");
var $peTR = $('<div id="TPE_div" class="even" style="display:table-row">');
var $peTD1 = $('<td class="metrics-table-first-value">');
var $peTD2 = $('<td>');
var $peA = $('<a href="javascript:void(0)">Today\'s Projected Earnings</a>');
var $TPE_details = $('<span style="color: blue; font-size: 10px; cursor: pointer; float: right;">Details<img style="margin-left: 5px;" src="/media/more.gif" border="0/"></span>');
var $peSPAN = $('<span class="reward">$0.00</span>');
$("td.metrics-table-first-value:contains(Total Earnings)").parent().after($peTR);
$peTR.append($peTD1.append($peA,$TPE_details),$peTD2.append($peSPAN));
var $TPED_table = $('<table style="display: none;" width="760" align="center" cellspacing="0" cellpadding="0">');
var $TPED_tboday = $('<tbody>');
var $TPED_tr_1 = $('<tr id="TPE_tr" height="25px"><td width="10" bgcolor="#7fb4cf" style="padding-left: 10px;"></td><td width="100%" bgcolor="#7fb4cf" class="white_text_14_bold">Today\'s Projected Earnings Details <a id="fourmEXPORT" href="javascript:void(0)" class="whatis" >(Forum Export)</a></td><td width="10" align="right" bgcolor="#7fb4cf"></td></tr>');
var $TPED_tr_2 = $('<tr><td class="container-content" colspan="3"><table class="metrics-table" width="100%"><tbody><tr><td width="100%"><table class="metrics-table" width="100%"><tbody id="tbody2"></tbody></table></td></tr></tbody></table></td></tr>');
var $TPED_tr_h = $('<tr class="metrics-table-header-row"><th class="metrics-table-first-header">Requester</th><th>Submitted</th><th>Projected</th></tr>');
var $TPED_tr_h = $('<tr class="metrics-table-header-row"><th class="metrics-table-first-header">Requester</th><th>Submitted</th><th>Projected</th><th>Hourly</th></tr>');
$("#subtabs_and_searchbar").next().next().after($TPED_table);
$TPED_table.append($TPED_tboday);
$TPED_tboday.append($TPED_tr_1,$TPED_tr_2);
$("#tbody2").append($TPED_tr_h);
$("#fourmEXPORT").click(function(){
var exportcode = "";
var bonus = $("#bonus").text();
if (bonus !== "$0.00"){
var total = (Number(pe)+Number(bonus.replace(/[^0-9.]/g, ""))).toFixed(2);
exportcode += "[b]Today's Projected Earnings: $"+Number(pe).toFixed(2)+" + Bonuses: "+bonus+" = $"+total+"[/b]\n";
}
else {
exportcode += "[b]Today's Projected Earnings: $"+Number(pe).toFixed(2)+"[/b]\n";
}
var today_submitted = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().text();
var today_approved = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().text();
var today_rejected = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().text();
var today_pending = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().text();
exportcode +=
'[spoiler=Today\'s Projected Earnings Overview][table]' +
'[tr][td]Submitted[/td][td]' + today_submitted + '[/td][/tr]' +
'[tr][td]Approved[/td][td]' + today_approved + '[/td][/tr]' +
'[tr][td]Rejected[/td][td]' + today_rejected + '[/td][/tr]' +
'[tr][td]Pending[/td][td]' + today_pending + '[/td][/tr]' +
'[/table][/spoiler]';
GM_setClipboard(exportcode);
alert("Forum Export copied to your clipboard.");
});
$peA.click(function(){
if ($peA.text() === "Today's Projected Earnings"){
var confirmation = confirm("Are you sure you want to recalculate Today's Projected Earnings?");
if (confirmation === true){
TPEhitLOG = {}; TPEdetailsLOG = {}; var TPEhourlyLOG = {}; pe = 0;
$("#tbody2").find("tr.odd, tr.even").remove();
getDATA(today);
$peSPAN.text("$0.00");
}
}
});
$TPE_details.click(function(){
$TPE_details.find("img").attr("src", ($TPE_details.find("img").attr("src") === "/media/more.gif") ? "/media/less.gif" : "/media/more.gif");
$TPED_table.toggle();
});
if (today){
var date = today.split("encodedDate=")[1];
if (date === localStorage.TPE_date){
if (localStorage.TPEhitLOG){
TPEhitLOG = JSON.parse(localStorage.TPEhitLOG);
}
pe = Number(localStorage.TPE_pe) || 0;
$peSPAN.text("$"+Number(pe).toFixed(2));
getDATA(localStorage.TPE_lastpage);
}
else {
localStorage.TPE_date = date;
localStorage.Goal_progress = 0;
TPEhitLOG = {}; pe = 0;
$peSPAN.text("$0.00");
getDATA(today);
}
}
function getDATA(URL){
var page = URL.match(/Number=([0-9]*)/g);
if (page){
$peA.text("Calculating Page "+page.toString().replace(/[^0-9.]/g, ""));
}
else {
localStorage.removeItem("TPEhitLOG");
localStorage.Goal_progress = 0;
$peA.text("Calculating Page 1");
}
$.get(URL, function(data){
var $data = $(data);
var $hits = $data.find("#dailyActivityTable").find("tr[valign='top']");
var pagereqerr = $data.find("td.error_title:contains(You have exceeded the maximum allowed page request rate for this website.)").length;
var noactivity = $data.find("#dailyActivityTable").find("td:contains(You have no HIT activity on this day matching the selected status.)").length;
if ($hits.length){
console.log("hit length");
var url = $data.find("a:contains(Next)[href*=statusdetail]").eq(0).prop("href");
for (var i = 0; i < $hits.length; i++){
var req = $hits.eq(i).find("td.statusdetailRequesterColumnValue").text().trim();
var title = $hits.eq(i).find("td.statusdetailTitleColumnValue").text().trim();
var reward = $hits.eq(i).find("td.statusdetailAmountColumnValue").text().trim();
var status = $hits.eq(i).find("td.statusdetailStatusColumnValue").text().trim();
var reqid = $hits.eq(i).find("a").prop("href").split("requesterId=")[1].split("&")[0];
var hitid = $hits.eq(i).find("a").prop("href").split("HIT+")[1];
if (!TPEhitLOG[hitid]){
TPEhitLOG[hitid] = {
req : req,
title : title,
reward : reward,
status : status,
reqid : reqid,
hitid : hitid
};
}
}
if (url){
getDATA(url);
}
else {
pe = 0;
for(var key in TPEhitLOG){
if (TPEhitLOG[key].status !== "Rejected"){
pe += parseFloat(TPEhitLOG[key].reward.replace(/[^0-9.]/g, ""));
}
if (!TPEdetailsLOG[TPEhitLOG[key].reqid]){
TPEdetailsLOG[TPEhitLOG[key].reqid] = {
req : TPEhitLOG[key].req,
submit : 1,
reward : parseFloat(TPEhitLOG[key].reward.replace(/[^0-9.]/g, "")),
reqid : TPEhitLOG[key].reqid
};
}
else {
TPEdetailsLOG[TPEhitLOG[key].reqid].submit = TPEdetailsLOG[TPEhitLOG[key].reqid].submit + 1;
TPEdetailsLOG[TPEhitLOG[key].reqid].reward = TPEdetailsLOG[TPEhitLOG[key].reqid].reward + parseFloat(TPEhitLOG[key].reward.replace(/[^0-9.]/g, ""));
}
if (!TPEhourlyLOG[TPEhitLOG[key].reqid]){
var time_data = localStorage.getItem('time_data.' + TPEhitLOG[key].hitid.split('&')[0]);
if (time_data != null){
var starts = time_data.split("$#$")[3].split('?');
var last_start = starts[starts.length-1];
var stops = time_data.split("$#$")[4].split('?');
var last_stop = stops[stops.length-1];
if (last_start.length && last_stop.length){
TPEhourlyLOG[TPEhitLOG[key].reqid] = {
req : TPEhitLOG[key].req,
intervals :[[last_start,last_stop]],
totalReward : parseFloat(time_data.split("$#$")[2]),
};
}
}
}
else{
var time_data = localStorage.getItem('time_data.' + TPEhitLOG[key].hitid.split('&')[0]);
if (time_data != null){
var starts = time_data.split("$#$")[3].split('?');
var last_start = starts[starts.length-1];
var stops = time_data.split("$#$")[4].split('?');
var last_stop = stops[stops.length-1];
if (last_start.length && last_stop.length){
TPEhourlyLOG[TPEhitLOG[key].reqid].intervals.push([last_start,last_stop]);
}
TPEhourlyLOG[TPEhitLOG[key].reqid].totalReward += parseFloat(time_data.split("$#$")[2]);
}
}
}
if (!TPEdetailsLOG.bonuses && $("#bonus").length){
TPEdetailsLOG.bonuses = {
req : "Bonuses",
submit : "N/A",
reward : parseFloat($("#bonus").text().replace(/[^0-9.]/g, "")),
reqid : "N/A"
};
}
else if ($("#bonus").length){
TPEdetailsLOG.bonuses.reward = parseFloat($("#bonus").text().replace(/[^0-9.]/g, ""));
}
var d_sorted = Object.keys(TPEdetailsLOG).sort(function(a,b){return TPEdetailsLOG[a].reward - TPEdetailsLOG[b].reward;});
var oddeven = true;
var total_intervals = [];
var total_recorded_earnings = 0;
for (var j = d_sorted.length-1; j > -1; j--){
var dkey = d_sorted[j];
var d_req = TPEdetailsLOG[dkey].req;
var d_submitted = TPEdetailsLOG[dkey].submit;
var d_reward = Number(TPEdetailsLOG[dkey].reward).toFixed(2);
var d_hourly = "N/A";
if (d_req !== "Bonuses" && TPEhourlyLOG[TPEdetailsLOG[dkey].reqid]){
var intervals = TPEhourlyLOG[TPEdetailsLOG[dkey].reqid].intervals;
var d_intervals_sum = 0;
for (i=0;i<intervals.length;i++){
d_intervals_sum += (intervals[i][1]-intervals[i][0]);
}
var d_intervals_avg = d_intervals_sum / intervals.length;
var d_intervals = mergeIntervals(intervals);
d_intervals = combineIntervals(intervals,Math.max(2*60*1000,Math.min(10*d_intervals_avg,10*60*1000)));
total_intervals = total_intervals.concat(d_intervals);
total_recorded_earnings += TPEhourlyLOG[TPEdetailsLOG[dkey].reqid].totalReward;
console.log(d_req, "padding", Math.min(10*d_intervals_avg,10*60*1000)/(60*1000) + " min");
var d_time = 0;
for (i=0;i<d_intervals.length; i++){
var s = new Date(parseInt(d_intervals[i][0]));
var f = new Date(parseInt(d_intervals[i][1]));
console.log(d_req, i, s.toLocaleTimeString(),f.toLocaleTimeString());
d_time += (d_intervals[i][1] - d_intervals[i][0])/(1000*60*60);
}
d_hourly = "$" + (TPEhourlyLOG[TPEdetailsLOG[dkey].reqid].totalReward / d_time).toFixed(2);
}
if (oddeven){
oddeven = false;
$("#tbody2").append('<tr class="odd"><td class="metrics-table-first-value">'+d_req+'</td><td>'+d_submitted+'</td><td><span class="reward">$'+d_reward+'</span></td><td><span class="reward">'+d_hourly+'</span></tr>');
}
else {
oddeven = true;
$("#tbody2").append('<tr class="even"><td class="metrics-table-first-value">'+d_req+'</td><td>'+d_submitted+'</td><td><span class="reward">$'+d_reward+'</span><td><span class="reward">'+d_hourly+'</span></td></tr>');
}
}
total_intervals = mergeIntervals(total_intervals);
var total_time = 0;
for (i=0;i<total_intervals.length; i++){
var s = new Date(parseInt(total_intervals[i][0]));
var f = new Date(parseInt(total_intervals[i][1]));
console.log(i, s.toLocaleTimeString(),f.toLocaleTimeString());
total_time += (total_intervals[i][1] - total_intervals[i][0])/(1000*60*60);
}
var total_hourly = '$' + (total_recorded_earnings/total_time).toFixed(2);
var hour = Math.floor(total_time);
var min = Math.floor((total_time - hour)*60);
var sec = Math.floor((total_time - hour - min/60)*3600);
var time_display = (hour>0?pad(hour,2) + ":":"") + pad(min,2) + ":" + pad(sec,2);
if (oddeven){
oddeven = false;
$("#tbody2").append('<tr class="odd"><td class="metrics-table-first-value">Total Hourly</td><td>'+time_display+'</td><td><span class="reward">$'+total_recorded_earnings.toFixed(2)+'</span></td><td><span class="reward">'+total_hourly+'</span></tr>');
}
else {
oddeven = true;
$("#tbody2").append('<tr class="even"><td class="metrics-table-first-value">Total Hourly</td><td>'+time_display+'</td><td><span class="reward">$'+total_recorded_earnings.toFixed(2)+'</span><td><span class="reward">'+total_hourly+'</span></td></tr>');
}
localStorage.TPEhitLOG = JSON.stringify(TPEhitLOG);
localStorage.TPE_lastpage = URL;
localStorage.TPE_pe = pe;
$peA.text("Today's Projected Earnings");
$peSPAN.text("$"+Number(pe).toFixed(2));
localStorage.Goal_percent = ((Number(localStorage.TPE_pe)/Number(localStorage.Goal_goal))*100);
localStorage.Goal_progress = Number(pe)-Number(localStorage.Goal_goal);
if ($("#goalDIV").length){
$("#progress").width(Number(localStorage.Goal_percent)+"%");
$("#progressper").text(Number(localStorage.Goal_progress).toFixed(2));
}
Unsynced();
}
}
else if (noactivity){
console.log("no activity");
localStorage.TPE_lastpage = URL;
localStorage.TPE_pe = 0;
localStorage.Goal_progress = 0;
$peA.text("Today's Projected Earnings");
$peSPAN.text("$0.00");
}
else if (pagereqerr) {
console.log("set timeout");
setTimeout(function(){ getDATA(URL); }, 2000);
}
});
}
function Unsynced(){
var hitscalced = Object.keys(TPEhitLOG).length;
var submitted = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().text());
if (hitscalced < submitted){
$peSPAN.css({backgroundColor:"red"});
}
else {
$peSPAN.css({backgroundColor:""});
}
}
}
function create_feedback_str(time_data)
{
var last_start = time_data.split("$#$")[3].split('?');
last_start = new Date(parseInt(last_start[last_start.length - 1]));
var last_finish = time_data.split("$#$")[4].split('?');
last_finish = new Date(parseInt(last_finish[last_finish.length - 1]));
console.log(time_data, last_start, last_finish, time_data.split("$#$")[3].split('?'), time_data.split("$#$")[4].split('?'));
var reward = time_data.split("$#$")[2];
var time_spent = last_finish - last_start;
var h = Math.floor(time_spent/(1000*60*60));
var m = Math.floor((time_spent - h*1000*60*60)/(1000*60));
var s = Math.floor((time_spent - h*1000*60*60 - m*1000*60)/(1000));
return "Opened: " + last_start.toLocaleTimeString() + "<br>Submitted: " + last_finish.toLocaleTimeString()+ "<br>Time: " + (h > 0 ? (pad(h,2) + ":"):"") + pad(m,2) + ":" + pad(s,2) + "<br>Hourly: $" + (reward/((last_finish-last_start)/(60*60*1000))).toFixed(2) ;
}
function store_data(action_type)
{
if (action_type.indexOf('Worker') > -1){
if (!hit_returned){
var now_in_milliseconds = new Date().getTime();
var hitReview_hitId = window.location.href.split('tasks/')[1].split('?')[0];
console.log(hitReview_hitId);
var $data_holder = $('a:contains("HIT Details"):eq(0)').parent().attr('data-react-props');
var requester_name = JSON.parse($data_holder).modalOptions.requesterName;
var hit_title = JSON.parse($data_holder).modalOptions.projectTitle;
var hit_reward = JSON.parse($data_holder).modalOptions.monetaryReward.amountInDollars;
var open_list = "";
var close_list = "";
var stored_copy = localStorage.getItem('time_data.' + hitReview_hitId);
if (stored_copy !== null){
open_list = stored_copy.split('$#$')[3];
close_list = stored_copy.split('$#$')[4];
}
if (action_type == "openWorker"){
open_list += "?" + now_in_milliseconds;
}
else if (action_type == "closeWorker"){
close_list += "?" + now_in_milliseconds;
}
var autoapprove_data = requester_name + "$#$" + hit_title + "$#$"+ hit_reward +"$#$" + open_list + "$#$" + close_list;
console.log(autoapprove_data);
localStorage.setItem('time_data.' + hitReview_hitId, autoapprove_data);
}
}
else{
var $isAccepted = $('input[type="hidden"][name="isAccepted"][value="true"]');
if ($isAccepted.length > 0 && !hit_returned)
{
var hitReview_hitId = $('form[name="hitForm"][action="/mturk/hitReview"] input[name="hitId"]').val();
console.log(hitReview_hitId);
var hit_reward = $('form[name="hitForm"][action="/mturk/submit"] input[name="prevReward"]').val().replace('USD','');
console.log(hit_reward);
var requester_name = $('td.capsule_field_title:contains("Requester:"):eq(0)').next().text().trim();
var hit_title = $('table:contains("Requester:"):eq(0) table:eq(0)').text().trim();
var now_in_milliseconds = new Date().getTime();
var open_list = "";
var close_list = "";
var stored_copy = localStorage.getItem('time_data.' + hitReview_hitId);
if (stored_copy !== null){
open_list = stored_copy.split('$#$')[3];
close_list = stored_copy.split('$#$')[4];
}
if (action_type == "open"){
open_list += "?" + now_in_milliseconds;
}
else{
close_list += "?" + now_in_milliseconds;
}
var autoapprove_data = requester_name + "$#$" + hit_title + "$#$"+ hit_reward +"$#$" + open_list + "$#$" + close_list;
console.log(autoapprove_data);
localStorage.setItem('time_data.' + hitReview_hitId, autoapprove_data);
}
}
}
function mergeIntervals(intervals) {
// test if there are at least 2 intervals
if(intervals.length <= 1)
return intervals;
var stack = [];
var top = null;
// sort the intervals based on their start values
intervals = intervals.sort(function (startValue, endValue) {
if (startValue[0] > endValue[0]) {
return 1;
}
if (startValue[0] < endValue[0]) {
return -1;
}
return 0;
});
// push the 1st interval into the stack
stack.push(intervals[0]);
// start from the next interval and merge if needed
for (var i = 1; i < intervals.length; i++) {
// get the top element
top = stack[stack.length - 1];
// if the current interval doesn't overlap with the
// stack top element, push it to the stack
if (top[1] < intervals[i][0]) {
stack.push(intervals[i]);
}
// otherwise update the end value of the top element
// if end of current interval is higher
else if (top[1] < intervals[i][1])
{
top[1] = intervals[i][1];
stack.pop();
stack.push(top);
}
}
return stack;
}
function combineIntervals(intervals, padding) {
// test if there are at least 2 intervals
if(intervals.length <= 1)
return intervals;
var stack = [];
var top = null;
// push the 1st interval into the stack
stack.push(intervals[0]);
// start from the next interval and merge if needed
for (var i = 1; i < intervals.length; i++) {
// get the top element
top = stack[stack.length - 1];
// if the current interval doesn't overlap with the
// stack top element, push it to the stack
if ((intervals[i][0]-top[1]) > padding) {
// console.log("hi",(intervals[i][0]-top[1]) + padding);
stack.push(intervals[i]);
}
// otherwise update the end value of the top element
// if end of current interval is higher
else if (top[1] < intervals[i][1])
{
top[1] = intervals[i][1];
stack.pop();
stack.push(top);
}
}
//console.log("stack",stack);
return stack;
}
function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
function Remove_Old_Data(){
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
if (localStorage.getItem('mturkHourlyRemovalDate') != date){
console.log('mturk hourly data older than 45 days has been cleared');
//thanks to @ChrisTurk for the old key removal code:
Object.keys(localStorage)
.forEach(function(key){
if (/^time_data\./.test(key)) {
console.log(localStorage[key]);
var stored = localStorage[key].split(/\?/).pop(); // grabs last timestamp from the stack
// days * hours * min * sec * 1000 [millisec 'cause of the way its stored]
if (($.now()-stored) > 14*24*60*60*1000) {
// console.log('older than 14 days');
localStorage.removeItem(key); //uncomment this line to delete keys
} else {
// console.log('fresh memes'); //less than 1 day old, don't delete it.
}
}
});
localStorage.setItem('mturkHourlyRemovalDate',date);
}
}
function Goal(){
if (!localStorage.Goal_percent){
localStorage.Goal_percent = 0;
}
if (!localStorage.Goal_progress){
localStorage.Goal_progress = 0;
}
if (!localStorage.Goal_goal){
localStorage.Goal_goal = 25.00;
}
if ($("#bonusDIV").length){
var $goalDIV0 = $('<div id="goalDIV" class="even" style="display:table-row">');
$($goalDIV0).append('<td class="metrics-table-first-value"><div id="progressbar" style="width: 100%; height: 7px; border: 1px solid #7fb4cf; border-radius: 3px; overflow: hidden; margin-top: 3px; text-align: center; -webkit-user-select: none; -moz-user-select: none;"><div id="progress" style="height: 100%; background-color: #7fb4cf; -webkit-user-select: none; -moz-user-select: none;"></div></div></td><td><span id="progressper" class="reward">0%</span></td>');
$("#bonusDIV").after($goalDIV0);
}
else {
var $goalDIV1 = $('<div id="goalDIV" class="odd" style="display:table-row">');
$($goalDIV1).append('<td class="metrics-table-first-value"><div id="progressbar" style="width: 100%; height: 7px; border: 1px solid #7fb4cf; border-radius: 3px; overflow: hidden; margin-top: 3px; text-align: center; -webkit-user-select: none; -moz-user-select: none;"><div id="progress" style="height: 100%; background-color: #7fb4cf; -webkit-user-select: none; -moz-user-select: none;"></div></div></td><td><span id="progressper" class="reward">0%</span></td>');
$("#TPE_div").after($goalDIV1);
}
$("#progress").width(Number(localStorage.Goal_percent)+"%");
$("#progressper").text(Number(localStorage.Goal_progress).toFixed(2));
$("#progressbar").dblclick(function(e){
e.preventDefault();
var goal = prompt("Please enter your goal", localStorage.Goal_goal);
if (goal !== null) {
localStorage.Goal_goal = goal.replace(/[^0-9.]/g, "");
localStorage.Goal_percent = ((Number(localStorage.TPE_pe)/Number(localStorage.Goal_goal))*100);
localStorage.Goal_progress = Number(localStorage.TPE_pe)-Number(localStorage.Goal_goal);
$("#progress").width(Number(localStorage.Goal_progress)+"%");
$("#progressper").text(Number(localStorage.Goal_progress).toFixed(2));
}
});
}
function Todays_Bonuses(){
var today = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).prop("href");
var $bonusDIV = $('<div id="bonusDIV" class="odd" style="display:table-row">');
$($bonusDIV).append('<td class="metrics-table-first-value"><a href="javascript:void(0)">Today\'s Bonuses</a></td><td><span id="bonus" class="reward">$0.00</span></td>');
$("#TPE_div").after($bonusDIV);
if (today){
var date = today.split("encodedDate=")[1];
if (date === localStorage.TB_date){
if (!localStorage.today_start_bonuses){
localStorage.today_start_bonuses = Number($("#bonus_earnings_amount").text().replace(/[^0-9.]/g, ""));
}
Bonuses(localStorage.today_start_bonuses);
}
else {
var today_approved = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().text());
if (today_approved === 0){
localStorage.today_start_bonuses = (Number($("#bonus_earnings_amount").text().replace(/[^0-9.]/g, ""))-Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().next().text().replace(/[^0-9.]/g, "")));
}
else {
localStorage.today_start_bonuses = Number($("#bonus_earnings_amount").text().replace(/[^0-9.]/g, ""));
}
localStorage.TB_date = date;
Bonuses(localStorage.today_start_bonuses);
}
}
function Bonuses(starting_bonus){
var total_bonuses = $("#bonus_earnings_amount").text().replace(/[^0-9.]/g, "");
$("#bonus").text("$"+(Math.round((Number(total_bonuses)-Number(starting_bonus))*100)/100).toFixed(2));
}
}
function Real_Stats(){
var approved = Number($("td.metrics-table-first-value:contains(... Approved)").next().text());
var rejected = Number($("td.metrics-table-first-value:contains(... Rejected)").next().text());
$("td.metrics-table-first-value:contains(... Approved)").next().next().text(Math.round(((approved)/(approved+rejected))*1000000)/10000+"%");
$("td.metrics-table-first-value:contains(... Rejected)").next().next().text(Math.round(((rejected)/(approved+rejected))*1000000)/10000+"%");
}
function Best_Worst_Case(){
var submitted = Number($("td.metrics-table-first-value:contains(HITs Submitted)").next().text());
var rejected = Number($("td.metrics-table-first-value:contains(... Rejected)").next().text());
var approved = Number($("td.metrics-table-first-value:contains(... Approved)").next().text());
var pending = Number($("td.metrics-table-first-value:contains(... Pending)").next().text());
var $under99 = $('<span style="color: orange;"> ('+Math.round((rejected-((1.0 - 99/100)*submitted))/((1.0 - 99/100)-1))+' ≥ 99%)</span>');
var $under95 = $('<span style="color: red;"> ('+Math.round((rejected-((1.0 - 95/100)*submitted))/((1.0 - 95/100)-1))+' ≥ 95%)</span>');
var $worst = $('<span style="color: red;">\n'+Math.round(approved/(approved+rejected+pending) * 1000000)/10000+'%</span>');
$("td.metrics-table-first-value:contains(... Pending)").append($under99,$under95);
$("td.metrics-table-first-value:contains(... Pending)").next().next().text(Math.round(((submitted-rejected)/submitted)*1000000)/10000+"%").css({"color": "green"}).append($worst);
}
function Changes(){
var today = $("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).prop("href");
if (today){
var date = today.split("encodedDate=")[1];
if (date !== localStorage.Changes_date){
localStorage.Changes_date = date;
localStorage.today_submitted = 0;
localStorage.today_approved = 0;
localStorage.today_rejected = 0;
localStorage.today_pending = 0;
}
}
var earnings_hits = Number($("#approved_hits_earnings_amount").text().replace(/[^0-9.]/g, ""));
var earnings_bonuses = Number($("#bonus_earnings_amount").text().replace(/[^0-9.]/g, ""));
var earnings_total = Number($("#total_earnings_amount").text().replace(/[^0-9.]/g, ""));
var earnings_transfer = Number($("#transfer_earnings").text().replace(/[^0-9.]/g, ""));
var hits_submitted = Number($("td.metrics-table-first-value:contains(HITs Submitted)").next().text());
var hits_approved = Number($("td.metrics-table-first-value:contains(... Approved)").next().text());
var hits_rejected = Number($("td.metrics-table-first-value:contains(... Rejected)").next().text());
var hits_pending = Number($("td.metrics-table-first-value:contains(... Pending)").next().text());
var today_submitted = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().text());
var today_approved = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().text());
var today_rejected = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().text());
var today_pending = Number($("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().text());
if (Number(localStorage.earnings_hits) !== earnings_hits){
$("#approved_hits_earnings_amount").prev().append('<span id="earnings_hits" style="float:right;">+$'+(Math.round((earnings_hits-Number(localStorage.earnings_hits))*100)/100).toFixed(2)+'</span>');
localStorage.earnings_hits = earnings_hits;
}
if (Number(localStorage.earnings_bonuses) !== earnings_bonuses){
$("#bonus_earnings_amount").prev().append('<span id="earnings_bonuses" style="float:right;">+$'+(Math.round((earnings_bonuses-Number(localStorage.earnings_bonuses))*100)/100).toFixed(2)+'</span>');
localStorage.earnings_bonuses = earnings_bonuses;
}
if (Number(localStorage.earnings_total) !== earnings_total){
$("#total_earnings_amount").prev().append('<span id="earnings_total" style="float:right;">+$'+(Math.round((earnings_total-Number(localStorage.earnings_total))*100)/100).toFixed(2)+'</span>');
localStorage.earnings_total = earnings_total;
}
if (Number(localStorage.earnings_transfer) !== earnings_transfer){
if (Number(localStorage.earnings_transfer) > earnings_transfer){
$("#transfer_earnings").prev().append('<span id="earnings_transfer" style="float:right;">-$'+(Math.round((Number(localStorage.earnings_transfer)-earnings_transfer)*100)/100).toFixed(2)+'</span>');
}
else {
$("#transfer_earnings").prev().append('<span id="earnings_transfer" style="float:right;">+$'+(Math.round((earnings_transfer-Number(localStorage.earnings_transfer))*100)/100).toFixed(2)+'</span>');
}
localStorage.earnings_transfer = earnings_transfer;
}
if (Number(localStorage.hits_submitted) !== hits_submitted){
$("td.metrics-table-first-value:contains(HITs Submitted)").append('<span id="hits_submitted" style="float:right;">+'+(hits_submitted-Number(localStorage.hits_submitted))+'</span>');
localStorage.hits_submitted = hits_submitted;
}
if (Number(localStorage.hits_approved) !== hits_approved){
$("td.metrics-table-first-value:contains(... Approved)").append('<span id="hits_approved" style="float:right;">+'+(hits_approved-Number(localStorage.hits_approved))+'</span>');
localStorage.hits_approved = hits_approved;
}
if (Number(localStorage.hits_rejected) !== hits_rejected){
$("td.metrics-table-first-value:contains(... Rejected)").append('<span id="hits_rejected" style="float:right;">+'+(hits_rejected-Number(localStorage.hits_rejected))+'</span>');
localStorage.hits_rejected = hits_rejected;
}
if (Number(localStorage.hits_pending) !== hits_pending){
if (Number(localStorage.hits_pending) > hits_pending){
$("td.metrics-table-first-value:contains(... Pending)").append('<span id="hits_pending" style="float:right;">-'+(Number(localStorage.hits_pending)-hits_pending)+'</span>');
}
else {
$("td.metrics-table-first-value:contains(... Pending)").append('<span id="hits_pending" style="float:right;">+'+(hits_pending-Number(localStorage.hits_pending))+'</span>');
}
localStorage.hits_pending = hits_pending;
}
if (Number(localStorage.today_submitted) !== today_submitted){
$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().append('<span id="today_submitted" style="float:left;">+'+(today_submitted-Number(localStorage.today_submitted))+'</span>');
localStorage.today_submitted = today_submitted;
}
if (Number(localStorage.today_approved) !== today_approved){
$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().append('<span id="today_approved" style="float:left;">+'+(today_approved-Number(localStorage.today_approved))+'</span>');
localStorage.today_approved = today_approved;
}
if (Number(localStorage.today_rejected) !== today_rejected){
$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().append('<span id="today_rejected" style="float:left;">+'+(today_rejected-Number(localStorage.today_rejected))+'</span>');
localStorage.today_rejected = today_rejected;
}
if (Number(localStorage.today_pending) !== today_pending){
if (Number(localStorage.today_pending) > today_pending){
$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().append('<span id="today_pending" style="float:left;">-'+(Number(localStorage.today_pending)-today_pending)+'</span>');
}
else {
$("a[href^='/mturk/statusdetail?encodedDate']:contains(Today)").eq(0).parent().next().next().next().next().append('<span id="today_pending" style="float:left;">+'+(today_pending-Number(localStorage.today_pending))+'</span>');
}
localStorage.today_pending = today_pending;
}
}
function Yearly(){
var totalearnings = Number($("#total_earnings_amount").text().replace(/[^0-9.]/g, ""));
var $reward = $("#table_yearly_earnings").find("span.reward");
for (var i = 0; i < $reward.length; i++){
totalearnings -= Number($reward.eq(i).text().replace(/[^0-9.]/g, ""));
}
var earnings2016 = Number((totalearnings).toFixed(2)).toLocaleString("en");
var $thisyear = $('<tr class="odd"><td class="metrics-table-first-value">2017</td><td id="yearly_earnings_amount"><span class="reward">$'+earnings2016+'</span></td></tr>');
$("#table_yearly_earnings").find("tr.metrics-table-header-row").after($thisyear);
}
function Hide_HIT_DB(pending, PEday, PEweek){
var tbody = $("#approved_hits_earnings_amount").parent().parent().addClass("tbody");
var $css = '<style type="text/css">\n';
if (pending){
$css += ".tbody > .odd:nth-child(8), .even:nth-child(8) {display: none;}\n";
}
if (PEday){
$css += ".tbody > .odd:nth-child(9), .even:nth-child(9) {display: none;}\n";
}
if (PEweek){
$css += ".tbody > .odd:nth-child(10), .even:nth-child(10) {display: none;}\n";
}
$("head").append($css);
}
function initialize() {
Object.assign(String.prototype, {
number () {
return Number(this.replace(/[^0-9.]/g, ``));
}
});
const rows = document.getElementById(`dashboard-hits-overview`).getElementsByClassName(`row`);
window.dashboard = {
hits_overview: {
approved: rows[0].getElementsByClassName(`text-xs-right`)[0].textContent.number(),
pending: rows[2].getElementsByClassName(`text-xs-right`)[0].textContent.number(),
rejected: rows[3].getElementsByClassName(`text-xs-right`)[0].textContent.number(),
},
daily_hit_statistics_overview: {
total: {
submitted: 0,
approved: 0,
rejected: 0,
pending: 0,
earnings: 0,
}
},
earnings_to_date: {
bonuses: document.getElementById(`dashboard-earnings-to-date`).getElementsByClassName(`text-xs-right`)[2].textContent.number()
}
};
for (const row of document.getElementsByClassName(`daily_hit_statuses`)) {
const col = row.children;
const date = col[0].children[0].href.match(/([0-9])+/)[0];
window.dashboard.daily_hit_statistics_overview[date] = {};
[`submitted`, `approved`, `rejected`, `pending`, `earnings`].forEach((currentValue, index) => {
const value = col[index + 1].textContent.number();
window.dashboard.daily_hit_statistics_overview[date][currentValue] = value;
window.dashboard.daily_hit_statistics_overview.total[currentValue] += value;
});
}
}
function allApprovedRate() {
const overview = dashboard.hits_overview;
const row = document.createElement(`div`);
row.className = `row m-b-sm`;
const col1 = document.createElement(`div`);
col1.className = `col-xs-7`;
row.appendChild(col1);
const strong = document.createElement(`strong`);
strong.textContent = `All Approved Rate`;
col1.appendChild(strong);
const col2 = document.createElement(`div`);
col2.className = `col-xs-5 text-xs-right`;
col2.textContent = `${((overview.approved + overview.pending) / (overview.approved + overview.pending + overview.rejected) * 100).toFixed(4)}%`;
row.appendChild(col2);
const additional = document.getElementById(`HitsOverviewAdditionalInfo`);
additional.parentNode.insertBefore(row, additional);
}
function allRejectedRate() {
const overview = dashboard.hits_overview;
const row = document.createElement(`div`);
row.className = `row m-b-sm`;
const col1 = document.createElement(`div`);
col1.className = `col-xs-7`;
row.appendChild(col1);
const strong = document.createElement(`strong`);
strong.textContent = `All Rejected Rate`;
col1.appendChild(strong);
const col2 = document.createElement(`div`);
col2.textContent = `${(overview.approved / (overview.approved + overview.rejected + overview.pending) * 100).toFixed(4)}%`;
col2.className = `col-xs-5 text-xs-right`;
row.appendChild(col2);
const additional = document.getElementById(`HitsOverviewAdditionalInfo`);
additional.parentNode.insertBefore(row, additional);
}
function fourDigitPercents() {
const overview = dashboard.hits_overview;
for (const row of document.getElementById(`dashboard-hits-overview`).getElementsByClassName(`row`)) {
if (row.textContent.indexOf(`Approval Rate`) !== -1) {
row.getElementsByClassName(`text-xs-right`)[0].textContent = `${(overview.approved / (overview.approved + overview.rejected) * 100).toFixed(4)}%`;
}
if (row.textContent.indexOf(`Rejection Rate`) !== -1) {
row.getElementsByClassName(`text-xs-right`)[0].textContent = `${(overview.rejected / (overview.approved + overview.rejected) * 100).toFixed(4)}%`;
}
}
}
function rejectionsBelow99() {
const overview = dashboard.hits_overview;
const row = document.createElement(`div`);
row.className = `row m-b-sm`;
const col1 = document.createElement(`div`);
col1.className = `col-xs-7`;
row.appendChild(col1);
const strong = document.createElement(`strong`);
strong.textContent = `Rejections ≤ 99%`;
col1.appendChild(strong);
const col2 = document.createElement(`div`);
col2.textContent = Math.round((overview.rejected - (0.01 * (overview.approved + overview.rejected + overview.pending))) / -0.99).toLocaleString();
col2.className = `col-xs-5 text-xs-right`;
row.appendChild(col2);
const additional = document.getElementById(`HitsOverviewAdditionalInfo`);
additional.insertBefore(row, additional.lastChild);
}
function rejectionsBelow95() {
const overview = dashboard.hits_overview;
const row = document.createElement(`div`);
row.className = `row m-b-sm`;
const col1 = document.createElement(`div`);
col1.className = `col-xs-7`;
row.appendChild(col1);
const strong = document.createElement(`strong`);
strong.textContent = `Rejections ≤ 95%`;
col1.appendChild(strong);
const col2 = document.createElement(`div`);
col2.textContent = Math.round((overview.rejected - (0.05 * (overview.approved + overview.rejected + overview.pending))) / -0.95).toLocaleString();
col2.className = `col-xs-5 text-xs-right`;
row.appendChild(col2);
const additional = document.getElementById(`HitsOverviewAdditionalInfo`);
additional.insertBefore(row, additional.lastChild);
}
function totalLast45Days() {
const table = document.querySelector(`.mturk-table.hits-statuses`);
const row = table.insertRow(1);
row.className = `daily_hit_statuses`;
const date = row.insertCell(0);
date.textContent = `Total`;
date.className = `hidden-xs-down col-sm-2 col-md-2`;
const submitted = row.insertCell(1);
submitted.textContent = window.dashboard.daily_hit_statistics_overview.total.submitted;
submitted.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;
const approved = row.insertCell(2);
approved.textContent = window.dashboard.daily_hit_statistics_overview.total.approved;
approved.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;
const rejected = row.insertCell(3);
rejected.textContent = window.dashboard.daily_hit_statistics_overview.total.rejected;
rejected.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;
const pending = row.insertCell(4);
pending.textContent = window.dashboard.daily_hit_statistics_overview.total.pending;
pending.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;
const earnings = row.insertCell(5);
earnings.textContent = `$${window.dashboard.daily_hit_statistics_overview.total.earnings.toLocaleString(`en-US`, { minimumFractionDigits: 2 })}`;
earnings.className = `text-xs-right col-xs-3 col-sm-2 col-md-2`;
}
function hitStatusChanges() {
const oldDashboard = localStorage.dashboard ? JSON.parse(localStorage.dashboard) : null;
localStorage.dashboard = JSON.stringify(dashboard);
for (const row of document.getElementsByClassName(`daily_hit_statuses`)) {
const col = row.children;
const date = col[0].children[0] ? col[0].children[0].href.match(/([0-9])+/)[0] : `total`;
[`submitted`, `approved`, `rejected`, `pending`, `earnings`].forEach((currentValue, index) => {
const value = col[index + 1].textContent.number();
const oldValue = oldDashboard ? oldDashboard.daily_hit_statistics_overview[date][currentValue] : 0;
if (value !== oldValue) {
const change = value - oldValue;
const changeString = change.toFixed(2).toString().replace(`.00`, ``);
if (Math.round(change * 100) !== 0) {
const span = document.createElement(`span`);
span.textContent = change > 0 ? `+${changeString}` : changeString;
span.style.float = `left`;
span.style.fontSize = `70%`;
col[index + 1].appendChild(span);
}
}
});
}
}
function todaysActivity() {
const container = document.createElement(`div`);
container.className = `row m-b-xl`;
const col = document.createElement(`div`);
col.className = `col-xs-12`;
container.appendChild(col);
const h2 = document.createElement(`h2`);
h2.className = `m-b-md`;
h2.textContent = `Today's Activity`;
col.appendChild(h2);
const row = document.createElement(`div`);
row.className = `row`;
col.appendChild(row);
const col2 = document.createElement(`div`);
col2.className = `col-xs-12`;
row.appendChild(col2);
const border = document.createElement(`div`);
border.className = `border-gray-lightest p-a-sm`;
col2.appendChild(border);
const earningsRow = document.createElement(`div`);
earningsRow.className = `row m-b-sm`;
border.appendChild(earningsRow);
const earningsText = document.createElement(`div`);
earningsText.className = `col-xs-7 col-sm-6 col-lg-7`;
earningsRow.appendChild(earningsText);
const earningsStrong = document.createElement(`strong`);
earningsStrong.textContent = `Projected Earnings`;
earningsText.appendChild(earningsStrong);
const earningsValue = document.createElement(`div`);
earningsValue.className = `col-xs-5 col-sm-6 col-lg-5 text-xs-right`;
earningsValue.textContent = localStorage.todaysearnings || `$0.00`;
earningsRow.appendChild(earningsValue);
const bonusesRow = document.createElement(`div`);
bonusesRow.className = `row m-b-sm`;
border.appendChild(bonusesRow);
const bonusesText = document.createElement(`div`);
bonusesText.className = `col-xs-7 col-sm-6 col-lg-7`;
bonusesRow.appendChild(bonusesText);
const bonusesStrong = document.createElement(`strong`);
bonusesStrong.textContent = `Bonuses`;
bonusesText.appendChild(bonusesStrong);
const bonusesValue = document.createElement(`div`);
bonusesValue.className = `col-xs-5 col-sm-6 col-lg-5 text-xs-right`;
bonusesValue.textContent = localStorage.todaysbonuses || `$0.00`;
bonusesRow.appendChild(bonusesValue);
const hourlyRow = document.createElement(`div`);
hourlyRow.className = `row m-b-sm`;
border.appendChild(hourlyRow);
const hourlyText = document.createElement(`div`);
hourlyText.className = `col-xs-6 col-sm-6 col-lg-6`;
hourlyRow.appendChild(hourlyText);
const hourlyStrong = document.createElement(`strong`);
hourlyStrong.textContent = `Total Hourly`;
hourlyText.appendChild(hourlyStrong);
const hourlyTime = document.createElement(`div`);
hourlyTime.className = `col-xs-3 col-sm-3 col-lg-3 text-xs-right`;
hourlyTime.textContent = `00:00:00`;
hourlyRow.appendChild(hourlyTime);
const hourlyValue = document.createElement(`div`);
hourlyValue.className = `col-xs-3 col-sm-3 col-lg-3 text-xs-right`;
hourlyValue.textContent = `$0.00`;
hourlyRow.appendChild(hourlyValue);
const collapse = document.createElement(`div`);
collapse.id = `TodaysActivityAdditionalInfo`;
collapse.className = `collapse`;
border.appendChild(collapse);
const hr = document.createElement(`hr`);
hr.className = `m-b-sm m-t-0`;
collapse.appendChild(hr);
const hr2 = document.createElement(`hr`);
hr2.className = `m-b-sm m-t-0`;
border.appendChild(hr2);
const control = document.createElement(`a`);
control.className = `collapse-more-less`;
control.href = `#TodaysActivityAdditionalInfo`;
control.setAttribute(`aria-controls`, `TodaysActivityAdditionalInfo`);
control.setAttribute(`aria-expanded`, `false`);
control.setAttribute(`data-toggle`, `collapse`);
border.appendChild(control);
const more = document.createElement(`span`);
more.className = `more`;
control.appendChild(more);
const plus = document.createElement(`i`);
plus.className = `fa fa-plus-circle`;
more.appendChild(plus);
const moreText = document.createTextNode(`\nMore\n`);
more.appendChild(moreText);
const less = document.createElement(`span`);
less.className = `less`;
control.appendChild(less);
const minus = document.createElement(`i`);
minus.className = `fa fa-minus-circle`;
less.appendChild(minus);
const lessText = document.createTextNode(`\nLess\n`);
less.appendChild(lessText);
const side = document.querySelector(`.col-md-push-8`);
side.insertBefore(container, side.firstChild);
const today = document.querySelector(`a[href^="https://www.mturk.com/mturk/statusdetail"]`);
if (today.textContent === `Today`) {
const date = today.href.match(/([0-9])+/)[0];
if (date === localStorage.WMTD_date) {
if (!localStorage.WMTD_bonusStart) {
localStorage.WMTD_bonusStart = window.dashboard.earnings_to_date.bonuses;
}
}
else {
if (window.dashboard.daily_hit_statistics_overview[date].approved === 0) {
localStorage.WMTD_bonusStart = dashboard.earnings_to_date.bonuses - dashboard.daily_hit_statistics_overview[date].earnings;
}
else {
localStorage.WMTD_bonusStart = dashboard.earnings_to_date.bonuses;
}
}
bonusesValue.textContent = `$${(dashboard.earnings_to_date.bonuses - localStorage.WMTD_bonusStart).toLocaleString(`en-US`, { minimumFractionDigits: 2 })}`;
const hitLog = date === localStorage.WMTD_date ? localStorage.WMTD_hitLog ? JSON.parse(localStorage.WMTD_hitLog) : {} : {};
const get = async (url, rescan) => {
try {
const page = url.match(/Number=([0-9]*)/);
earningsValue.textContent = `Calculating Page ${page ? page[1] : `1`}`;
const response = await new Promise((resolve) => {
GM_xmlhttpRequest({
method: `GET`,
url: url,
onload: resolve
});
});
const text = response.responseText;
if (text.indexOf(`You have exceeded the maximum allowed page request rate for this website.`) !== -1) {
return setTimeout(get, 2000, url, rescan);
}
if (text.indexOf(`You have no HIT activity on this day matching the selected status.`) !== -1) {
return false;
}
localStorage.WMTD_lastPage = url;
const doc = new DOMParser().parseFromString(text, `text/html`);
const hits = doc.getElementById(`dailyActivityTable`).querySelectorAll(`tr[valign="top"]`);
if (hits.length) {
for (const hit of hits) {
const td = hit.children;
const obj = {
req: td[0].textContent.trim(),
tit: td[1].textContent.trim(),
rew: td[2].textContent.trim().number(),
sta: td[3].textContent.trim(),
rid: td[0].getElementsByTagName(`a`)[0].href.match(/requesterId=([A-Z0-9]+)/)[1],
hid: td[0].getElementsByTagName(`a`)[0].href.match(/hitId=([A-Z0-9]+)/)[1]
};
hitLog[obj.hid] = obj;
}
const logLength = Object.keys(hitLog).length;
const expectedLength = (page ? page[1].number() * 25 - 25 : 0) + hits.length;
if (!rescan && logLength !== expectedLength) {
return get(today.href, true);
}
else {
localStorage.WMTD_hitLog = JSON.stringify(hitLog);
}
const next = doc.querySelector(`img[src="/media/right_arrow.gif"]`);
if (next) {
return get(next.parentElement.href.replace(`worker`, `www`), rescan);
}
else {
let projectedEarnings = 0;
const reqLog = {};
const hourlyLog = {};
const gmHourlyLog = {};
for (const key in hitLog) {
if (hitLog[key].status !== `Rejected`) {
projectedEarnings += hitLog[key].rew;
}
if (!reqLog[hitLog[key].rid]){
reqLog[hitLog[key].rid] = {
req: hitLog[key].req,
submit: 1,
reward: hitLog[key].rew,
reqid: hitLog[key].rid
};
}
else {
reqLog[hitLog[key].rid].submit += 1;
reqLog[hitLog[key].rid].reward += hitLog[key].rew;
}
if (!hourlyLog[hitLog[key].reqid]){
var time_data = localStorage.getItem('time_data.' + hitLog[key].hid.split('&')[0]);
if (time_data != null){
gmHourlyLog[hitLog[key].hid] = time_data;
var starts = time_data.split("$#$")[3].split('?');
var last_start = starts[starts.length-1];
var stops = time_data.split("$#$")[4].split('?');
var last_stop = stops[stops.length-1];
if (last_start.length && last_stop.length){
hourlyLog[hitLog[key].rid] = {
req : hitLog[key].req,
intervals :[[last_start,last_stop]],
totalReward : parseFloat(time_data.split("$#$")[2]),
};
}
}
}
else{
var time_data = localStorage.getItem('time_data.' + hitLog[key].hid.split('&')[0]);
if (time_data != null){
gmHourlyLog[hitLog[key].hid] = time_data;
var starts = time_data.split("$#$")[3].split('?');
var last_start = starts[starts.length-1];
var stops = time_data.split("$#$")[4].split('?');
var last_stop = stops[stops.length-1];
if (last_start.length && last_stop.length){
hourlyLog[hitLog[key].rid].intervals.push([last_start,last_stop]);
}
hourlyLog[hitLog[key].rid].totalReward += parseFloat(time_data.split("$#$")[2]);
}
}
}
console.log(gmHourlyLog);
GM_setValue('gmHourlyLog',JSON.stringify(gmHourlyLog));
const sort = Object.keys(reqLog).sort((a, b) => reqLog[a].reward - reqLog[b].reward);
const fragment = document.createDocumentFragment();
var total_intervals = [];
var total_recorded_earnings = 0;
for (var j = sort.length-1; j > -1; j--){
var dkey = sort[j];
var d_req = reqLog[dkey].req;
var d_submitted = reqLog[dkey].submit;
var d_reward = Number(reqLog[dkey].reward).toFixed(2);
var d_hourly = "N/A";
if (d_req !== "Bonuses" && hourlyLog[reqLog[dkey].reqid]){
var intervals = hourlyLog[reqLog[dkey].reqid].intervals;
var d_intervals_sum = 0;
for (i=0;i<intervals.length;i++){
d_intervals_sum += (intervals[i][1]-intervals[i][0]);
}
var d_intervals_avg = d_intervals_sum / intervals.length;
var d_intervals = mergeIntervals(intervals);
d_intervals = combineIntervals(intervals,Math.max(2*60*1000,Math.min(10*d_intervals_avg,10*60*1000)));
total_intervals = total_intervals.concat(d_intervals);
total_recorded_earnings += hourlyLog[reqLog[dkey].reqid].totalReward;
var d_time = 0;
for (i=0;i<d_intervals.length; i++){
var s = new Date(parseInt(d_intervals[i][0]));
var f = new Date(parseInt(d_intervals[i][1]));
console.log(d_req, i, s.toLocaleTimeString(),f.toLocaleTimeString());
d_time += (d_intervals[i][1] - d_intervals[i][0])/(1000*60*60);
}
d_hourly = "$" + (hourlyLog[reqLog[dkey].reqid].totalReward / d_time).toFixed(2);
}
reqLog[dkey].hourly = d_hourly;
}
total_intervals = mergeIntervals(total_intervals);
var total_time = 0;
for (i=0;i<total_intervals.length; i++){
var s = new Date(parseInt(total_intervals[i][0]));
var f = new Date(parseInt(total_intervals[i][1]));
console.log(i, s.toLocaleTimeString(),f.toLocaleTimeString());
total_time += (total_intervals[i][1] - total_intervals[i][0])/(1000*60*60);
}
var total_hourly = '$' + (total_recorded_earnings/total_time).toFixed(2);
var hour = Math.floor(total_time);
var min = Math.floor((total_time - hour)*60);
var sec = Math.floor((total_time - hour - min/60)*3600);
var time_display = (hour>0?pad(hour,2) + ":":"") + pad(min,2) + ":" + pad(sec,2);
hourlyValue.textContent = total_hourly;
hourlyTime.textContent = time_display;
for (let i = sort.length - 1; i > -1; i--) {
const key = sort[i];
const req = reqLog[key].req;
const submit = reqLog[key].submit;
const reward = `$${reqLog[key].reward.toLocaleString(`en-US`, { minimumFractionDigits: 2 })}`;
const hourly = reqLog[key].hourly;
const reqRow = document.createElement(`div`);
reqRow.className = `row m-b-sm`;
fragment.appendChild(reqRow);
const requester = document.createElement(`div`);
requester.className = `col-xs-6`;
reqRow.appendChild(requester);
const requesterStrong = document.createElement(`strong`);
requesterStrong.textContent = req;
requester.appendChild(requesterStrong);
const submitValue = document.createElement(`div`);
submitValue.className = `col-xs-2 text-xs-right`;
submitValue.textContent = submit;
reqRow.appendChild(submitValue);
const rewardValue = document.createElement(`div`);
rewardValue.className = `col-xs-2 text-xs-right`;
rewardValue.textContent = reward;
reqRow.appendChild(rewardValue);
const hourlyValue = document.createElement(`div`);
hourlyValue.className = `col-xs-2 text-xs-right`;
hourlyValue.textContent = hourly;
reqRow.appendChild(hourlyValue);
}
collapse.appendChild(fragment);
earningsValue.textContent = `$${projectedEarnings.toLocaleString(`en-US`, { minimumFractionDigits: 2 })}`;
}
}
}
catch (error) {
console.error(error);
}
};
get(date === localStorage.WMTD_date ? localStorage.WMTD_lastPage ? localStorage.WMTD_lastPage : today.href : today.href, false);
localStorage.WMTD_date = date;
}
else {
earningsValue.textContent = `N/A`;
bonusesValue.textContent = `N/A`;
}
}