Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
Adé Mochtar committed Nov 28, 2018
0 parents commit 8fe0934
Show file tree
Hide file tree
Showing 13 changed files with 519 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.crx
*.xpi
*.zip
3 changes: 3 additions & 0 deletions .web-extension-id
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# This file was created by https://github.com/mozilla/web-ext
# Your auto-generated extension ID for addons.mozilla.org is:
{ace7ba65-c6a8-4f2c-934f-f03716c34132}
9 changes: 9 additions & 0 deletions browser-polyfill.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 99 additions & 0 deletions calculate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// note: days and levels are 1-based here
function getMemberCompletionDayLevel(member, day, level) {
let completed = null

if (member.completion_day_level !== undefined &&
member.completion_day_level[day] != undefined &&
member.completion_day_level[day][level] !== undefined &&
member.completion_day_level[day][level].get_star_ts !== undefined) {
completed = member.completion_day_level[day][level].get_star_ts
}

return completed
}

// note: days and levels are 1-based here
function compareMembersByDayLevel(day, level) {
return function (a, b) {
aCompleted = getMemberCompletionDayLevel(a, day, level)
bCompleted = getMemberCompletionDayLevel(b, day, level)

if (aCompleted === bCompleted) {
return +b.id - +a.id
}
if (aCompleted === null) {
return 1
}
if (bCompleted === null) {
return -1
}
return +aCompleted - +bCompleted
}
}

// note: day is 0-based here
function compareRankingByDay(day) {
return function (a, b) {
if (a.total_scores[day] === b.total_scores[day]) {
return +a.id - +b.id
}
return b.total_scores[day] - a.total_scores[day]
}
}

function calculateRanking(data) {
// initialize ranking structure
members = Object.values(data.members)
ranking = {}
members.forEach(member => ranking[member.id] = {
id: member.id,
name: member.name,
total_score: 0,
scores: [],
ranks: [],
stars: [],
total_scores: [],
total_ranks: []
})

// max score per star is number of members
max_score = members.length

// do actual calculation of scores, ranks and stars
for (let d = 0; d < 25; d++) {
for (let l = 1; l <= 2; l++) {
members.sort(compareMembersByDayLevel(d+1, l))
members.forEach(function (member, index) {
if (ranking[member.id].scores[d] === undefined) {
ranking[member.id].scores[d] = 0
}

if (ranking[member.id].stars[d] === undefined) {
ranking[member.id].stars[d] = 0
}

completed = getMemberCompletionDayLevel(member, d+1, l)
if (completed !== null) {
ranking[member.id].stars[d] = l
score = max_score - index
ranking[member.id].scores[d] += score
ranking[member.id].total_score += score
}

ranking[member.id].ranks[d] = index + 1
ranking[member.id].total_scores[d] = ranking[member.id].total_score
})
}
}
ranking = Object.values(ranking)

// finally get total_ranks for all days
for (let d = 0; d < 25; d++) {
ranking.sort(compareRankingByDay(d))
ranking.forEach(function(rank, index) {
ranking[index].total_ranks[d] = index + 1
})
}

return {ranking: ranking}
}
4 changes: 4 additions & 0 deletions d3.v2.min.js

Large diffs are not rendered by default.

Binary file added icons/aoc-ranking-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/aoc-ranking-48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/aoc-ranking-96.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/aoc-ranking-screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
function fetchData(url, key) {
return fetch(url)
.then(response => response.json())
.then(data => {
val = {
data: data,
date: new Date().getTime()
}
browser.storage.local.set({[key]: val})
return data
})
.catch(err => {console.log(err)})
}

function loadData() {
return new Promise((resolve, reject) => {
url = document.location.href.split('#')[0] + ".json"
parts = document.location.pathname.split('/')
key = parts[1] + '_' + parts.pop()

browser.storage.local.get(key).then(k => {
if (k === null || !k.hasOwnProperty(key) || !k[key].hasOwnProperty('data') || !k[[key]].hasOwnProperty('date')) {
fetchData(url, key).then(data => resolve(data))
} else {
ttl = new Date(k[key].date + 60000)
if (ttl < new Date()) {
fetchData(url, key).then(data => resolve(data))
} else {
resolve(k[key].data)
}
}
})
})
}

loadData()
.then(data => calculateRanking(data))
.then(ranking => visualize(ranking))
20 changes: 20 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"manifest_version": 2,
"name": "AoC Ranking",
"version": "1.0.7",

"description": "Visualize the ranking over time of a Advent of Code private leaderboard",

"icons": {
"48": "icons/aoc-ranking-48.png",
"96": "icons/aoc-ranking-96.png"
},

"permissions": ["storage"],

"content_scripts": [{
"matches": ["https://adventofcode.com/*/leaderboard/private/view/*"],
"js": ["browser-polyfill.min.js", "d3.v2.min.js", "calculate.js", "visualize.js", "loader.js"],
"css": ["ranking.css"]
}]
}
60 changes: 60 additions & 0 deletions ranking.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* body {
margin: 0;
padding: 0;
background-color: #0f0f23;
font-family: "Source Code Pro", monospace;
font-size: 14px;
color: #cccccc;
overflow: hidden;
} */

/* h1, h1 a {
font-size: 20px;
color: #00cc00;
text-shadow: 0 0 2px #00cc00, 0 0 5px #00cc00;
text-align: center;
}
#attrib {
position: absolute;
bottom: 0px;
width: 100%;
padding: 10px;
font-size: 10px;
color: #cccccc;
text-align: center;
}
#attrib a {
color: #ffffff;
text-shadow: 0 0 5px #ffffff;
} */

#chart {
overflow-y: auto;
width: 100%;
}

text.day {
fill: #999999;
}

text.label {
fill: #000000;
}

text.label.medal {
font-weight: bold;
}

circle.medal {
stroke-width: 1;
}

polyline.ranking {
fill: none;
stroke-width: 3;
}

line.tickLine {
stroke: #999999;
}
Loading

0 comments on commit 8fe0934

Please sign in to comment.