CrowdSurf productivity tools

Adds a variety of improvements and extensions to CrowdSurf tasks. Works on AMT and CSW.

目前為 2015-11-02 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         CrowdSurf productivity tools
// @namespace    mobiusevalon.tibbius.com
// @version      0.2
// @description  Adds a variety of improvements and extensions to CrowdSurf tasks.  Works on AMT and CSW.
// @author       Mobius Evalon
// @include      /^https{0,1}:\/\/ops.cielo24.com\/mediatool\/.*$/
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// ==/UserScript==

function exists(element,tag)
{
	if(element !== null && element !== undefined && (tag === undefined || element.tagName === tag)) return 1;
	return 0;
}

function capture(event)
{
    if(event.keyCode === 13)
    {
        var modal = document.getElementById("generic-modal")
        var submit_button = document.getElementById("approve_button");
        if(exists(modal) && modal.style.display === "block")
        {
            var ok_button = modal.getElementsByClassName("accept")[0];
            if(exists(ok_button,"BUTTON") && ok_button.innerHTML === "Ok") ok_button.click();
        }
        else if(exists(submit_button) && event.ctrlKey === true) submit_button.click();
    }
}

function ckey(s)
{
    return s.replace(/[^a-z]/ig,"-").toLowerCase();
}

function tabulate(url,type,id,reward)
{
    var storage_prefix = ("cspt_"+url+"_"+type+"_");
    var last_job = GM_getValue(storage_prefix+"last","");
    if(id != last_job)
    {
        var jobs = GM_getValue(storage_prefix+"jobs","0");
        var earnings = GM_getValue(storage_prefix+"earnings","0");

        /* math operations on strings automatically juggle the type to numerical, 
        so ++ takes care of that on the job count and multiplying by one takes
        care of the total earnings accumulation */
        jobs++;
        earnings = ((earnings*1)+(reward*1));

        /* GM_getValue and GM_setValue basically only work with strings, so
        that is all that can be stored and retrieved safely */
        GM_setValue(storage_prefix+"jobs",(""+jobs));
        GM_setValue(storage_prefix+"earnings",(""+earnings.toFixed(2)));
        GM_setValue(storage_prefix+"last",id);
    }
}

function dom_message(event)
{
    if(event.origin === "https://ops.cielo24.com")
    {
        var data = event.data.split("-");
        if(data[0] === "cspt")
        {
            switch(data[1])
            {
                case "reset":
                    var storage_prefix = ("cspt_"+data[2]+"_"+data[3]+"_");
                    GM_deleteValue(storage_prefix+"jobs");
                    GM_deleteValue(storage_prefix+"earnings");
                    update_display(data[2],data[3]);
                    break;
            }
        }
    }
}

function dbl(n)
{
    n *= 1;
    return n.toFixed(2);
}

function update_display(domain,job_type)
{
    var span = document.getElementById("cspt-display");
    if(!exists(span))
    {
        var guidelines = document.getElementById("guidelines");
        span = document.createElement("span");
        span.id = "cspt-display";
        span.style.fontWeight = "bold";
        span.style.fontSize = "16px";
        span.style.paddingBottom = "15px";
        span.style.cursor = "pointer";
        guidelines.insertBefore(span,guidelines.childNodes[0]);
    }
    span.innerHTML = ("<b style='font-size: 125%;'>"+job_type.ucfirst()+" <span onclick=\"window.postMessage('cspt-reset-"+domain+"-"+job_type+"','https://ops.cielo24.com');\">[Reset]</span></b><br>Volume: "+GM_getValue("cspt_"+domain+"_"+job_type+"_jobs","0")+"<br>Earnings: $"+dbl(GM_getValue("cspt_"+domain+"_"+job_type+"_earnings","0")));
}

String.prototype.slice_substring = function(s,e)
{
    var start = this.indexOf(s);
    var end = this.indexOf(e);
    var len = (start+s.length);
    if(start > -1 && end > -1 && end > len) return this.substring(len,end);
}

String.prototype.ucfirst = function()
{
    return (this.charAt(0).toUpperCase()+this.slice(1));
}

var domain = "";
var job_type = "";
var job_id = "";
var job_reward = "";

var regex = /.*\/mediatool\/(\w*)\/.*&crowd=([\w ]*).*&crowd_assignment_id=(\w*)/ig;
var matches = regex.exec(unescape(window.location.href));

if(matches !== null)
{
    domain = ckey(matches[matches.length-2]);
    job_type = ckey(matches[matches.length-3]);
    job_id = matches[matches.length-1];
}

// doing a bit of manual reassignment here
switch(job_type)
{
    case "transcription-asr":
        // "review and edit" queue, rolls together with transcription
        job_type = "transcription";
        break;
    case "transcription-review":
        // this is mainly so i can use the word in display later
        job_type = "review";
        break;
}
if(job_type === "transcription-asr") job_type = "transcription";

switch(job_type)
{
    case "transcription": case "review":
        if(job_id !== "none" && job_id.length === 32)
        {
            var submit_button = document.getElementById("approve_button");
            var price_header = document.getElementById("price_header");
            var textarea = document.getElementById("plaintext_edit");

            // find the reward amount for this job
            job_reward = price_header.innerHTML.slice_substring("$","&nbsp;");

            // this event listener allows the enter button to close modal dialogs
            // and for ctrl+enter to submit a transcript
            window.addEventListener("keydown",capture,false);
            submit_button.addEventListener("click",function() {tabulate(domain,job_type,job_id,job_reward)},false);
            textarea.focus();
        }
        update_display(domain,job_type);
        window.addEventListener("message",dom_message,false);
        break;
}