Skip to content

Instantly share code, notes, and snippets.

@sweeneyapps
Last active May 28, 2021 23:20
Show Gist options
  • Save sweeneyapps/7b6b4ff194ce47e5e672964ec0d70068 to your computer and use it in GitHub Desktop.
Save sweeneyapps/7b6b4ff194ce47e5e672964ec0d70068 to your computer and use it in GitHub Desktop.
RF Job History TamperMonkey script ( v.56 )
// ==UserScript==
// @name Rainforest Jobs
// @namespace http://tampermonkey.net/
// @version 56
// @description collect info from job page
// @author Paul Sweeney Jr. (Code cleaner), ixamy (original idea)
// @modifier JrRandy
// @credits taruga, marco.aguiaram, russ, uangonline2016, mariusb
// @match https://portal.rainforestqa.com/*
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
var EasyCopy = true; //adjust this variables to control the easy copy/paste stats under the tables (true/false)
var isCF = true; //adjust this variable for CrowdFlower of non-crowdflower (true/false)
var CFinDollar = true; //adjust this variable to show summary table in $ instead of C for CF
var runCssOnce = true;
var rejectionButton;
var reviewButton;
var rfLinks = document.querySelectorAll("a.primary");
if (rfLinks) {
for (var i = 0; i < rfLinks.length; i++) {
var link = rfLinks[i];
if (link.innerHTML === "History" && !link.href.includes("&page_size=100")) {
link.href = link.href + "&page_size=100";
}
if (link.innerHTML.includes("Rejected")) {
rejectionButton = link;
}
if (link.innerHTML.includes("Reviews")) {
reviewButton = link;
}
}
}
var curURL = window.location.href;
if (!curURL.includes("&page_size=100")) {
if (curURL.includes("/profile") && !curURL.includes("/edit") || curURL.includes('/tester')) {
var earned, jobs, bugs, rejection, score;
var allStatsLabel = document.querySelectorAll('.tester-stat-label');
for( var all in allStatsLabel ) {
if ( allStatsLabel[all].innerText && allStatsLabel[all].innerText.includes("EARNED") ) {
earned = allStatsLabel[all].nextElementSibling;
}
if ( allStatsLabel[all].innerText && allStatsLabel[all].innerText.includes("JOBS") ) {
jobs = allStatsLabel[all].nextElementSibling;
}
if ( allStatsLabel[all].innerText && allStatsLabel[all].innerText.includes("BUGS") ) {
bugs = allStatsLabel[all].nextElementSibling.nextElementSibling;
}
if ( allStatsLabel[all].innerText && allStatsLabel[all].innerText.includes("SCORE") ) {
score = allStatsLabel[all].nextElementSibling.innerText;
reviewButton.innerHTML = "Reviews " + "(" + score + ")";
}
if ( allStatsLabel[all].innerText && allStatsLabel[all].innerText.includes("REJECTIONS") ) {
rejection = allStatsLabel[all].nextElementSibling.innerText;
rejectionButton.innerHTML = "Rejected Training Jobs " + "(" + rejection + ")";
}
}
// debugging for developers only
console.log("EARNED: " + earned.innerHTML);
console.log("JOBS: " + jobs.innerHTML);
console.log("BUGS: " + bugs.innerHTML);
console.log("REJECTION: " + rejection);
console.log("SCORE: " + score);
if (isCF) earned.innerHTML = "$" + (Number(earned.innerHTML.replace("c", "")) / 100);
var percent = ((parseInt(bugs.innerHTML) / parseInt(jobs.innerHTML)) * 100).toFixed(2);
bugs.innerHTML = bugs.innerHTML + " | " + percent + "%";
}
return; // skip the script below
}
var rfTable = document.getElementsByTagName('table')[1];
var divForTable = document.createElement('div');
$(divForTable).insertBefore(rfTable);
var payFilterSelection = document.getElementById('filter_form');
var page100 = document.createElement('input');
page100.type = "hidden";
page100.name = "page_size";
page100.value = "100";
payFilterSelection.appendChild(page100);
/** Running the Script **/
var dates = {};
getDates(); // setup dates
var dropdownDate = generateDropDown(dates);
$(dropdownDate).insertBefore(divForTable);
var firstDate = Object.keys(dates)[0];
createTable({date: firstDate, text: firstDate});
/** End Script **/
/** Bunch of Functions Below **/
function getDates() {
var tempDates = {};
for (var i = 1; i < rfTable.rows.length; i++) {
var rowDate = rfTable.rows[i].cells[1].innerHTML;
tempDates[rowDate] = rowDate;
}
dates = tempDates;
}
function createTable(day) {
var requestDate = day.date;
var paid = 0;
var pending = 0;
var jobCount = 0;
var reCurr = /\d+\.\d{1,2}|\d+/;
var reCF = /\d+\.0c/;
var CFFIXED = 2;
var CFCENT = "";
var DOLLAR = "$";
var trainingJobs = 0;
var STEPPAY = 0.04;
var timeSpent = 0;
var ts,a,seconds;
function cleanCurrency(currStr) {
if (reCF.test(currStr)) isCF = true;
var cleanCur = currStr.match(reCurr);
return cleanCur ? Number(cleanCur[0]) : 0;
}
function isToday(dateStr) {
if (dateStr === '—') return false;
return requestDate === dateStr;
}
function getCell(row, cell) {
return rfTable.rows[row].cells[cell].innerHTML;
}
for (var i = 1; i < rfTable.rows.length; i++) {
// paypal and payza bug fix
var cashouttest = /Cashout/g;
var broswerCol = getCell(i, 2);
if (cashouttest.test(broswerCol)) continue;
//
if(isToday(getCell(i, 1))) {
if (cleanCurrency(getCell(i,7)) === 0 && cleanCurrency(getCell(i,6)) === 0) {
ts = getCell(i,4);
if (ts !== '—') {
a = ts.split(':');
seconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]);
timeSpent += seconds;
trainingJobs += 1;
}
} else {
paid += cleanCurrency(getCell(i,7));
pending += cleanCurrency(getCell(i,6));
ts = getCell(i,4);
if (ts !== '—') {
a = ts.split(':');
seconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]);
jobCount += 1;
timeSpent += seconds;
}
}
}
}
if(isCF) {
if(CFinDollar) {
CFFIXED = 2;
CFCENT = "";
DOLLAR = "$";
STEPPAY = 0.04;
paid = paid/100;
pending = pending/100;
} else {
CFFIXED = 0;
CFCENT = "c";
DOLLAR = "";
STEPPAY = 4;
}
}
var TotalPay = Number(paid) + Number(pending);
var Bonus=0;
if (jobCount+trainingJobs >= 100) {
Bonus = TotalPay/5;
} else if (jobCount+trainingJobs >= 10) {
Bonus = TotalPay/10;
} else {
Bonus = 0;
}
var Steps = TotalPay/STEPPAY;
var avgperjob = (Number(paid) + Number(pending))/Number(jobCount);
var avgsteps = (Steps)/Number(jobCount);
function formatSeconds(seconds) {
var date = new Date(1970,0,1);
date.setSeconds(seconds);
return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
}
function formatText(txt) {
return DOLLAR + txt.toFixed(CFFIXED) + CFCENT;
}
/** Data Section **/
var tableData = [];
function addTableData(heading, value) {
tableData.push({heading: heading, value: value});
}
addTableData('Paid', formatText(paid));
addTableData('Pending', formatText(pending));
addTableData('Total', formatText(TotalPay));
addTableData('Est. Bonus', formatText(Bonus));
addTableData('Pay/Job', formatText(avgperjob));
addTableData('Job Count', jobCount);
addTableData('Training', trainingJobs);
addTableData('Steps', Steps.toFixed(0));
addTableData('Steps/Job', avgsteps.toFixed(2));
addTableData('Time', formatSeconds(timeSpent));
var cssData = [];
function addCssData(selector, rules) {
cssData.push({selector: selector, rules: rules});
}
addCssData('table#info', [
'border-collapse:collapse;',
'border-color:#ccc;',
'border:none;']);
addCssData('table#info', [
'border-collapse:collapse;',
'border-color:#ccc;',
'border:none;']);
addCssData('table#info tr th', ['background-color:#f0f0f0;']);
addCssData('table#info tr th, table#info tr td', [
'font-family:Arial, sans-serif;',
'font-size:14px;',
'font-weight:normal;',
'padding:10px 5px;',
'padding:10px 5px;',
'border-style:solid;',
'border-width:0px;',
'overflow:hidden;',
'word-break:normal;',
'border-color:#ccc;',
'color:#333;',
'text-align:center;',
'vertical-align:top;']);
addCssData('table#info tr td:nth-child(even)', ['background-color:#fff;']);
addCssData('table#info tr td:nth-child(odd)', ['background-color:#f9f9f9;']);
addCssData('span#summary > center', ['display: inline;']);
if (runCssOnce) { // only need to run this once
var style = generateCSS(cssData);
$(style).insertBefore(rfTable);
runCssOnce = false;
}
var div = document.createElement('div');
var br = document.createElement('br');
div.appendChild(br);
var table = generateTable(day, tableData);
table.id = "info";
div.appendChild(table);
if (EasyCopy) {
var textDiv = document.createElement('div');
textDiv.innerHTML = generateText(day, tableData, ["Steps/Job", "Pay/Job", "Paid", "Pending", "Total", "Est. Bonus"]);
div.appendChild(textDiv);
}
divForTable.innerHTML = "";
divForTable.appendChild(div);
divForTable.innerHTML += "<hr />";
} // end createTable
/** Generators for HTML / TEXT / CSS **/
function generateText(day, data, skip) {
var text = day.text;
for (var i = 0; i < data.length; i++) {
if (skip.indexOf(data[i].heading) !== -1) continue;
text += " " + data[i].heading + ": " + data[i].value + " |";
}
return text;
}
function generateTable(day, data) {
var table = document.createElement('table');
var headingRow = document.createElement('tr');
var valueRow = document.createElement('tr');
table.appendChild(headingRow);
table.appendChild(valueRow);
for (var i = 0; i < data.length; i++) {
var cell = data[i];
var headingCell = document.createElement('th');
var valueCell = document.createElement('td');
headingCell.innerHTML = cell.heading;
valueCell.innerHTML = cell.value;
headingRow.appendChild(headingCell);
valueRow.appendChild(valueCell);
}
return table;
}
function generateCSS(data) {
var style = document.createElement('style');
var cssBody = "";
for (var i = 0; i < data.length; i++) {
var selector = data[i].selector;
var rules = data[i].rules;
cssBody += selector + " { ";
for (var r = 0; r < rules.length; r++){
var rule = rules[r];
cssBody += rule;
}
cssBody += " } ";
}
style.innerText = cssBody;
return style;
}
function generateDropDown(data) {
var dropDown = document.createElement('select');
for (var x in data) {
var option = document.createElement('option');
option.setAttribute('value', data[x]);
option.innerHTML = data[x];
dropDown.appendChild(option);
}
dropDown.onchange = function(event) {
var date = event.target.value;
createTable({date: date, text: date});
};
var title = document.createElement('center');
title.innerHTML = "Summary for ";
var span = document.createElement('span');
span.setAttribute("id", "summary");
span.appendChild(title);
span.appendChild(dropDown);
return span;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment