-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
leaderboard.py
executable file
·118 lines (94 loc) · 3.11 KB
/
leaderboard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python
'''
This script will grab the leaderboard from Advent of Code and post it to Slack
'''
# pylint: disable=wrong-import-order
# pylint: disable=C0301,C0103,C0209
import os
import datetime
import sys
import json
import requests
LEADERBOARD_ID = os.environ.get('LEADERBOARD_ID')
SESSION_ID = os.environ.get('SESSION_ID')
SLACK_WEBHOOK = os.environ.get('SLACK_WEBHOOK')
# If the ENV Var hasn't been set, then try to load from local config.
# Simply create secrets.py with these values defined.
# See README for more detailed directions on how to fill these variables.
if not all([LEADERBOARD_ID, SESSION_ID, SLACK_WEBHOOK]):
from secrets import LEADERBOARD_ID, SESSION_ID, SLACK_WEBHOOK
# You should not need to change this URL
LEADERBOARD_URL = "https://adventofcode.com/{}/leaderboard/private/view/{}".format(
datetime.datetime.today().year,
LEADERBOARD_ID)
def formatLeaderMessage(members):
"""
Format the message to conform to Slack's API
"""
message = ""
# add each member to message
medals = [':third_place_medal:', ':second_place_medal:', ':trophy:']
for username, score, stars in members:
if medals:
medal = ' ' + medals.pop()
else:
medal = ''
message += f"{medal}*{username}* {score} Points, {stars} Stars\n"
message += f"\n<{LEADERBOARD_URL}|View Leaderboard Online>"
return message
def parseMembers(members_json):
"""
Handle member lists from AoC leaderboard
"""
# get member name, score and stars
members = [(m["name"],
m["local_score"],
m["stars"]
) for m in members_json.values()]
# sort members by score, descending
members.sort(key=lambda s: (-s[1], -s[2]))
return members
def postMessage(message):
"""
Post the message to to Slack's API in the proper channel
"""
payload = json.dumps({
"icon_emoji": ":christmas_tree:",
"username": "Advent Of Code Leaderboard",
"text": message
})
requests.post(
SLACK_WEBHOOK,
data=payload,
timeout=60,
headers={"Content-Type": "application/json"}
)
def main():
"""
Main program loop
"""
# make sure all variables are filled
if LEADERBOARD_ID == "" or SESSION_ID == "" or SLACK_WEBHOOK == "":
print("Please update script variables before running script.\n\
See README for details on how to do this.")
sys.exit(1)
# retrieve leaderboard
r = requests.get(
"{}.json".format(LEADERBOARD_URL),
timeout=60,
cookies={"session": SESSION_ID},
headers={
'User-Agent': 'https://github.com/tomswartz07/AdventOfCodeLeaderboard'
}
)
if r.status_code != requests.codes.ok: # pylint: disable=no-member
print("Error retrieving leaderboard")
sys.exit(1)
# get members from json
members = parseMembers(r.json()["members"])
# generate message to send to slack
message = formatLeaderMessage(members)
# send message to slack
postMessage(message)
if __name__ == "__main__":
main()