Skip to content

Commit 3718280

Browse files
committedDec 18, 2022
Merge remote-tracking branch 'origin/mxl0velace/add-star-display'
Also add year option to command and a title to scoreboard output
2 parents 2db960c + 5757b1e commit 3718280

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed
 

‎src/main.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
MAX_MESSAGE_LEN = 2000 - 6
2323

2424
PLAYER_STR_FORMAT = '{rank:2}) {name:{name_pad}} ({points:{points_pad}}) {stars:{stars_pad}}* ({star_time})\n'
25+
PLAYER_STR_FORMAT_NOPOINTS = '{rank:2}) {name:{name_pad}} {stars:{stars_pad}}* ({star_time})\n'
2526
URL_STR_FORMAT = 'https://adventofcode.com/{year}/leaderboard/private/view/{leaderboard_id}.json'
2627

2728
USER_AGENT = 'github.com/CSSUoB/advent-of-code-bot by cssoc@cs.bham.ac.uk'
@@ -265,4 +266,65 @@ async def daily(context, day: str = None, year: int = CURRENT_YEAR):
265266
await output_leaderboard(context, ranking, f'Leaderboard for {year}, day {day}:\n')
266267

267268

269+
@bot.command(name='stars', help='Will give the time of completion of each star for specified day')
270+
async def stars(context, day: str = None, year: int = CURRENT_YEAR):
271+
# The default day calculation cannot be in the function default value because the default
272+
# value is evaluated when the program is started, not when the function is called
273+
if day is None:
274+
# The default day is whatever day's challenge has just come out
275+
# So at 4.59AM UTC it will still show previous day's leaderboard
276+
day = str((datetime.datetime.today() - datetime.timedelta(hours=5)).day)
277+
278+
# Only respond if used in a channel containing CHANNEL_NAME
279+
if CHANNEL_NAME not in context.channel.name:
280+
return
281+
282+
print("Star time leaderboard requested for day:", day)
283+
players = get_players(year)
284+
285+
# Goes through all the players checking if they have data for that day and if they do adding to players_days
286+
players_day = [player for player in players if day in player[4]]
287+
288+
# Players_day has all people who have finished one star for that day
289+
stars = []
290+
291+
# Adds all stars achieved to the stars list
292+
for player_day in players_day:
293+
if '1' in player_day[4][day]:
294+
stars.append((player_day[0], int(player_day[4][day]['1']['get_star_ts']), '1'))
295+
if '2' in player_day[4][day]:
296+
stars.append((player_day[0], int(player_day[4][day]['2']['get_star_ts']), '2'))
297+
298+
# Sorts the list on timestamps
299+
stars.sort(key=lambda data: data[1])
300+
301+
final_table = []
302+
303+
# Adds all the stars to the final list
304+
for i, player in enumerate(stars):
305+
final_table.append((player[0], (len(stars) - i), player[1], player[2]))
306+
307+
# Sorts the table by timestamp
308+
final_table.sort(key=lambda data: data[2])
309+
310+
# Outputs data
311+
if not final_table:
312+
result = "```No Scores for this day yet```"
313+
await context.send(result)
314+
else:
315+
# Get string lengths for the format string
316+
max_name_len = len(max(final_table, key=lambda t: len(t[0]))[0])
317+
max_points_len = len(str(max(final_table, key=lambda t: t[1])[1]))
318+
max_stars_len = len(str(max(final_table, key=lambda t: t[3])[3]))
319+
leaderboard = []
320+
for place, player in enumerate(final_table):
321+
leaderboard.append(PLAYER_STR_FORMAT_NOPOINTS.format(rank=place+1,
322+
name=player[0], name_pad=max_name_len,
323+
points=player[1], points_pad=max_points_len,
324+
stars=player[3], stars_pad=max_stars_len,
325+
star_time=time.strftime('%H:%M %d/%m',
326+
time.localtime(player[2]))))
327+
await output_leaderboard(context, leaderboard, f'Stars for day {day}, {year}:\n')
328+
329+
268330
bot.run(TOKEN)

0 commit comments

Comments
 (0)
Please sign in to comment.