Tracks a best-estimate hourly wage on active HITs being worked.
当前为
// ==UserScript==
// @name MTurk Wage Reporter
// @namespace localhost
// @description Tracks a best-estimate hourly wage on active HITs being worked.
// @include https://www.mturk.com/mturk/accept?*
// @include https://www.mturk.com/mturk/previewandaccept?*
// @include https://www.mturk.com/mturk/dashboard*
// @include https://www.mturk.com/mturk/submit*
// @version 0.4b
// @grant GM_setValue
// @grant GM_getValue
// @require http://code.jquery.com/jquery-2.1.1.js
// @downloadURL
// @updateURL
// @author DeliriumTremens 2014
// ==/UserScript==
//
// 2014-07-10 0.1b Beginning development. Creating timer and tab tracker, as well as initial IndexedDB for storage of data.
//
// ------------------------------------------------------------------------------------------------------------------------------------------------
// First, create indexedDB variables.
// Parts borrowed from HITdb
var indexedDB = window.indexedDB || window.webkidIndexedDB || window.mozIndexedDB;
var WageStorage = {};
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.mozIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.mozIDBKeyRange;
WageStorage.IDBTransactionModes = { "READ_ONLY": "readonly", "READ_WRITE": "readwrite", "VERSION_CHANGE": "versionchange" };
var idbKeyRange = window.IDBKeyRange;
WageStorage.indexedDB = {};
WageStorage.indexedDB.db = null;
// Global catch for indexedDB errors
WageStorage.indexedDB.onerror = function(e) {
console.log(e);
}
// Check if database exists. If no database, create one.
// Parts borrowed from HITdb.
var dbExists = true;
var v = 5;
WageStorage.indexedDB.create = function () {
var request = indexedDB.open("WageDB", v);
request.onupgradeneeded = function (e) {
WageStorage.indexedDB.db = e.target.result;
var db = WageStorage.indexedDB.db;
var newDB = false;
if(!db.objectStoreNames.contains("Wage")) {
var store = db.createObjectStore("Wage", { keyPath: "hitId" });
store.createIndex("date", "date", {unique: false});
store.createIndex("reqName", "reqName", {unique: false});
store.createIndex("reqId", "reqId", {unique: false});
store.createIndex("reward", "reward", {unique: false});
store.createIndex("start", "start", {unique: false});
store.createIndex("stop", "stop", {unique: false});
store.createIndex("queue", "queue", {unique: false});
newDB = true;
}
db.close();
}
request.onsuccess = function(e) {
WageStorage.indexedDB.db = e.target.result;
var db = WageStorage.indexedDB.db;
db.close();
}
request.onerror = WageStorage.indexedDB.onerror;
}
// Function for adding HIT data into database
WageStorage.indexedDB.addhit = function () {
var request = indexedDB.open("WageDB", v);
request.onsuccess = function (e) {
WageStorage.indexedDB.db = e.target.result;
var db = WageStorage.indexedDB.db;
var newDB = false;
if(!db.objectStoreNames.contains("Wage")) {
db.close();
}
else {
var trans = db.transaction(["Wage"],WageStorage.IDBTransactionModes.READ_WRITE);
var store = trans.objectStore("Wage");
var request;
request = store.put({ hitId: hitId[1], date: date, reqName: reqName, reqId: reqId[1], reward: reward, start: wageStart, stop: wageEnd, queue: wageExtra });
}
db.close();
}
request.onerror = WageStorage.indexedDB.onerror;
}
// Function for getting current hourly wage for today
WageStorage.indexedDB.getWage = function () {
var request = indexedDB.open("WageDB", v);
request.onsuccess = function (e) {
WageStorage.indexedDB.db = e.target.result;
var db = WageStorage.indexedDB.db
var transaction = db.transaction('Wage','readonly');
var store = transaction.objectStore('Wage');
var index = store.index('date');
var range = IDBKeyRange.only(date);
var results = [];
var tmp_results = {};
index.openCursor(range).onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
var hit = cursor.value;
if (tmp_results[hit.hitId] === undefined) {
tmp_results[hit.hitId] = [];
tmp_results[hit.hitId][0] = hit.reward;
tmp_results[hit.hitId][1] = hit.start;
tmp_results[hit.hitId][2] = hit.stop;
}
cursor.continue();
}
else {
for (var key in tmp_results) {
results.push(tmp_results[key]);
}
addTableElement(results);
}
}
}
}
// Script Variables
var wageLost = false;
var wageExtra = 0;
var wageStart = null;
var wageEnd = null;
var reqId = document.URL.match(/requesterId=(.*?)&/i);
if (reqId) {
GM_setValue("reqId", reqId);
}
else {
reqId = GM_getValue("reqId");
}
// HIT Data
var hitId = document.URL.match(/hitId=(.*?)&/i);
var reward = parseFloat($('span[class="reward"]:eq(1)').text().replace('$',''));
var reqName = $('input[name="prevRequester"]').val();
var date = new Date();
date = date.toLocaleDateString().replace(/\//g,'-');
// Create table element for showing hourly wage. Borrowed from Today's Projected Earnings script
var allTds, thisTd;
var allTdhtml = [];
//allTds = document.getElementsByTagName('td');
addTableElement = function (wage) {
var currStart = 0;
var currEnd = 0;
var currWages = [];
var currWage = 0;
for (var i = 0; i < wage.length; i++) {
currStart = ((wage[i][1] > currStart) ? wage[i][1] : currStart);
currEnd = ((wage[i][2] > currEnd) ? wage[i][2] : currEnd);
currWages.push(((((currEnd - currStart) / 1000) / 3600) * 10000) * wage[i][0]);
}
for (var i = 0; i < currWages.length; i++) {
currWage += currWages[i];
}
currWage = parseFloat(currWage/currWages.length).toFixed(2);
var belowThisTD = (($.inArray('<a href=\"https://www.mturk.com/mturk/dashboard\">Today\'s Projected Earnings</a>',allTdhtml) > -1) ? /Today's Projected Earnings/ : /Total Earnings/ );
var rowColor = (($.inArray('<a href=\"https://www.mturk.com/mturk/dashboard\">Today\'s Projected Earnings</a>',allTdhtml) > -1) ? "#f1f3eb" : "FFFFFF" );
console.log(belowThisTD);
for (var i = 0; i < allTds.length; i++)
{
thisTd = allTds[i];
if ( thisTd.innerHTML.match(belowThisTD) && thisTd.className.match(/metrics\-table\-first\-value/) )
{
var row = document.createElement('tr');
row.className = "even";
row.setAttribute("style",("background-color:" + rowColor));
var hourlyWageTitle = document.createElement('p');
hourlyWageTitle.innerHTML = "Today's Hourly Wage";
hourlyWageTitle.setAttribute("style",("background-color:" + rowColor));
var cellLeft = document.createElement('td');
cellLeft.className = "metrics-table-first-value";
cellLeft.appendChild(hourlyWageTitle);
row.appendChild(cellLeft);
var cellRight = document.createElement('td');
cellRight.innerHTML = "$" + currWage + "/hr";
row.appendChild(cellRight);
thisTd.parentNode.parentNode.insertBefore(row,thisTd.parentNode.nextSibling);
}
}
}
// Timestamp when the HIT is accepted
$(window).ready( function() {
if (document.URL === "https://www.mturk.com/mturk/dashboard" ) {} // Don't record anything on dashboard, instead add appropriate element to tables
else {
wageStart = new Date().getTime();
console.log("Wage Starting!");
}
});
$(window).on('load', function() {
allTds = document.getElementsByTagName('td');
for (var i = 0; i < allTds.length; i++) {
allTdhtml.push(allTds[i].innerHTML);
}
console.log(allTdhtml);
WageStorage.indexedDB.getWage();
});
// Detect if 'Return HIT' button has been clicked to record timer as zero-earnings.
// Timestamp when button was clicked to end time spent.
$('a[href*="/mturk/return?"]').on('click', function() {
wageLost = true;
wageEnd = new Date().getTime();
});
$('img[name="/submit"]').on('click', function() {
wageLost = false;
});
// Create database if not created yet
WageStorage.indexedDB.create();
//WageStorage.indexedDB.getWage();
// Detect the page unloading and react accordingly.
// If return button was clicked, record zero wage earnings, otherwise record earnings.
// Timestamp if submitted to end time spent.
$(window).on('beforeunload', function() {
if (wageLost) {
// ***** DO STUFF WHEN RETURN CLICKED *****
reward = 0;
WageStorage.indexedDB.addhit();
}
else {
// ***** DO STUFF WHEN SUBMITTED *****
wageEnd = new Date().getTime();
WageStorage.indexedDB.addhit();
}
});
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址