Greasy Fork

mmmturkeybacon Expected Earnings - Projected Earnings This Week

Shows projected earnings for the current week assuming all HITs are approved. If you complete a HIT after the HIT's status page has been processed by this script it will not be shown in the total until cookies are cleared and the total is recalculated by processing all of the pages again. Bonuses are also not shown in the total.

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

// ==UserScript==
// @name        mmmturkeybacon Expected Earnings - Projected Earnings This Week
// @author      mmmturkeybacon
// @description Shows projected earnings for the current week assuming all HITs are approved. If you complete a HIT after the HIT's status page has been processed by this script it will not be shown in the total until cookies are cleared and the total is recalculated by processing all of the pages again. Bonuses are also not shown in the total. 
// @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.01
// @grant       GM_log
// ==/UserScript==

var DATE_LIST_DELAY = 500;
var STATUSDETAIL_DELAY = 500;
var MPRE_DELAY = 2000;
var STATUSDETAIL_BASE_URL = '/mturk/statusdetail?encodedDate=';
var PROJECTED_EARNINGS_WEEK_LINK_TEXT = 'Projected Earnings This Week';

var global_run = false;
var statusdetail_loop_finished = false;
var resume_date = 0;
var resume_page = 0;
var page_total = 0;
var subtotal = 0;
var page_num = 1;

var projected_earnings_week_link = document.createElement('A');
var projected_earnings_week_field = document.createElement('TD');      

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

function wait_until_finished()
{
    if (global_run == true)
    {
        if (statusdetail_loop_finished == true)
        {
            /* The page_total isn't added to subtotal before it is saved because the last page
             * might not be a full page. It's easier to rescrape the entire last page than to
             * remember the position of the last HIT scraped on a page. Additionally since HITs
             * are often worked on in an order different than they were accepted there might be
             * a HIT that gets inserted before the last HIT we scraped. */
            setCookie('mmmturkeybacon_projected_earnings_week_total', subtotal+page_total, 7);
            setCookie('mmmturkeybacon_projected_earnings_week_subtotal', subtotal, 7);
            setCookie('mmmturkeybacon_projected_earnings_week_resume_page', page_num, 7);

            global_run = false;
            projected_earnings_week_link.innerHTML = PROJECTED_EARNINGS_WEEK_LINK_TEXT;
            projected_earnings_week_field.innerHTML = '$' + ((subtotal+page_total)/100).toFixed(2);
        }
        else
        {
            setTimeout(function(){wait_until_finished();}, 500);
        }
    }
}

function scrape($src)
{
    var $reward = $src.find('td[class="statusdetailStatusColumnValue"]:not(:contains("Rejected"))').siblings('td[class="statusdetailAmountColumnValue"]');
    page_total = 0;

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

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)
                {
                    subtotal += page_total;
                    setCookie('mmmturkeybacon_projected_earnings_week_subtotal', subtotal, 7);
                    setCookie('mmmturkeybacon_projected_earnings_week_resume_page', page_num, 7);

                    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);

                    scrape($src);

                    $next_URL = $src.find('a[href^="/mturk/statusdetail"]:contains("Next")');
                    next_URL = ($next_URL.length != 0) ? $next_URL.attr('href') : '';

                    if (next_URL != 0)
                    {
                        page_num++;
                        next_URL = $next_URL.attr('href');
                    }
                    else
                    {
                        next_URL = '';
                    }

                    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 date_URL = date_URLs.pop();
                var date_str = date_URL.replace(STATUSDETAIL_BASE_URL, '');
                setCookie('mmmturkeybacon_projected_earnings_week_resume_date', date_str, 7);

                var next_URL = date_URL + '&sortType=All&pageNumber=1';
                if (date_str == resume_date)
                {
                    page_num = resume_page;
                    next_URL = date_URL + '&sortType=All&pageNumber='+resume_page;
                }

                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 = 'projected_earnings_week';

    var projected_earnings_week_clear_cookies_link = document.createElement('A');
    projected_earnings_week_clear_cookies_link.innerHTML = '<font color="red">x</font>';
    projected_earnings_week_clear_cookies_link.title = 'Click to clear and recalculate.';
    projected_earnings_week_clear_cookies_link.href =  '#';
    projected_earnings_week_clear_cookies_link.onclick = function(){clearCookies(); start_running(); return false;}; // return false so href isn't followed

    projected_earnings_week_link.title = 'Click to calculate/stop.';
    projected_earnings_week_link.href =  '#';
    projected_earnings_week_link.onclick = function(){start_running(); return false;}; // return false so href isn't followed

    var projected_earnings_week_link_cell = document.createElement('TD');
    projected_earnings_week_link_cell.className = 'metrics-table-first-value';
    projected_earnings_week_link_cell.style.paddingLeft = '3px';
    projected_earnings_week_link_cell.appendChild(projected_earnings_week_clear_cookies_link);
    projected_earnings_week_link_cell.appendChild(document.createTextNode(' '));
    projected_earnings_week_link_cell.appendChild(projected_earnings_week_link);

    new_row.appendChild(projected_earnings_week_link_cell);
    new_row.appendChild(projected_earnings_week_field);

    var $expected_earnings_header = $('tr[id="expected_earnings_row"]');
    if ($expected_earnings_header.length > 0)
    {
        // Approved, Pending, Projected Month, Projected Week, Projected Today
        var $projected_earnings_today_row = $('tr[id="projected_earnings_today"]');
        if ($projected_earnings_today_row.length > 0)
        {
            $projected_earnings_today_row.before(new_row);
        }
        else
        {
            $expected_earnings_header.nextAll('tr').last().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);
    }


    projected_earnings_week_link.innerHTML = PROJECTED_EARNINGS_WEEK_LINK_TEXT;
    projected_earnings_week_field.innerHTML = '$?.??';
    var saved_total = parseInt(getCookie('mmmturkeybacon_projected_earnings_week_total'), 10);
    if (saved_total)
    {
        projected_earnings_week_field.innerHTML = '$' + (saved_total/100).toFixed(2);
    }

}

function start_running()
{

    if (global_run == false)
    {
        global_run = true;
        statusdetail_loop_finished = true;
        page_total = 0;
        page_num = 1;

        resume_date = getCookie('mmmturkeybacon_projected_earnings_week_resume_date');
        subtotal = parseInt(getCookie('mmmturkeybacon_projected_earnings_week_subtotal'), 10);
        resume_page = parseInt(getCookie('mmmturkeybacon_projected_earnings_week_resume_page'), 10);

        resume_date = (resume_date) ? resume_date : 0;
        subtotal = (subtotal) ? subtotal : 0;
        resume_page = (resume_page) ? resume_page : 1;

        projected_earnings_week_link.innerHTML = PROJECTED_EARNINGS_WEEK_LINK_TEXT;
        projected_earnings_week_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 previous_sunday = new Date();
                previous_sunday.setMinutes(previous_sunday.getMinutes() - (480 - previous_sunday.getTimezoneOffset())); // set to mturk timezone
                previous_sunday.setDate(previous_sunday.getDate() - previous_sunday.getDay());

                //http://stackoverflow.com/questions/3605214/javascript-add-leading-zeroes-to-date
                var previous_sunday_date = ('0' + (previous_sunday.getMonth()+1)).slice(-2) + ('0' + previous_sunday.getDate()).slice(-2) + previous_sunday.getFullYear();

                var begin_date = resume_date;
                if (resume_date < previous_sunday_date)
                {
                    begin_date = previous_sunday_date;
                    clearCookies();
                    resume_date = 0;
                    subtotal = 0;
                    resume_page = 1;
                }

                var date_URLs = new Array();
                $src.find('a[href^="/mturk/statusdetail"]').filter(function(){return ($(this).attr('href').substring(32) >= begin_date);}).each(function(){date_URLs.push($(this).attr('href'));});

                date_list_loop(date_URLs);
            }
        });
    }
    else
    {
        global_run = false; // this will stop scraping pages prematurely
        projected_earnings_week_link.innerHTML = PROJECTED_EARNINGS_WEEK_LINK_TEXT + ' - stoppped! ';
        projected_earnings_week_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_projected_earnings_week_resume_date', 0, 7);
   setCookie('mmmturkeybacon_projected_earnings_week_total', 0, 7);
   setCookie('mmmturkeybacon_projected_earnings_week_subtotal', 0, 7);
   setCookie('mmmturkeybacon_projected_earnings_week_resume_page', 1, 7);
   return true;
}

draw_interface();