commit
eb0f3cec07
2 changed files with 104 additions and 0 deletions
@ -0,0 +1,95 @@ |
|||
import discord |
|||
from discord.ext import tasks |
|||
import os |
|||
import sqlite3 |
|||
from aiohttp import ClientSession |
|||
import json |
|||
|
|||
client = discord.Client() |
|||
conn = sqlite3.connect('data.db') |
|||
|
|||
def setup(): |
|||
conn.execute(''' |
|||
CREATE TABLE IF NOT EXISTS |
|||
guild(id int primary key, channel int, leaderboard int, last_sync text) |
|||
''') |
|||
|
|||
@client.event |
|||
async def on_ready(): |
|||
print('We have logged in as {0.user}'.format(client)) |
|||
|
|||
@client.event |
|||
async def on_message(message): |
|||
if message.content.startswith("!setup"): |
|||
leaderboard = int(message.content[7:]) |
|||
conn.execute(''' |
|||
insert into guild(id, channel, leaderboard, last_sync) |
|||
values (?, ?, ?, ?) on conflict(id) do |
|||
update set channel=excluded.channel, leaderboard=excluded.leaderboard''', |
|||
(message.guild.id, message.channel.id, leaderboard, None)) |
|||
conn.commit() |
|||
await message.channel.send( |
|||
'Updated {0.guild} to use channel {0.channel} and leaderboard {1}!' |
|||
.format(message, leaderboard)) |
|||
|
|||
def gather_stars(member): |
|||
star_list = [] |
|||
for day in member['completion_day_level']: |
|||
stars = member['completion_day_level'][day] |
|||
if "1" in stars: |
|||
star_list.append((member['name'], int(day), 1, stars['1']['get_star_ts'])) |
|||
if "2" in stars: |
|||
star_list.append((member['name'], int(day), 2, stars["2"]['get_star_ts'])) |
|||
return star_list |
|||
|
|||
def perform_member_diff(old_member, new_member): |
|||
old_stars = gather_stars(old_member) |
|||
new_stars = gather_stars(new_member) |
|||
return [star for star in new_stars if star not in old_stars] |
|||
|
|||
def perform_diff(old_json, new_json): |
|||
if old_json is None: |
|||
old_json = {'members': {}} |
|||
else: |
|||
old_json = json.loads(old_json) |
|||
new_json = json.loads(new_json) |
|||
diff = { 'join': [], 'new_stars': [] } |
|||
for new_member in new_json['members'].keys(): |
|||
if new_member not in old_json['members']: |
|||
diff['join'].append(new_json['members'][new_member]['name']) |
|||
continue |
|||
member_diff = perform_member_diff(old_json['members'][new_member], new_json['members'][new_member]) |
|||
diff['new_stars'] += member_diff |
|||
return diff |
|||
|
|||
async def send_diff(id, channel, diff): |
|||
announcements = [] |
|||
for user in diff['join']: |
|||
full_text = "User {0} joined the leaderboard!".format(user) |
|||
announcements.append(full_text) |
|||
for (user, day, star, ts) in diff['new_stars']: |
|||
star_name = "silver" if star == 1 else "gold" |
|||
full_text = "{0} won the {1} star from day {2}!".format(user, star_name, day) |
|||
announcements.append(full_text) |
|||
|
|||
if len(announcements) != 0: |
|||
channel = await client.fetch_channel(channel) |
|||
await channel.send("\n".join(announcements)) |
|||
|
|||
@tasks.loop(minutes=1.0) |
|||
async def update_aoc(): |
|||
url_string = "https://adventofcode.com/2020/leaderboard/private/view/{0}.json" |
|||
cookies = { 'session': os.getenv("AOC_SESSION") } |
|||
|
|||
async with ClientSession(cookies=cookies) as session: |
|||
for (id, channel, leaderboard, json) in conn.execute('select * from guild'): |
|||
async with session.get(url_string.format(leaderboard)) as resp: |
|||
new_json = await resp.text() |
|||
diff = perform_diff(json, new_json) |
|||
await send_diff(id, channel, diff) |
|||
conn.execute('update guild set last_sync=? where id=?', (new_json, id)) |
|||
conn.commit() |
|||
|
|||
setup() |
|||
update_aoc.start() |
|||
client.run(os.environ['AOC_BOT_TOKEN']) |
@ -0,0 +1,9 @@ |
|||
aiohttp==3.6.3 |
|||
async-timeout==3.0.1 |
|||
attrs==20.3.0 |
|||
chardet==3.0.4 |
|||
discord==1.0.1 |
|||
discord.py==1.5.1 |
|||
idna==2.10 |
|||
multidict==4.7.6 |
|||
yarl==1.5.1 |
Loading…
Reference in new issue