// ==UserScript==
// @name Yahoo Fantasy Football Rank
// @author Bijan
// @version 2.9
// @description Very simple script to conveniently see how many points a team gives up
// @namespace http://albuyeh.com
// @match *://football.fantasysports.yahoo.com/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require https://greasyfork.org/scripts/5392-waitforkeyelements/code/WaitForKeyElements.js?version=19641
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @icon http://albuyeh.com/FF/Icon.png
// ==/UserScript==
/* CHANGELOG
v2.4: Accidentaly had St Louis listed as 'Stl' and not 'StL'. This caused the script to break as soon as it saw a player/opposing team on St Louis :P
v2.5: I fixed something but forgot what it was
v2.6: Made script more versatille. Watched Mad Max. Fixed a lot of issues of script not showing player stats. Had some chicken nuggets too.
v2.7: Oops. Fixed for realsies.
v2.8: Update waitForKeyElements require to be GreasyFork compliant. Added IDP. Forced redownload
v2.9: Made script work on 'Opponents' page
*/
//Map Team Name to abbreviation
var teamNameList = {
"Arizona Cardinals": "Ari",
"Atlanta Falcons": "Atl",
"Baltimore Ravens": "Bal",
"Buffalo Bills": "Buf",
"Carolina Panthers": "Car",
"Chicago Bears": "Chi",
"Cincinnati Bengals": "Cin",
"Cleveland Browns": "Cle",
"Dallas Cowboys": "Dal",
"Denver Broncos": "Den",
"Detroit Lions": "Det",
"Green Bay Packers": "GB",
"Houston Texans": "Hou",
"Indianapolis Colts": "Ind",
"Jacksonville Jaguars": "Jax",
"Kansas City Chiefs": "KC",
"Miami Dolphins": "Mia",
"Minnesota Vikings": "Min",
"New England Patriots": "NE",
"New Orleans Saints": "NO",
"New York Giants": "NYG",
"New York Jets": "NYJ",
"Oakland Raiders": "Oak",
"Philadelphia Eagles": "Phi",
"Pittsburgh Steelers": "Pit",
"San Diego Chargers": "SD",
"San Francisco 49ers": "SF",
"Seattle Seahawks": "Sea",
"St. Louis Rams": "StL",
"Tampa Bay Buccaneers": "TB",
"Tennessee Titans": "Ten",
"Washington Redskins": "Was",
}
const playerPositions = ["QB", "WR", "RB", "TE", "K", "DEF", "DB", "DL", "LB", "DT", "DE", "CB", "S"]; //Positions to fetch data for
const numPositions = playerPositions.length;
const baseURL = "http://football.fantasysports.yahoo.com/f1/326198/pointsagainst?pos="; //Page to create fetch request to
var rankingsTable = {}; //This will be filled by the AJAX parser.
var final = {}; //Final table that holds all of the team/position info
var result = {};
var numPagesFetched = 0;
var tableName = "FF_Array3";
//Display notification of Update
var ver = GM_info.script.version;
if (GM_getValue("version", "") < ver) {
GM_setValue("version", ver);
alert("Updated Yahoo Fantasy Football Rank by Bijan to version v" + ver);
}
//Fetch results once per day.
var now = new Date();
var currdate = Math.floor(now/8.64e7);
if (GM_getValue("date2", "") < currdate || GM_getValue (tableName, "").length == 0) {
GM_setValue("date2", currdate);
console.log("Fetched results @ :" + currdate);
main(); //Go to main() to fetch data
}
else {
console.log("Already fetched data. Continuing to display results");
displayResults();
}
function main () {
for (var J in playerPositions) {
GM_xmlhttpRequest ( {
method: "GET",
url: baseURL + playerPositions[J],
context: playerPositions[J],
onload: parseResponse,
onerror: function (e) { console.error ('**** error ', e); },
onabort: function (e) { console.error ('**** abort ', e); },
ontimeout: function (e) { console.error ('**** timeout ', e); }
} );
}
}
function parseResponse (response) {
var playerPosition = response.context;
var parser = new DOMParser ();
var ajaxDoc = parser.parseFromString (response.responseText, "text/html");
var statRows = ajaxDoc.querySelectorAll ("#statTable0 > tbody > tr");
var newStatTable = $(statRows).map ( function () {
var tblRow = $(this);
var teamRank = parseInt (tblRow.find (".rank-indicator").text().trim(), 10);
var teamName = teamNameList[tblRow.find ("td:eq(1)").text().trim().split(" vs")[0]];
return [ [teamName, teamRank] ];
} ).get ();
numPagesFetched++;
console.log ('Fetched page ' + numPagesFetched + ' of ' + numPositions + '.');
/*--- Now loop over the fetched rows and collate them into the master table, depending
on playerPosition.
*/
var columnIdx = playerPositions.indexOf (playerPosition);
for (var K in newStatTable) {
var teamName = newStatTable[K][0];
var teamRank = newStatTable[K][1];
var teamStats = rankingsTable[teamName] || new Array (numPositions);
teamStats[columnIdx] = teamRank;
rankingsTable[teamName] = teamStats;
}
if (numPagesFetched === numPositions) {
displayFinalResult ();
}
}
function displayFinalResult () {
//Sort team name
var sortedTeamNames = Object.keys (rankingsTable).sort ( function (zA, zB) {
return zA.localeCompare (zB);
} );
//Store team name and rank array in a single array
for (var J in sortedTeamNames) {
var teamName = sortedTeamNames[J];
if (rankingsTable.hasOwnProperty (teamName) ) {
final[teamName] = rankingsTable[teamName]
}
}
//Save array to browser
GM_setValue (tableName, JSON.stringify (final) );
displayResults(final)
}
function getColor(rank) {
if (1 <= rank && rank <= 10) color = "F-rank-good"; //Green
else if (11 <= rank && rank <= 22) color = "F-rank-neutral"; //Yellow
else if (23 <= rank && rank <= 32) color = "F-rank-bad"; //Red
return color;
}
function displayResults(result) {
//Get saved results
var myList = {};
var myListObj = GM_getValue (tableName, "");
if (myListObj) {
myList = JSON.parse (myListObj);
}
//Check if we have already fetched results for the day
if (typeof result === 'undefined') { result = myList; console.log("Loading pre-loaded data");}
function delinkChangeStat (jNode) {
var raw = jNode[0].innerHTML
//console.log(raw)
if ((player = raw.match(/<span class="Fz-xxs">.*? - (\w+)/)) && (opp = raw.match(/(?:vs|\@) (\w+)/))) {
var playerIndex = playerPositions.indexOf(player[1])
if( playerIndex != -1) {
var rank = result[opp[1]][playerIndex];
console.log(opp[1] + " gives up the #" + rank + " points to the " + player[1] + " position");
jNode.html(jNode.html().replace(opp[1] + "</a>", "<span class='" + getColor(rank) + "'>" + opp[1] + " - " + rank + "</span></a>"))
}
}
}
function opponentsPage (jNode) {
var posA = jNode[0].querySelectorAll('span.Fz-xxs:not(.ysf-player-status):not(.Px-xxs)');
for(i=0; i<posA.length; i++) {
var pos = posA[i].innerHTML.split(" ").slice(-1)[0] //QB
var oppA = jNode[0].querySelectorAll('.P-xs');
for(i=0; i<oppA.length; i++) {
var opp = oppA[i].innerText.trim() //Opposing team without @
var playerIndex = playerPositions.indexOf(pos)
var opp_without = opp.replace("@","")
if (opp_without != "Bye") {
var rank = result[opp_without][playerIndex];
oppA[i].innerHTML = "<span class='" + getColor(rank) + "'>" + oppA[i].innerHTML + " - " + rank + "</span></a>"
}
else {
oppA[i].innerHTML = "<b>" + oppA[i].innerHTML + "</b>";
}
}
}
}
waitForKeyElements (".Mx-a", delinkChangeStat);
waitForKeyElements (".Ov-h", delinkChangeStat);
waitForKeyElements ("tbody > tr.editable:not(.empty-bench)", opponentsPage);
}
// That's it!