JR Mturk Panda Crazy Queue Helper

A script add on for Panda Crazy for displaying queue and sorting queue after submitting hits.

目前為 2016-09-15 提交的版本,檢視 最新版本

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

You will need to install an extension such as Tampermonkey to install this script.

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        JR Mturk Panda Crazy Queue Helper
// @version     0.1
// @namespace   https://greasyfork.org/users/6406
// @description A script add on for Panda Crazy for displaying queue and sorting queue after submitting hits.
// @include     http*://*mturk.com/mturk/myhits*
// @include		http*://*mturk.com/mturk/findhits*
// @include		http*://*mturk.com/mturk/sorthits*
// @include		http*://*mturk.com/mturk/viewhits*
// @include     http*://*mturk.com/mturk/continue*
// @include     http*://*mturk.com/mturk/accept*
// @include     http*://*mturk.com/mturk/submit
// @include     http*://*mturk.com/mturk/return*
// @include		http*://*mturk.com/mturk/*searchbar*
// @include     http*://*mturk.com/mturk/return?requesterId=*
// @include     http*://*mturk.com/mturk/preview?prevRequester=*
// @exclude     http*://*mturk.com/mturk/findhits?*hit_scraper*
// @require     http://code.jquery.com/jquery-2.1.4.min.js
// @grant       GM_getValue
// @grant       GM_setValue
// ==/UserScript==

var gScriptVersion = "0.1";
var gScriptName = "pandacrazy";
var gLocation = window.location.href;
var gPandaCrazyLives = false, gHitExternalNextLink="", gHitExternalNextAcceptLink="";
var gPandaCrazyVersion = -1, gHitReturnLink="";
var gQueueData = null, gPE=0, gTabTextMode = 0, gTabTextTimer=0, gOriginalTitle = document.title, gCurrentPostion = 1;
var gSubmitHitID = "", gReturnedHitID = ""; // previous hitID submitted ore returned just to be sure it doesn't get redone.
var gCorrectVersion = false;
var gThisTarget = (new Date().getTime()) + "_JRID"; // target ID from the time to distinguish different scripts.
var gThisId = -1; // ID number to represent the id in the Panda Crazy external data number ID just for separating messages.
var jobDataDefault = {"requesterName":"","requesterId":"","groupId":"","pay":"","title":"","duration":"0","hitsAvailable":0,"timeLeft":"","totalSeconds":0,"hitId":"",
		"continueURL":"","returnURL":"","durationParsed":null,"jobNumber":"-1","friendlyRName":"","friendlyTitle":"","assignedOn":"","description":"","qual":"","keywords":""};

function createDiv(theHtml) { var inner = (theHtml) ? theHtml : ""; return $('<div>').html(inner); }
function createSpan(theHtml) { var inner = (theHtml) ? theHtml : ""; return $('<span>').html(inner); }
function parseVersionString (str) {
    var x = str.split('.');
    var maj = parseInt(x[0]) || 0; var min = parseInt(x[1]) || 0; var pat = parseInt(x[2]) || 0;
    return {"major": maj, "minor": min, "patch": pat};
}
function checkVersion(str) { 
	var versionObj = parseVersionString(str);
	if (versionObj.major>=0 && versionObj.minor>=3 && versionObj.patch>=7) return true;
	else return false;
}
function checkMode() {
	if (gLocation.indexOf("mturk/myhits") != -1) return "queuePageStart";
	else if (gLocation.indexOf("mturk/continue") != -1 || gLocation.indexOf("mturk/accept") != -1 || gLocation.indexOf("mturk/preview?prevRequester=") != -1) return "hitPage";
	else if (gLocation.indexOf("mturk/submit") != -1) return "submitPage";
	else if (gLocation.indexOf("mturk/return") != -1) return "returnPage";
	return null;
}
function createMessageData(command,data,target) { return {"time":(new Date().getTime()),"command":command,"data":data,"theTarget":target}; }
function sendCommandMessage(data) { localStorage.setItem("JR_message_" + gScriptName, JSON.stringify(data)); }

function sendMessageData(command,theData) {
	var messageData = createMessageData(command,theData);
	sendCommandMessage(messageData);
}
function sendPingMessage(target) { localStorage.setItem("JR_message_ping_" + gScriptName, JSON.stringify(createMessageData("areYouThere",null,target))); }
function sendPongMessage(target) { localStorage.setItem("JR_message_pong_" + gScriptName, JSON.stringify(createMessageData("iAmHere",null,target))); }
function sendQueuePageMessage(target) { localStorage.setItem("JR_message_" + gScriptName, JSON.stringify(createMessageData("getQueueData",null,target))); }
function sendSubmittedMessage(target,thisHitID) { localStorage.setItem("JR_message_" + gScriptName, JSON.stringify(createMessageData("submitted",{"hitId":thisHitID},target))); }
function findNextHitQueue(currentHitID) {
	if (!gQueueData || currentHitID === "") return null;
	var i=-1, skip=false, targetHit=null;
	do {
		i++;
		if (gQueueData[i].hitId==currentHitID) gCurrentPostion = i+1;
		if (gQueueData[i].hitId==currentHitID || gQueueData[i].hitId==gSubmitHitID || gQueueData[i].hitId==gReturnedHitID) skip=true;
		else targetHit = gQueueData[i];
	} while (i<gQueueData.length-1 && !targetHit && skip);
	return targetHit;
}
function findNextPositionQueue(position) {
}
function queuePageStart() {
	var sortresultsForm = $("#sortresults_form");
	var hitsText = $(sortresultsForm).prev();
	$(hitsText).find(".title_orange_text_bold").append(createSpan("PC Enhanced Mode").css({"font-size":"11px","padding":"1px 2px","background-color":"#FFE4C4","color":"black"}));
	var lastTables = $(sortresultsForm).next().next();
	var displayHits = $(sortresultsForm).next();
	var afterThis = $("#subtabs_and_searchbar");
	theMainContainer = createDiv().attr({"id":"JRMQContainer"}).insertAfter(afterThis);
	//createDiv().attr({"id":"JRNormalQueue"}).append(hitsText).append(displayHits).appendTo(theMainContainer);
	createDiv().attr({"id":"JRNormalQueue"}).appendTo(theMainContainer);
	$("#JRNormalQueue").append($(hitsText));
	$("#JRNormalQueue").append($(sortresultsForm));
	$("#JRNormalQueue").append($(displayHits));
	createDiv().attr({"id":"JREnhancedQueue1"}).appendTo(theMainContainer);
	createDiv().attr({"id":"JREnhancedQueue"}).appendTo(theMainContainer);
	gScriptMode = "queuePage";
}
function mainListener(e) {
	var returnedStorage = JSON.parse(e.newValue);
	if (!gPandaCrazyLives) {
		if ( e.key.substring(0,16) == 'JR_message_pong_' &&  e.key.substr(e.key.length - gScriptName.length) == gScriptName && // Receiving correct message from Panda Crazy
				returnedStorage && returnedStorage.theTarget == gThisTarget) { // Receiving as a targeted message for first message from Panda Crazy
			gPandaCrazyLives = true; // We now know Panda Crazy is running.
			gPandaCrazyVersion = returnedStorage.version;
			gCorrectVersion = checkVersion(gPandaCrazyVersion);
			if (gScriptMode=="queuePageStart" || gScriptMode=="hitPage") { sendQueuePageMessage(gThisTarget); }
		}
	} else if (gCorrectVersion && returnedStorage && returnedStorage.data) { // Panda Crazy is up and running with correct version.
		if (e.key.substring(0,11) == 'JR_message_' &&  e.key.substr(e.key.length - gScriptName.length) == gScriptName && // Receiving correct message from Panda Crazy
				(returnedStorage.theTarget == gThisTarget || returnedStorage.theTarget===null)) { // Receiving as a targeted message or a ping message
			if (returnedStorage.data.queue) gQueueData = returnedStorage.data.queue;
			if (returnedStorage.data.PE) gPE = returnedStorage.data.PE;
			if (returnedStorage.command=="ping") sendPongMessage(gThisTarget);
			if (gScriptMode=="queuePageStart") queuePageStart();
			else if (gScriptMode=="hitPage") { //console.log("This is a hitpage so looking for next target hit");
				var hitIdNode = $("input[name='hitId']");
				var hitId = (hitIdNode.length>0) ? $("input[name='hitId']").eq(0).val() : "";
				targetHit = findNextHitQueue(hitId);
				if (targetHit) {
					var realHitId = $("input[name='hitId']").eq(0).val();
					if (gHitExternalNextLink) $(gHitExternalNextLink).attr('href', targetHit.continueURL + "&prevsubmithitId=" + hitId);
					if (gHitExternalNextAcceptLink) $(gHitExternalNextAcceptLink).attr('href', targetHit.continueURL + "&prevsubmithitId=" + hitId);
					var theReturnLinkHref = "https://www.mturk.com/mturk/return?hitId=" + realHitId + "&hitNextId=" + targetHit.hitId + "&inPipeline=false";
					if (gHitReturnLink.length) $(gHitReturnLink).attr('href', theReturnLinkHref);
				} else {
					if (hitExternalNextLink) {
                        var theNextLinkHref = $(gHitExternalNextLink).attr('href');
                        if (theNextLinkHref.indexOf("&prevsubmithitId=") == -1) theNextLinkHref = theNextLinkHref + "&prevsubmithitId=" + hitId;
                        $(hitExternalNextLink).attr('href', theNextLinkHref );
                    }
				}
				//console.log("Next link is now: " + $(gHitExternalNextLink).attr('href'));
			}
		}
	}
}
gScriptMode = checkMode();
if (gLocation.indexOf("&prevsubmithitId=") != -1) { gSubmitHitID = (gLocation.split("&prevsubmithitId=")[1]).split("&")[0]; sendSubmittedMessage(gThisTarget,gSubmitHitID); }
if (gScriptMode=="returnPage") { 
	gReturnedHitID = (gLocation.indexOf("hitId=") != -1) ? (gLocation.split("hitId=")[1]).split("&")[0] : "";
	sendSubmittedMessage(gThisTarget,gReturnedHitID);
}
if (gScriptMode=="submitPage" || gScriptMode=="returnPage") {
	var goToNext = "";
	if (gLocation.indexOf("&hitNextId=") != -1) goToNext = "https://www.mturk.com/mturk/continue?hitId=" + (gLocation.split("&hitNextId=")[1]).split("&")[0];
	if (goToNext!=="") {
		$("body").html("");
		setTimeout(function() { window.location.replace(goToNext); },1100);
	}
}
$(function() {
	if (!gScriptMode) return;
	var submitButton = document.getElementsByName("/submit");
	if (submitButton.length) {
		gHitExternalNextLink = $("#hitExternalNextLink");
		gHitExternalNextAcceptLink = $("#hitExternalNextAcceptLink");
		gHitReturnLink = $("a[href*='mturk/return']");
		setInterval( function() {
			var timeLeft = $("#theTime").text();
			var theTimeLeft = $("a#time_left\\.tooltip");
			var theDuration = (theTimeLeft.length) ? theTimeLeft.parent().next().html().trim() : "";
			var requesterTip = $("#requester\\.tooltip");
			var requesterNameNode = (requesterTip.length) ? $(requesterTip).parent().next() : null;
			var theRequesterName = (requesterNameNode.length) ? $(requesterNameNode).html().trim() : "";
			gTabTextTimer+=1000;
			if (gTabTextTimer>=4000) {
				gTabTextTimer=0;
				gTabTextMode = 1 - gTabTextMode;
			}
			if (gTabTextMode===0) document.title = "( " + timeLeft + " of " + theDuration + " ) " + theRequesterName + " :: " + gOriginalTitle;
			if (gTabTextMode==1) document.title = "( " + gCurrentPostion + "/" + gQueueData.length + " ) " + theRequesterName + " :: " + gOriginalTitle;
		},1000);
	}
	window.addEventListener("storage", mainListener, false);
	sendPingMessage(gThisTarget);
});