-
-
Save JrRandy/366612f0f7e1e239539937f8ede5527e to your computer and use it in GitHub Desktop.
useful script for Rainforest History page.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Rainforest Jobs | |
// @namespace http://tampermonkey.net/ | |
// @version 47 | |
// @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/* | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
var EasyCopy = true; //adjust this variables to control the easy copy/paste stats under the tables (true/false) | |
var isCF = false; //adjust this variable for CrowdFlower of non-crowdflower (true/false) | |
var CFinDollar = false; //adjust this variable to show summary table in $ instead of C for CF | |
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"; | |
} | |
} | |
} | |
var curURL = window.location.href; | |
if (!curURL.includes("&page_size=100")) { | |
if (curURL.includes("/profile") && !curURL.includes("/edit") || curURL.includes('/tester')) { | |
var stats = document.querySelectorAll("span.tester-stat-number"); | |
var earned = stats[0], jobs = stats[1], bugs = stats[2]; | |
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]; | |
/** Running the Script **/ | |
var yesterday = new Date(new Date().setDate(new Date().getDate()-1)); | |
createTable({date: new Date(), text: 'Today'}); | |
createTable({date: yesterday, text: 'Yesterday'}); | |
/** End Script **/ | |
/** Bunch of Functions Below **/ | |
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; | |
var submitDateUTC = dateStr.replace(/ UTC/, ""); | |
var submitDate = new Date(submitDateUTC); | |
return requestDate.getUTCDate() === submitDate.getDate(); | |
} | |
function getCell(row, cell) { | |
return rfTable.rows[row].cells[cell].innerHTML; | |
} | |
for (var i = 1; i < rfTable.rows.length; i++) { | |
// job id to link | |
var jobIDcell = rfTable.rows[i].cells[0]; | |
var id = jobIDcell.innerHTML; | |
var link = 'https://portal.rainforestqa.com/retrospective/' + id; | |
var hyperlink = document.createElement('a'); | |
hyperlink.innerHTML = id; | |
hyperlink.setAttribute('href', link); | |
hyperlink.setAttribute('target', '_blank'); | |
jobIDcell.innerHTML = ""; | |
jobIDcell.appendChild(hyperlink); | |
// end job id to link | |
if(isToday(getCell(i, 1) + ' 00:00:01')) { | |
if (cleanCurrency(getCell(i,6)) === 0 && cleanCurrency(getCell(i,5)) === 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,6)); | |
pending += cleanCurrency(getCell(i,5)); | |
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 = .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 (day.text === 'Today') { | |
if (jobCount+trainingJobs >= 100) { | |
Bonus = TotalPay/5; | |
} else if (jobCount+trainingJobs >= 10) { | |
Bonus = TotalPay/10; | |
} else { | |
Bonus = 0; | |
} | |
} else { | |
if (jobCount+trainingJobs >= 100) { | |
Bonus = TotalPay/120*20; | |
} else if (jobCount+trainingJobs >= 10) { | |
Bonus = TotalPay/110*10; | |
} else { | |
Bonus = 0; | |
} | |
} | |
var Steps = 0; | |
if (day.text === 'Today') { | |
Steps = TotalPay/STEPPAY; | |
} else { | |
Steps = (TotalPay-Bonus)/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 = [ | |
{ | |
heading: 'Paid', | |
value: formatText(paid) | |
}, | |
{ | |
heading: 'Pending', | |
value: formatText(pending) | |
}, | |
{ | |
heading: 'Total', | |
value: formatText(TotalPay) | |
}, | |
{ | |
heading: 'Est. Bonus', | |
value: formatText(Bonus) | |
}, | |
{ | |
heading: 'Pay/Job', | |
value: formatText(avgperjob) | |
}, | |
{ | |
heading: 'Job Count', | |
value: jobCount | |
}, | |
{ | |
heading: 'Training', | |
value: trainingJobs | |
}, | |
{ | |
heading: 'Steps', | |
value: Steps.toFixed(0) | |
}, | |
{ | |
heading: 'Steps/Job', | |
value: avgsteps.toFixed(2) | |
}, | |
{ | |
heading: 'Time', | |
value: formatSeconds(timeSpent) | |
} | |
]; | |
var cssData = [ | |
{ | |
selector: 'table#info', | |
rules: [ | |
'border-collapse:collapse;', | |
'border-color:#ccc;', | |
'border:none;' | |
] | |
}, | |
{ | |
selector: 'table#info tr th', | |
rules: [ | |
'background-color:#f0f0f0;' | |
] | |
}, | |
{ | |
selector: 'table#info tr th, table#info tr td', | |
rules: [ | |
'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;' | |
] | |
}, | |
{ | |
selector: 'table#info tr td:nth-child(even)', | |
rules: [ | |
'background-color:#fff;' | |
] | |
}, | |
{ | |
selector: 'table#info tr td:nth-child(odd)', | |
rules: [ | |
'background-color:#f9f9f9;' | |
] | |
} | |
]; | |
if (day.text === "Today") { // only need to run this once | |
var style = generateCSS(cssData); | |
$(style).insertBefore(rfTable); | |
} | |
var div = document.createElement('div'); | |
var br = document.createElement('br'); | |
div.appendChild(br); | |
var title = document.createElement('center'); | |
title.innerHTML = day.text + "'s Summary"; | |
div.appendChild(title); | |
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); | |
} | |
$(div).insertBefore(rfTable); | |
} // 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; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This script is for TamperMonkey (http://tampermonkey.net/)
Download the Tamper Monkey application
Install the Tamper Monkey application
Left click on the Tamper Monkey addon
Select "Add a new script..." or "Create a new script..."
Replace everything in the editor window with the code above
Save
Reload your history page, and you should be good to go!