Skip to content

Instantly share code, notes, and snippets.

@tKe
Created December 4, 2022 13:30
Show Gist options
  • Save tKe/ae45147502866ab765fa52c366181c9e to your computer and use it in GitHub Desktop.
Save tKe/ae45147502866ab765fa52c366181c9e to your computer and use it in GitHub Desktop.
Advent of Code Leaderboard Log
#!/usr/bin/env sh
set -o errexit
set -o pipefail
readonly BOARD=${1?Missing leaderboard id}
readonly YEAR=${2:-$(date +%Y)}
readonly LOG_LIMIT=${3:-20}
readonly BOARD_CACHE="/tmp/.aoc-cache"
readonly BOARD_FILE="$BOARD_CACHE/leaderboard-$BOARD-$YEAR.json"
mkdir -p "$BOARD_CACHE"
if [ ! -f "$BOARD_FILE" ] || [ $(( $(date +%s) - $(date -r "$BOARD_FILE" +%s) > 900 )) -eq 1 ]; then
readonly SESSION_COOKIE=$(cat .session-cookie 2>/dev/null)
: ${SESSION_COOKIE:?Missing session cookie}
curl --silent -b "session=$SESSION_COOKIE" \
"https://adventofcode.com/$YEAR/leaderboard/private/view/$BOARD.json" > "$BOARD_FILE" || rm "$BOARD_FILE"
if [ ! -f "$BOARD_FILE" ]; then
echo "Failed to download leaderboard json - is the session cookie valid?" >&2
exit 1
fi
fi
<"$BOARD_FILE" jq -r --argjson loglim "$LOG_LIMIT" '
def star: ["⚫️","⭐️","🌟"][tonumber];
def ansi(n): "\u001b[\(n)m\(.)\u001b[0m";
def stars: [.completion_day_level["\(range(1;26))"]|length|star]|join("");
def strip_ansi: tostring|gsub("\u001b\\[[0-9;]+?m"; "");
def pad($align;$width):
if $align == 0 then .
else
(($width - (strip_ansi|length) + ($align|length-1)) * " " // "") as $padding |
if $align < 0 then $padding + .
else . + $padding end
end;
def format_tbl($align):
(transpose | map(map(strip_ansi|length)|max)) as $widths |
.[] | to_entries |
map(.key as $k|.value|pad($align[$k];$widths[$k])) |
join(" ");
def log: .members | map(
{name} + (
.completion_day_level |
to_entries[] |
{day: .key} + (.value|to_entries[]) |
{action: "got \(.key|star) for day \(.day)!",ts:.value.get_star_ts}
)
) |
sort_by(.ts)[-$loglim:][] |
"\(.ts | strftime("Day %d %H:%M:%S") | ansi(36)) \(.name|ansi(32)) \(.action)";
def standings: [.members[]] |
sort_by(-.local_score) |
to_entries | map(.value + {rank:(.key+1)}) |
map([("\(.rank))" | ansi(1)), (.local_score | ansi(33)), stars, (.name | ansi(32))]) |
[
["", "", " 1 5 10 15 20 25" | ansi(4)],
.[]
] | format_tbl([-3,-2,0,1]);
# fix anonymous names
(.members |= with_entries(.value.name = (.value.name // "(anonymous user #\(.key))"))) |
# generate output
("\(.members[.owner_id|tostring].name)'\''s Leaderboard" | ansi("1;4")), "",
("Current Standings" | ansi("1;4")), standings, "",
("Star Log" | ansi("1;4")), log
'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment