132 lines
3.8 KiB
Python
132 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
import json
|
|
import requests
|
|
import datetime
|
|
import time
|
|
|
|
CONFIG_FILE = "aocDiscordConfig.json"
|
|
DATA_FILE = "aocDiscordData.json"
|
|
|
|
|
|
def get_star_state(n, day, is_part_two):
|
|
target_bit = ((day - 1) * 2) + (1 if is_part_two else 0)
|
|
return (n & (1 << target_bit)) != 0
|
|
|
|
|
|
def count_stars(n):
|
|
x = 0
|
|
while n != 0:
|
|
if n & 1 == 1:
|
|
x += 1
|
|
n = n >> 1
|
|
return x
|
|
|
|
|
|
def transform_response(x):
|
|
res = {}
|
|
for user_id in x["members"]:
|
|
n = 0
|
|
for day_number in x["members"][user_id]["completion_day_level"]:
|
|
day = int(day_number)
|
|
if "1" in x["members"][user_id]["completion_day_level"][day_number]:
|
|
n = n | (1 << ((day - 1) * 2))
|
|
if "2" in x["members"][user_id]["completion_day_level"][day_number]:
|
|
n = n | (1 << (((day - 1) * 2) + 1))
|
|
res[user_id] = n
|
|
return res
|
|
|
|
|
|
def dump_data(dat):
|
|
f = open(DATA_FILE, "w")
|
|
json.dump(transform_response(dat), f)
|
|
f.close()
|
|
|
|
|
|
def make_embed(player, day, part, time):
|
|
return {
|
|
"title": f"{player} solved day {day}, part {part}!",
|
|
"color": 0xFFFF66 if part == "2" else 0x9999CC,
|
|
"timestamp": datetime.datetime.fromtimestamp(int(time)).isoformat(),
|
|
}
|
|
|
|
|
|
def send_embeds(url, embeds):
|
|
while len(embeds) != 0:
|
|
time.sleep(1)
|
|
n = 10
|
|
if len(embeds) < n:
|
|
n = len(embeds)
|
|
|
|
requests.post(url, json={"embeds": embeds[:n]}).raise_for_status()
|
|
|
|
embeds = embeds[n:]
|
|
|
|
|
|
def main():
|
|
# load settings
|
|
with open(CONFIG_FILE) as f:
|
|
raw_json = json.load(f)
|
|
SESSION_TOKEN = raw_json["session"]
|
|
LEADERBOARD_ID = raw_json["leaderboardID"]
|
|
WEBHOOK_URL = raw_json["webhook"]
|
|
EMAIL_ADDR = raw_json["email_address"]
|
|
|
|
r = requests.get(
|
|
f"https://adventofcode.com/2022/leaderboard/private/view/{LEADERBOARD_ID}.json",
|
|
cookies={"session": SESSION_TOKEN},
|
|
headers={"User-Agent": EMAIL_ADDR},
|
|
)
|
|
r.raise_for_status()
|
|
response = r.json()
|
|
|
|
# load cache file
|
|
try:
|
|
f = open(DATA_FILE)
|
|
historial_data = json.load(f)
|
|
f.close()
|
|
except FileNotFoundError:
|
|
dump_data(response)
|
|
return
|
|
|
|
embeds = []
|
|
for user_id in response["members"]:
|
|
n = historial_data.get(user_id, 0)
|
|
historical_num_stars = count_stars(n)
|
|
current_num_stars = response["members"][user_id]["stars"]
|
|
|
|
if current_num_stars != historical_num_stars:
|
|
|
|
for day_number in response["members"][user_id]["completion_day_level"]:
|
|
day = int(day_number)
|
|
ds = response["members"][user_id]["completion_day_level"][day_number]
|
|
|
|
if not get_star_state(n, day, False) and "1" in ds:
|
|
embeds.append(
|
|
make_embed(
|
|
response["members"][user_id]["name"],
|
|
day_number,
|
|
"1",
|
|
response["members"][user_id]["completion_day_level"][
|
|
day_number
|
|
]["1"]["get_star_ts"],
|
|
)
|
|
)
|
|
if not get_star_state(n, day, True) and "2" in ds:
|
|
embeds.append(
|
|
make_embed(
|
|
response["members"][user_id]["name"],
|
|
day_number,
|
|
"2",
|
|
response["members"][user_id]["completion_day_level"][
|
|
day_number
|
|
]["2"]["get_star_ts"],
|
|
)
|
|
)
|
|
|
|
send_embeds(WEBHOOK_URL, embeds)
|
|
|
|
dump_data(response)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|