mmmturkeybacon Expected Earnings - Approved (Awaiting Payment) Earnings

Shows the total earnings from all HITs over the past 30 days which have been recently approved but not yet paid out.

当前为 2015-03-22 提交的版本,查看 最新版本

// ==UserScript==
// @name        mmmturkeybacon Expected Earnings - Approved (Awaiting Payment) Earnings
// @author      mmmturkeybacon
// @description Shows the total earnings from all HITs over the past 30 days which have been recently approved but not yet paid out.
// @namespace   http://userscripts.org/users/523367
// @match       https://www.mturk.com/mturk/dashboard
// @require     https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
// @version     1.05
// @grant       GM_xmlhttpRequest
// ==/UserScript==


var DATE_LIST_DELAY = 500;
var STATUSDETAIL_DELAY = 500;
var MPRE_DELAY = 2000;
var APPROVED_PENDING_EARNINGS_DIV_TEXT = 'Approved (Awaiting Payment) Earnings ';

var global_run = false;
var statusdetail_loop_finished = false;
var total = 0;
var page_num = 1;

var approved_pending_earnings_div = document.createElement("DIV");
var approved_pending_earnings_field = document.createElement("TD");

//var amazon_timezone_offset = -25200000; //PDT:-25200000, PST:-28800000
var amazon_timezone_offset = parseInt(getCookie('mmmturkeybacon_seven_days_dashboard_amazon_timezone_offset'), 10);
if (!amazon_timezone_offset)
{
    GM_xmlhttpRequest(
    {
        method: 'GET',
        url: 'https://maps.googleapis.com/maps/api/timezone/json?location=47.6097,-122.3331&timestamp='+(new Date()).getTime()/1000+'&sensor=false',
        synchronous: true,
        onload: function (results)
        {
            var rdata = $.parseJSON(results.responseText);
            amazon_timezone_offset = rdata['dstOffset']*1000 + rdata['rawOffset']*1000;
            setCookie('mmmturkeybacon_seven_days_dashboard_amazon_timezone_offset', amazon_timezone_offset, 1);
        }
    });
}

var amazon_time_ms = (new Date()).getTime() + amazon_timezone_offset;

function set_progress_report(text, force)
{
    if (global_run == true || force == true)
    {
        approved_pending_earnings_div.innerHTML = text;
    }
}

function wait_until_finished()
{
    if (global_run == true)
    {
        if (statusdetail_loop_finished == true)
        {
            global_run = false;
            approved_pending_earnings_div.innerHTML = APPROVED_PENDING_EARNINGS_DIV_TEXT;
            approved_pending_earnings_field.innerHTML = '$' + (total/100).toFixed(2);
            setCookie('mmmturkeybacon_approved_pending_earnings_total', total, 1);
        }
        else
        {
            setTimeout(function(){wait_until_finished();}, 500);
        }
    }
}

function scrape($src)
{
    var $reward = $src.find('td[class="statusdetailAmountColumnValue"]');

    for (var j = 0; j < $reward.length; j++)
    {
        // I"m worried if I use parseFloat errors will accumulate because floats are inexact
        var reward = parseInt($reward.eq(j).text().replace(/[^0-9]/g,''), 10);
        total += reward;
    }
}

function statusdetail_loop(next_URL)
{
    if (global_run == true)
    {
        if (next_URL.length != 0)
        {
            $.get(next_URL, function(data)
            {
                var $src = $(data);
                var maxpagerate = $src.find('td[class="error_title"]:contains("You have exceeded the maximum allowed page request rate for this website.")');
                if (maxpagerate.length == 0)
                {
                    var date_header = $src.find("td[class='white_text_14_bold']:contains('HITs You Worked On For')").text().replace(/HITs You Worked On For|\(What\'s this\?\)/g, '').trim();
                    set_progress_report('Processing ' + date_header + ' - page ' + page_num);
                    page_num++;
                    scrape($src);
     
                    $next_URL = $src.find('a[href^="/mturk/statusdetail"]:contains("Next")');
                    next_URL = ($next_URL.length != 0) ? $next_URL.attr("href") : "";
                    setTimeout(function(){statusdetail_loop(next_URL);}, STATUSDETAIL_DELAY);
                }
                else
                {
                    setTimeout(function(){statusdetail_loop(next_URL);}, MPRE_DELAY);
                }
            });
        }
        else
        {
            statusdetail_loop_finished = true;
        }
    }
}

function date_list_loop(date_URLs)
{
    if (global_run == true)
    {
        if (date_URLs.length != 0)
        {
            if (statusdetail_loop_finished == true)
            {
                page_num = 1;
                statusdetail_loop_finished = false;

                var next_URL = date_URLs.pop() + '&sortType=Approved&pageNumber=1';
                statusdetail_loop(next_URL);

                setTimeout(function(){date_list_loop(date_URLs);}, DATE_LIST_DELAY);
            }
            else
            {
                setTimeout(function(){date_list_loop(date_URLs);}, DATE_LIST_DELAY);
            }
        }
        else
        {
            wait_until_finished();
        }
    }
}

function draw_interface()
{
    var new_row = document.createElement("tr");
    new_row.id = 'approved_pending_earnings';

    var approved_pending_earnings_clear_cookies_div = document.createElement('DIV');
    approved_pending_earnings_clear_cookies_div.innerHTML = '<font color="red">x</font>';
    approved_pending_earnings_clear_cookies_div.title = 'Click to clear and recalculate.';
    approved_pending_earnings_clear_cookies_div.style.cssText = 'display: inline; cursor: pointer';
    approved_pending_earnings_clear_cookies_div.onclick = function(){clearCookies(); start_running();};

    approved_pending_earnings_div.title = 'Earnings from HITs that have been approved, but not yet paid out. Click to calculate/stop.';
    approved_pending_earnings_div.style.cssText = 'display: inline; cursor: pointer';
    approved_pending_earnings_div.onclick = function(){start_running();};

    var approved_pending_earnings_div_cell = document.createElement("td");
    approved_pending_earnings_div_cell.className = 'metrics-table-first-value';
    approved_pending_earnings_div_cell.style.paddingLeft = '3px';
    approved_pending_earnings_div_cell.appendChild(approved_pending_earnings_clear_cookies_div);
    approved_pending_earnings_div_cell.appendChild(document.createTextNode(' '));
    approved_pending_earnings_div_cell.appendChild(approved_pending_earnings_div);

    new_row.appendChild(approved_pending_earnings_div_cell);
    new_row.appendChild(approved_pending_earnings_field);

    var $expected_earnings_header = $('tr[id="expected_earnings_row"]');
    if ($expected_earnings_header.length > 0)
    {
        // Approved, Pending, Projected Month, Projected Week, Projected Today
        $expected_earnings_header.after(new_row);
        $expected_earnings_header.nextAll('tr').each(function(index)
        {
            $(this).attr('class', ((index % 2 == 0) ? 'odd' : 'even'));
        });
    }
    else
    {
        var $transfer_earnings_row = $('a[href="/mturk/transferearnings"]:contains("Transfer Earnings")').parent().parent();
        $transfer_earnings_row.after('<tr id="expected_earnings_row" class="metrics-table-header-row"><th class="metrics-table-first-header">Expected Earnings</th><th>Value</th></tr>');
        $expected_earnings_header = $('tr[id="expected_earnings_row"]');
        new_row.className = 'odd';
        $expected_earnings_header.after(new_row);
    }

    approved_pending_earnings_div.innerHTML = APPROVED_PENDING_EARNINGS_DIV_TEXT;
    approved_pending_earnings_field.innerHTML = '$?.??';
    var saved_total = parseInt(getCookie('mmmturkeybacon_approved_pending_earnings_total'), 10);
    if (saved_total)
    {
        approved_pending_earnings_field.innerHTML = '$' + (saved_total/100).toFixed(2);
    }
}


function start_running()
{
    if (global_run == false)
    {
        global_run = true;
        statusdetail_loop_finished = true;
        total = 0;
        page_num = 1;

        approved_pending_earnings_div.innerHTML = APPROVED_PENDING_EARNINGS_DIV_TEXT;
        approved_pending_earnings_field.innerHTML = '$?.??';

        $.get('/mturk/status', function(data)
        {
            var $src = $(data);
            var maxpagerate = $src.find("td[class='error_title']:contains('You have exceeded the maximum allowed page request rate for this website.')");
            if (maxpagerate.length == 0)
            {
                var thirty_days_ago = new Date(amazon_time_ms);
                thirty_days_ago.setUTCDate(thirty_days_ago.getUTCDate() - 30);
                //http://stackoverflow.com/questions/3605214/javascript-add-leading-zeroes-to-date
                var thirty_days_ago_date = ('0' + (thirty_days_ago.getUTCMonth()+1)).slice(-2) + ('0' + thirty_days_ago.getUTCDate()).slice(-2) + thirty_days_ago.getUTCFullYear();

                var date_URLs = new Array();
                $src.find('td[class="statusApprovedColumnValue"]').filter(function(){return($(this).text() != '0')}).siblings('td[class="statusDateColumnValue"]').children('a[href^="/mturk/statusdetail"]').filter(function(){return ($(this).attr('href').substring(32) >= thirty_days_ago_date);}).each(function(){date_URLs.push($(this).attr('href'));});

                date_list_loop(date_URLs);
            }
        });
    }
    else
    {
        global_run = false; // this will stop scraping pages prematurely
        approved_pending_earnings_div.innerHTML = APPROVED_PENDING_EARNINGS_DIV_TEXT + '- stoppped! ';
        approved_pending_earnings_field.innerHTML = '$?.??';
    }
}

//
//  Cookie functions copied from http://www.w3schools.com/JS/js_cookies.asp
//

function setCookie(c_name,value,exdays)
{
   var exdate=new Date(); 
   exdate.setDate(exdate.getDate() + exdays);
   var c_value=escape(value) + ((exdays==null) ? '' : '; expires='+exdate.toUTCString());
   document.cookie=c_name + '=' + c_value;
}


function getCookie(c_name)
{
   var i,x,y,ARRcookies=document.cookie.split(';');
   for (i=0;i<ARRcookies.length;i++)
   {
      x=ARRcookies[i].substr(0,ARRcookies[i].indexOf('='));
      y=ARRcookies[i].substr(ARRcookies[i].indexOf('=')+1);
      x=x.replace(/^\s+|\s+$/g,'');
      if (x==c_name)
      {
         return unescape(y);
      }
   }
}

function clearCookies()
{
   setCookie('mmmturkeybacon_approved_pending_earnings_total', 0, 1);
   setCookie('mmmturkeybacon_seven_days_dashboard_amazon_timezone_offset', 0, 1);
   return true;
}

draw_interface();