JR mturk timer warning

Script will warn you at specific times left for your hit. The times can be set in the options menu.

Verze ze dne 14. 12. 2014. Zobrazit nejnovější verzi.

// ==UserScript==
// @name        JR mturk timer warning
// @version     0.6.3
// @namespace   https://greasyfork.org/users/6406
// @description Script will warn you at specific times left for your hit. The times can be set in the options menu.
// @author      John Ramirez (JohnnyRS)
// @include     http*://*.mturk.com/mturk/continue*
// @include     http*://*.mturk.com/mturk/accept*
// @include     http*://*.mturk.com/mturk/preview*
// @include     http*://*.mturk.com/mturk/myhits*
// @exclude     *mturk.com/*HITMONITOR*
// @grant       GM_getValue
// @grant       GM_setValue
// ==/UserScript==

// Warns you with a voice, alarm or colors on the amount of time left for the current hit. You can set your own options
// in the menu at top. There is a male and female voice for the warning. You can turn off the warnings and color.
// the options are saved so you don't have to set it again. You can stop it saving options for the current hit if
// you just want changes for the hit you are on.

var gSeconds = 0, gElapsedSeconds = 0, gWorking = false, gDoNotSpeak = false;
var gOptions = {"status":["On",0],"voice":["female",0],"alarm":["Off",0],"color":["On",0]};
var gOptionTimes = {"60":["Off",0],"30":["On",0],"20":["Off",0],"10":["Off",0],"5":["On",0],"1":["On",0],"30s":["On",0]};
var gWarningTimes = {"60":false,"30":false,"20":false,"10":false,"5":false,"1":false,"30s":false};
var gHtmlColors = ["FF0000","FF3322","FF6633","FFAA39","FFCCCC","FFEFEC","FFEFCC","EEEFCC","CCCCBB","CCCCBF","CCCCCC","CCCCDD","CCCCDF","CCCCEE","CCCCEF","CCDDFF","DDDDFF","EEEEFF","EEEEF9","EEEEF6","FFFFF2","FFFFF5","FFFFF8","FFFFFF"];

var f60MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%201%20hour%20left%20-%20Laura.mp3");
var m60MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%201%20hour%20left%20-%20Paul.mp3");
var a60MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2060%20minutes%20left.mp3");
var f30MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2030%20minutes%20left%20-%20laura.mp3");
var m30MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2030%20minutes%20left%20-%20Paul.mp3");
var a30MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2030%20minutes%20left.mp3");
var f20MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2020%20minutes%20left%20-%20laura.mp3");
var m20MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2020%20minutes%20left%20-%20Paul.mp3");
var a20MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2020%20minutes%20left.mp3");
var f10MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2010%20minutes%20left%20-%20Laura.mp3");
var m10MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2010%20minutes%20left%20-%20Paul.mp3");
var a10MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2010%20minutes%20left.mp3");
var f5MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%205%20minutes%20left%20-%20Laura.mp3");
var m5MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%205%20minutes%20left%20-%20Paul.mp3");
var a5MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%205%20minutes%20left.mp3");
var f1MinuteLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%201%20minute%20left%20-%20Laura.mp3");
var m1MinuteLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%201%20minute%20left%20-%20Paul.mp3");
var a1MinuteLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%201%20minute%20left.mp3");
var f30SecondsLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2030%20seconds%20left%20-%20Laura.mp3");
var m30SecondsLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2030%20seconds%20left%20-%20Paul.mp3");
var a30SecondsLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2030%20seconds%20left.mp3");
var fTesting = new Audio("http://www.allbyjohn.com/sounds/This%20is%20just%20a%20test%20of%20this%20warning%20system%20-%20Laura.mp3");
var mTesting = new Audio("http://www.allbyjohn.com/sounds/This%20is%20just%20a%20test%20of%20this%20warning%20system%20-%20Paul.mp3");
var g60MinutesLeft = null, g30MinutesLeft = null, g20MinutesLeft = null, g10MinutesLeft = null, g5MinutesLeft = null, g1MinutesLeft = null, 
    g30SecondsLeft = null, gTesting = null;

function loadSettings() {
    gOptions = JSON.parse(GM_getValue("JR_WN_options",JSON.stringify(gOptions)));
    gOptionTimes = JSON.parse(GM_getValue("JR_WN_optionTimes",JSON.stringify(gOptionTimes)));
}
function saveSettings() {
    GM_setValue("JR_WN_options",JSON.stringify(gOptions));
    GM_setValue("JR_WN_optionTimes",JSON.stringify(gOptionTimes));
}
function createMyElement(elementName,theClass,theId,theStyle,theText) {
    var theElement = document.createElement(elementName);
    if (theClass) theElement.className = theClass;
    if (theId) theElement.id = theId;
    if (theStyle) theElement.setAttribute("style",theStyle);
    if (theText) theElement.innerHTML = theText;
    return theElement;
}
function createCheckbox(theClass,theId,theValue,theName,theStyle) {
    var theCheckbox = createMyElement("input",theClass,theId,theStyle);
    theCheckbox.value = theValue;
    theCheckbox.type = "checkbox";
    if (theName) theCheckbox.name = theName;
    return theCheckbox;
}
function createTextInput(theClass,theId,theValue,theName,theStyle) {
    var theInput = createMyElement("input",theClass,theId,theStyle);
    theInput.type = "text";
    if (theValue) theInput.value = theValue;
    if (theName) theInput.name = theName;
    return theInput;
}
function setUpVoices(gender) {
    if (gender == "Female") {
        g60MinutesLeft = f60MinutesLeft; g30MinutesLeft = f30MinutesLeft; g20MinutesLeft = f20MinutesLeft; g10MinutesLeft = f10MinutesLeft; 
        g5MinutesLeft = f5MinutesLeft; g1MinuteLeft = f1MinuteLeft; g30SecondsLeft = f30SecondsLeft; gTesting = fTesting;
    } else if (gender == "Male") {
        g60MinutesLeft = m60MinutesLeft; g30MinutesLeft = m30MinutesLeft; g20MinutesLeft = m20MinutesLeft; g10MinutesLeft = m10MinutesLeft;
        g5MinutesLeft = m5MinutesLeft; g1MinuteLeft = m1MinuteLeft; g30SecondsLeft = m30SecondsLeft; gTesting = mTesting;
    } else {
        g60MinutesLeft = a60MinutesLeft; g30MinutesLeft = a30MinutesLeft; g20MinutesLeft = a20MinutesLeft; g10MinutesLeft = a10MinutesLeft;
        g5MinutesLeft = a5MinutesLeft; g1MinuteLeft = a1MinuteLeft; g30SecondsLeft = a30SecondsLeft; gTesting = a30SecondsLeft;
    }
}
function setColor(theTimeLeft) {
    var theColor = "FFFFFF";
    if (theTimeLeft<30) theColor = gHtmlColors[0]; // less than 30 seconds
    else if (theTimeLeft<60) theColor = gHtmlColors[1]; // less than 1 minute
    else if (theTimeLeft<600) {
        theColor = gHtmlColors[Math.ceil(theTimeLeft/60)]; // less than 10 minutes
    }
    else if (theTimeLeft<1200) {
        theColor = gHtmlColors[Math.ceil((theTimeLeft-600)/120)+10]; // less than 20 minutes
    }
    else if (theTimeLeft<1800) {
        theColor = gHtmlColors[Math.ceil((theTimeLeft-1200)/240)+15]; // less than 30 minutes
    }
    else if (theTimeLeft<2100) theColor = gHtmlColors[20];
    else if (theTimeLeft<2400) theColor = gHtmlColors[21];
    else if (theTimeLeft<3000) theColor = gHtmlColors[22];
    else if (theTimeLeft<2600) theColor = gHtmlColors[23];
    document.getElementsByTagName("form")[1].style.backgroundColor = "#"+theColor;
}
function timeLeft() {
    theTime = document.getElementById("theTime");
    if (theTime) {
        var theSplit = theTime.innerHTML.split(":");
        hours = parseInt(theSplit[0]);
        minutes = parseInt(theSplit[1]);
        seconds = parseInt(theSplit[2]);
        minutes += hours * 60;
        gElapsedSeconds = seconds + (minutes * 60);
        var timeLeftMinutes = Math.floor(gSeconds/60) - minutes - 1;
        document.getElementById("timeLeftDiv").innerHTML = "Time Left: " + timeLeftMinutes + " Minutes : " + (60-seconds) + " Seconds";
        return gSeconds - gElapsedSeconds;
    } else return null;
}
function warning(theSound,theTime) {
    theSound.play();
    gWarningTimes[theTime] = true;
}
function checkTimes(announceNow) {
    var timeLeftSeconds = timeLeft();
    var timeLeftMinutes = Math.floor(timeLeftSeconds/60);
    if (timeLeftSeconds) {
        if (timeLeftSeconds<=30) {
            if (gOptionTimes["30s"][0] == "On" && !gWarningTimes["30s"]) warning(g30SecondsLeft,"30s");
        } else if (timeLeftSeconds<=60) {
            if (gOptionTimes["1"][0] == "On" && !gWarningTimes["1"]) warning(g1MinuteLeft,"1");
        } else if (timeLeftMinutes<5 && (timeLeftMinutes>3 || announceNow)) {
            if (gOptionTimes["5"][0] == "On" && (!gWarningTimes["5"] || announceNow))
                if (gElapsedSeconds>185 || announceNow) warning(g5MinutesLeft,"5");
        } else if (timeLeftMinutes<10 && (timeLeftMinutes>7 || announceNow)) {
            if (gOptionTimes["10"][0] == "On" && (!gWarningTimes["10"] || announceNow))
                if (gElapsedSeconds>185 || announceNow) warning(g10MinutesLeft,"10");
        } else if (timeLeftMinutes<20 && (timeLeftMinutes>15 || announceNow)) {
            if (gOptionTimes["20"][0] == "On" && (!gWarningTimes["20"] || announceNow))
                if (gElapsedSeconds>305 || announceNow) warning(g20MinutesLeft,"20");
        } else if (timeLeftMinutes<30 && (timeLeftMinutes>24 || announceNow)) {
            if (gOptionTimes["30"][0] == "On" && (!gWarningTimes["30"] || announceNow))
                if (gElapsedSeconds>365  || announceNow) warning(g30MinutesLeft,"30");
        } else if (timeLeftMinutes<60 && (timeLeftMinutes>53 || announceNow)) {
            if (gOptionTimes["60"][0] == "On" && (!gWarningTimes["60"] || announceNow))
                if (gElapsedSeconds>425 || announceNow) warning(g60MinutesLeft,"60");
        }
        if (gOptions.color[0] == "On") setColor(timeLeftSeconds);
        else document.getElementsByTagName("form")[1].style.backgroundColor = "#FFFFFF";
    }
}
function setOptions() {
    gOptions.status[0] = document.getElementById("warningOption").getAttribute("currentValue");
    gOptions.status[1] = document.getElementById("warningOption").getAttribute("valueIndex");
    gOptions.voice[0] = document.getElementById("warningVoiceOptions").getAttribute("currentValue");
    gOptions.voice[1] = document.getElementById("warningVoiceOptions").getAttribute("valueIndex");
    gOptions.alarm[0] = document.getElementById("warningAlarmOptions").getAttribute("currentValue");
    gOptions.alarm[1] = document.getElementById("warningAlarmOptions").getAttribute("valueIndex");
    gOptions.color[0] = document.getElementById("warningColorOptions").getAttribute("currentValue");
    gOptions.color[1] = document.getElementById("warningColorOptions").getAttribute("valueIndex");
    gOptionTimes["60"][0] = document.getElementById("1HourOptions").getAttribute("currentValue");
    gOptionTimes["60"][1] = document.getElementById("1HourOptions").getAttribute("valueIndex");
    gOptionTimes["30"][0] = document.getElementById("30MinutesOptions").getAttribute("currentValue");
    gOptionTimes["30"][1] = document.getElementById("30MinutesOptions").getAttribute("valueIndex");
    gOptionTimes["20"][0] = document.getElementById("20MinutesOptions").getAttribute("currentValue");
    gOptionTimes["20"][1] = document.getElementById("20MinutesOptions").getAttribute("valueIndex");
    gOptionTimes["10"][0] = document.getElementById("10MinutesOptions").getAttribute("currentValue");
    gOptionTimes["10"][1] = document.getElementById("10MinutesOptions").getAttribute("valueIndex");
    gOptionTimes["5"][0] = document.getElementById("5MinutesOptions").getAttribute("currentValue");
    gOptionTimes["5"][1] = document.getElementById("5MinutesOptions").getAttribute("valueIndex");
    gOptionTimes["1"][0] = document.getElementById("1MinuteOptions").getAttribute("currentValue");
    gOptionTimes["1"][1] = document.getElementById("1MinuteOptions").getAttribute("valueIndex");
    gOptionTimes["30s"][0] = document.getElementById("30SecondsOptions").getAttribute("currentValue");
    gOptionTimes["30s"][1] = document.getElementById("30SecondsOptions").getAttribute("valueIndex");
    if (gOptions.voice[0] != "Off") setUpVoices(gOptions.voice[0]);
    else if (gOptions.alarm[0] != "Off") setUpVoices();
    if (gWorking) {
        if (gOptions.color[0] == "On" && gOptions.status[0] == "On") setColor(timeLeft());
        else document.getElementsByTagName("form")[1].style.backgroundColor = "#FFFFFF";
        if (!gDoNotSpeak && gOptions.status[0] == "On" && (gOptions.voice[0] != "Off" || gOptions.alarm[0] != "Off")) checkTimes(true);
    } else if (gOptions.status[0] == "On" && (gOptions.voice[0] != "Off" || gOptions.alarm[0] != "Off") && !gDoNotSpeak) gTesting.play();
    if (document.getElementById("warningOptionsSave").checked) saveSettings();
}
function createSpanOptions(theNode,theOptions) {
    var theId = "", theText = "", theValues = [], theStatus = "", replaceWith="";
    for (var i=0,len=theOptions.length; i<len; i++) {
        theId = theOptions[i][0];
        theText = theOptions[i][1];
        theValues = theOptions[i][2];
        theStatus = theValues[theOptions[i][3]].substr(0,1);
        replaceWith = theValues[theOptions[i][3]].replace(theStatus,"");
        theOption = createMyElement("span","myOwnDiv",theId,"cursor:pointer",theText.replace("$",replaceWith));
        if (theStatus=="-") theOption.style.color = "#FF0000";
        else theOption.style.color = "#006600";
        theOption.setAttribute("theValues",JSON.stringify(theValues));
        theOption.setAttribute("valueIndex",theOptions[i][3]);
        theOption.setAttribute("theText",theText);
        theOption.setAttribute("currentValue",replaceWith);
        theNode.appendChild(document.createTextNode(" "));
        theNode.appendChild(theOption);
        theOption.onclick = function() {
            gDoNotSpeak = false;
            var theValues = JSON.parse(this.getAttribute("theValues"));
            var theIndex = parseInt(this.getAttribute("valueIndex"));
            var theText = this.getAttribute("theText");
            theIndex = (theIndex < theValues.length-1) ? theIndex+1 : 0;
            this.setAttribute("valueIndex",theIndex);
            var theStatus = theValues[theIndex].substr(0,1);
            var replaceWith = theValues[theIndex].replace(theStatus,"");
            this.innerHTML = theText.replace("$",replaceWith);
            this.setAttribute("currentValue",replaceWith);
            if (theStatus=="-") this.style.color = "#FF0000";
            else this.style.color = "#006600";
            if (this.id == "warningAlarmOptions" && replaceWith == "On") {
                document.getElementById("warningVoiceOptions").setAttribute("currentValue","Off");
                document.getElementById("warningVoiceOptions").setAttribute("valueIndex","1");
                document.getElementById("warningVoiceOptions").innerHTML = "[ Voice: Off ]";
                document.getElementById("warningVoiceOptions").style.color = "#FF0000";
            } else if (this.id == "warningVoiceOptions" && replaceWith != "Off") {
                document.getElementById("warningAlarmOptions").setAttribute("currentValue","Off");
                document.getElementById("warningAlarmOptions").setAttribute("valueIndex","0");
                document.getElementById("warningAlarmOptions").innerHTML = "[ Alarm: Off ]";
                document.getElementById("warningAlarmOptions").style.color = "#FF0000";
            } else if (this.id == "warningOption" && replaceWith == "Off") {
                gDoNotSpeak = true;
            } else if (this.id == "warningColorOptions") gDoNotSpeak = true;
            setOptions();
        };
    }
}
function showOptions(beforeNode) {
    var theOptionsContainer = createMyElement("div","myOwnDiv","warningOptionsContainer",
        "background-color:#D8FCFB; text-align:center; margin:0 auto; padding: 0; width:80%; border: 2px solid black;");
    var theOptionsToggle = createMyElement("div","myOwnDiv","warningOptionsToggle","margin:0; padding:0 0 2px 0; background-color:#696969; color: Aqua; font-size:10px; cursor:default;",
        "Click here for Time Left Warning options.");
    var theOptionsControl = createMyElement("div","myOwnDiv","warningOptionsController","display:none;");
    var theOptionsSave = createCheckbox("myOwnCheckBox","warningOptionsSave","save Me","","margin-left:20px; height:4px;");
    theOptionsSave.checked = true;
    theOptionsSave.onclick = function() { if (theOptionsSave.checked) saveSettings(); }

    var spanWarningOptions = [ ["warningOption","[ Status: $ ]",["+On","-Off"],gOptions.status[1]], ["warningVoiceOptions","[ Voice: $ ]",["+Female","-Off","+Male"],gOptions.voice[1]],
        ["warningAlarmOptions","[ Alarm: $ ]",["-Off","+On"],gOptions.alarm[1]], ["warningColorOptions","[ Color: $ ]",["+On","-Off"],gOptions.color[1]]];
    theOptionsControl.appendChild(document.createTextNode("Time Left Warning:"));
    createSpanOptions(theOptionsControl,spanWarningOptions);
    theOptionsControl.appendChild(theOptionsSave);
    theOptionsControl.appendChild(document.createTextNode(" Save Options"));
    theOptionsControl.appendChild(createMyElement("br"));
    theOptionsControl.appendChild(document.createTextNode("Warn at: "));
    var spanTimeOptions = [ ["30SecondsOptions","[30 seconds]",["+On","-Off"],gOptionTimes["30s"][1]], ["1MinuteOptions","[1 minute]",["+On","-Off"],gOptionTimes["1"][1]],
        ["5MinutesOptions","[5 minutes]",["+On","-Off"],gOptionTimes["5"][1]], ["10MinutesOptions","[10 minutes]",["+On","-Off"],gOptionTimes["10"][1]],
        ["20MinutesOptions","[20 minutes]",["-Off","+On"],gOptionTimes["20"][1]], ["30MinutesOptions","[30 minutes]",["-Off","+On"],gOptionTimes["30"][1]],
        ["1HourOptions","[1 hour]",["-Off","+On"],gOptionTimes["60"][1]]];
    createSpanOptions(theOptionsControl,spanTimeOptions);
    theOptionsControl.appendChild(createMyElement("br"));
    theOptionsControl.appendChild(document.createTextNode("Click on text above to change options."));
    theOptionsToggle.onclick = function() {
        var theDisplay = theOptionsControl.style.display;
        theOptionsControl.style.display = (theDisplay == "none") ? "block" : "none";
        if (theOptionsControl.style.display == "none") this.innerHTML = "Click here for Time Left Warning options menu.";
        else this.innerHTML = "Click here to hide the options menu";
        
    }
    
    theOptionsContainer.appendChild(theOptionsToggle);
    theOptionsContainer.appendChild(theOptionsControl);
    beforeNode.parentNode.insertBefore(theOptionsContainer,beforeNode);
}

loadSettings();
setUpVoices(gOptions.voice[0]);
var timerTextNode = document.getElementsByClassName("title_orange_text")[0];
if (timerTextNode && timerTextNode.innerHTML.indexOf("Timer:") != -1) {
    gWorking = true;
    var weeks = 0, days = 0, hours = 0, minutes = 0;
    var theTime = document.getElementById("theTime");
    var timeLeftNode = createMyElement("div","myOwnDiv","timeLeftDiv","padding-left:20px");
    theTime.parentNode.parentNode.parentNode.appendChild(timeLeftNode);
    var ofTime = timerTextNode.innerHTML.split("</span>")[1];
    var ofTime = ofTime.split("<noscript>")[0].replace(/\s\s+/g," ").trim();
    var theSplit = ofTime.replace("of ","").split(" ");
    if (theSplit.length > 0) {
        if (theSplit > 2) {
            if (theSplit[3].indexOf("week") != -1) weeks = parseInt(theSplit[2]);
            else if (theSplit[3].indexOf("day") != -1) days = parseInt(theSplit[2]);
            else if (theSplit[3].indexOf("hour") != -1) hours = parseInt(theSplit[2]);
        }
        days += weeks * 7;
        hours += days * 24;
        if (theSplit[1].indexOf("day") != -1) days += parseInt(theSplit[0]);
        else if (theSplit[1].indexOf("hour") != -1) hours += parseInt(theSplit[0]);
        else if (theSplit[1].indexOf("minute") != -1) minutes = parseInt(theSplit[0]);
        else if (theSplit[1].indexOf("second") != -1) gSeconds = parseInt(theSplit[0]);
        hours += days * 24;
        minutes += hours * 60;
        gSeconds += minutes * 60;
        var intervalVar = setInterval( function(){
            if (gOptions.status[0] == "On" && (gOptions.voice[0] != "Off" || gOptions.alarm[0] != "Off")) checkTimes();
        }, 4000);
        var theHitForm = document.getElementsByTagName("form")[1];
        var theTable = theHitForm.getElementsByTagName("table")[0];
        var theDiv = theHitForm.getElementsByTagName("div")[2];
        theTable.style.backgroundColor = "#FFFFFF";
        theDiv.style.backgroundColor = "#FFFFFF";
        showOptions(theHitForm);
        if (gOptions.color[0] == "On" && gOptions.status[0] == "On") setColor(timeLeft());
        else document.getElementsByTagName("form")[1].style.backgroundColor = "#FFFFFF";
    }
} else {
    var theAlertBox = document.getElementById("alertBox");
    var theErrorTitle = document.getElementsByClassName("error_title")[0];
    var beforeNode = (theErrorTitle) ? theErrorTitle.parentNode.parentNode.parentNode : (theAlertBox) ? theAlertBox : timerTextNode.parentNode.parentNode.parentNode;
    showOptions(beforeNode);
}