MTurk Time Tracker

Manual time tracking for MTurk. Use with MTurk Status Page Chart.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name        MTurk Time Tracker
// @namespace   localhost
// @author      ThirdClassInternationalMasterTurker
// @description Manual time tracking for MTurk. Use with MTurk Status Page Chart.
// @include     https://www.mturk.com/mturk/*
// @exclude     https://www.mturk.com/mturk/status*
// @version     0.3.5
// @grant       none
// ==/UserScript==

//
// 2012-09-14 First public release by ThirdClassInternationalMasterTurker
//
// 2012-09-15 0.3 Added some HIT tracking.
//                Show number of hits, time, estimated reward and hourly rate for latest activity
//                and projected earnings and hourly rate for today.
//
// 2012-09-16 0.3.1 Bug fix
//            0.3.2 Better use of caching
//
// 2012-09-19 0.3.3 exclude https://www.mturk.com/mturk/status*
//
// 2012-10-11 0.3.4 Bug fix in format_date() (Integer/String mixup)
//
// 2012-12-02 0.3.5: Added @downloadURL and @updateURL
//

/* ------------------------------------------------------------------------- */
TRACK_HITS = true;
/* ------------------------------------------------------------------------- */

// Stolen from Today's Projected Earnings (http://userscripts.org/scripts/show/95331)
function getHTTPObject()  
{ 
   if (typeof XMLHttpRequest != 'undefined')
   { 
      return new XMLHttpRequest();
   }
   try
   { 
      return new ActiveXObject("Msxml2.XMLHTTP");
   } 
   catch (e) 
   { 
      try
      { 
         return new ActiveXObject("Microsoft.XMLHTTP"); 
      } 
      catch (e) {} 
   } 
   return false;
}

// Stolen from Today's Projected Earnings (http://userscripts.org/scripts/show/95331)
function process_page(link)
{
   var page = getHTTPObject();
   page.open("GET", link, false);      
   page.send(null);
   return parse_data(page.responseText); 
}

// Partly stolen from Today's Projected Earnings (http://userscripts.org/scripts/show/95331)
function parse_data(page_text) {
   var sub_total = 0;
   var rejected_rewards = 0;
   var rejected = 0;
   var index = 0;
   var page_html = document.createElement('div');
   var data = { hits: 0, rewards: 0, rejected: 0, rejected_rewards: 0 };
   page_html.innerHTML = page_text;

   var amounts = page_html.getElementsByClassName('statusdetailAmountColumnValue');
   var statuses = page_html.getElementsByClassName('statusdetailStatusColumnValue');

   for(var k = 0; k < amounts.length; k++)
   {
      if(statuses[k].innerHTML == 'Rejected') {
         data.rejected += 1;
         index = amounts[k].innerHTML.indexOf('$');
         data.rejected_rewards += parseFloat(amounts[k].innerHTML.substring(index+1));
      }
      else {
         index = amounts[k].innerHTML.indexOf('$');
         data.rewards += parseFloat(amounts[k].innerHTML.substring(index+1));
      }
   }
   data.hits = amounts.length;
   return data;
}

// Gets status details for given date (MMDDYYYY)
function getHITData(dataDate, cache) {
  var page;
  var data;
  var status = {hits:0,rewards:0, full_pages:0, full_page_rewards: 0, pages_fetched: 0, time: 0};
  if (typeof dataDate == 'undefined') dataDate = format_date(convert_timezone(new Date()));
  if (typeof cache == 'undefined') cache = true;

  if (localStorage["STATUS " + dataDate]) {
    status = JSON.parse(localStorage["STATUS " + dataDate]);
    if (status.time && (status.time > convert_timezone(new Date()).getTime() - 43200000 )) {
      page = status.full_pages+1;
      status.hits = status.full_pages*25;
      status.rewards = status.full_page_rewards;
      status.pages_fetched = 0;
    }
    else {
      status = {hits:0,rewards:0, full_pages:0, full_page_rewards: 0, pages_fetched: 0, time: 0};
    }
  }
  else {
    page = 1;
  }
  for(page; page < 150; page++)
  {
     detailed_status_page_link = "https://www.mturk.com/mturk/statusdetail?sortType=All&pageNumber=" + page + "&encodedDate=" + dataDate;            
     data = process_page(detailed_status_page_link);
     status.pages_fetched += 1;

     if (data.hits == 0)
       break;

     if (data.hits == 25) {
       status.full_pages += 1;
       status.full_page_rewards += data.rewards;
     }
     status.hits += data.hits;
     status.rewards += data.rewards;
     
  }
  status.time = convert_timezone(new Date()).getTime();

  if (cache) {
    localStorage["STATUS " + dataDate] = JSON.stringify(status);
  }
  return status;
}

function getHITDataFromCache(dataDate) {
  if (typeof dataDate == 'undefined') dataDate = format_date(convert_timezone(new Date()));

  if (localStorage["STATUS " + dataDate])
    return JSON.parse(localStorage["STATUS " + dataDate]);
  return null;
}

function formatTime(msec) {
    if (isNaN(msec))
      return "-";
    var seconds = Math.floor(msec / 1000) % 60;
    var minutes = Math.floor((msec / 1000) / 60) % 60;
    var hours = Math.floor(((msec / 1000) / 60) / 60) % 24;

    if (hours > 0)
      seconds = "";
    else
      seconds = "" + seconds + "s";
    minutes == 0 ? minutes = "" : minutes = "" + minutes + "m ";
    hours == 0   ? hours = "" : hours = "" + hours + "h ";

    return hours + minutes + seconds;
}

function format_date(t) {
  var dateString = '';
  var tempMonth = t.getMonth()+1;
  var tempDate = t.getDate();
  if (tempMonth < 10) tempMonth = '0' + tempMonth;
  if (tempDate < 10) tempDate = '0' + tempDate;
  dateString = '' + tempMonth + tempDate + t.getFullYear();
  return dateString;
}

// FIX!? 
function convert_timezone(t) {
  d = new Date();
  utc = d.getTime() + (d.getTimezoneOffset() * 60000);

  // What is MTurk timezone. UTC-8??
  t_mturk = new Date(utc + (3600000*-8));

  return t_mturk;
}

function formatTime(msec) {
    if (isNaN(msec))
      return "-";
    var seconds = Math.floor(msec / 1000) % 60;
    var minutes = Math.floor((msec / 1000) / 60) % 60;
    var hours = Math.floor(((msec / 1000) / 60) / 60) % 24;

    if (hours > 0)
      seconds = "";
    else
      seconds = "" + seconds + "s";
    minutes == 0 ? minutes = "" : minutes = "" + minutes + "m ";
    hours == 0   ? hours = "" : hours = "" + hours + "h ";

    return hours + minutes + seconds;
}

function worked_today() {
    var today = parseInt(localStorage[format_date(convert_timezone(new Date()))]);
    var status = getHITDataFromCache();
    if (isNaN(today))
      today = 0;

    if (status == null)
      stat_line = "";
    else
      stat_line = " (~$" + status.rewards.toFixed(2) + " = $" + (status.rewards/(today/1000/60/60)).toFixed(2) + "/h)";
      

    if (localStorage["LOG"] == "true") {
      today += (convert_timezone(new Date()).getTime()) - parseInt(localStorage["LOG START"]);

      var time = time_worked();
      return formatTime(today) + stat_line + ") <br><span style=\"color: red\"> Working...</span> " + formatTime(time);
    }

    return formatTime(today) + stat_line + "<br> " + localStorage["LATEST ACTIVITY"];
}
function time_worked() {
  if (localStorage["LOG"] && localStorage["LOG"] == "true") {
    var t = convert_timezone(new Date());
    start = new Date(parseInt(localStorage["LOG START"]));
    return (t.getTime()-start.getTime());
  }
  return 0;
}

// FIX handle midnights...
function toggle_logger() {
  var t = convert_timezone(new Date());

  if (localStorage["LOG"] == "true") {
    localStorage["LOG"] = "false";
    start = new Date(parseInt(localStorage["LOG START"]));
    var today = parseInt(localStorage[format_date(t)]);
    if (isNaN(today))
      today = 0;
    var time_used = t.getTime()-start.getTime();
    localStorage[format_date(t)] = "" + (today + (t.getTime()-start.getTime()));
    this.style.color = 'green';
    this.textContent = 'Start';

    if (TRACK_HITS) {
      var prev_status = getHITDataFromCache();
      var status = getHITData();

      var hits_done = status.hits - prev_status.hits;
      var rewards   = status.rewards - prev_status.rewards;

      localStorage["LATEST ACTIVITY"] = "HITS: " + hits_done + " REWARD: $" + rewards.toFixed(2) +
                                        " TIME: " + formatTime(time_used) + " $" + (rewards/(time_used/1000/60/60)).toFixed(2) + "/h";
    }
  }
  else {
    localStorage["LOG"] = "true";
    localStorage["LOG START"] = t.getTime();
    this.style.color = 'red';
    this.textContent = 'Stop';

    if (TRACK_HITS) {
      getHITData();
    }
  }
};

if (true) {
  /* temporary fix */
  for (var i=0; i<7; i++)
  {
    if (localStorage["" + (2032+i)])
    {
      alert("MTurk Time Tracker fixing: " + "101" + i + "2012");
      localStorage["101" + i + "2012"] = localStorage["" + (2032+i)];
      delete localStorage["" + (2032+i)];
    }
  }
  /* ------------- */

  var elements = document.getElementsByClassName('header_links');
  var newrow = document.createElement('tr');
  elements[0].parentNode.parentNode.parentNode.appendChild(newrow);
  newrow.innerHTML += "<td><button type=\"button\" id=\"toggle_logger\">X</button>" +
                      "Worked today: <span id=\"worked_today\">" + worked_today() + "</span></td>";
  toggle_button = document.getElementById('toggle_logger');
  toggle_button.addEventListener("click", toggle_logger, false);
  localStorage["LOG"] == "true" ? toggle_button.style.color = 'red' : toggle_button.style.color = 'green';
  localStorage["LOG"] == "true" ? toggle_button.textContent = 'Stop' : toggle_button.textContent = 'Start';

  worked = document.getElementById('worked_today');
  setInterval(function(){worked.innerHTML = worked_today();},1000);
  setInterval(function(){  localStorage["LOG"] == "true" ? toggle_button.style.color = 'red' : toggle_button.style.color = 'green';
  localStorage["LOG"] == "true" ? toggle_button.textContent = 'Stop' : toggle_button.textContent = 'Start';},5000);
}
else {
//
}