Skip to content

Commit 091484e

Browse files
authored
Merge pull request #161 from onerandomusername/qt/sorted-leaderboard
fix: sort the user into the leaderboard if in the top x values, and show the full top users even when a user is provided
2 parents 89f20b8 + a674b6f commit 091484e

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

bot/exts/advent_of_code/_cog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ async def aoc_leaderboard(self, ctx: commands.Context, *, aoc_name: str | None =
398398
number_of_participants = leaderboard["number_of_participants"]
399399

400400
top_count = min(AocConfig.leaderboard_displayed_members, number_of_participants)
401-
self_placement_header = " (and your personal stats compared to the top 10)" if aoc_name else ""
401+
self_placement_header = f" (and your personal stats compared to the top {top_count})" if aoc_name else ""
402402
header = f"Here's our current top {top_count}{self_placement_header}! {Emojis.christmas_tree * 3}"
403403
table = (
404404
"```\n"

bot/exts/advent_of_code/_helpers.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ def leaderboard_sorting_function(entry: tuple[str, dict]) -> tuple[int, int]:
8080
return result["score"], result["star_2"] + result["star_1"]
8181

8282

83+
def _get_user_placement(user_name: str, leaderboard: dict[int, dict]) -> int | None:
84+
"""Get the placement of a specific user in the leaderboard."""
85+
for rank, data in enumerate(leaderboard.values(), start=1):
86+
if data["name"] == user_name:
87+
return rank
88+
return None
89+
90+
8391
def _parse_raw_leaderboard_data(raw_leaderboard_data: dict) -> dict:
8492
"""
8593
Parse the leaderboard data received from the AoC website.
@@ -160,22 +168,29 @@ def _parse_raw_leaderboard_data(raw_leaderboard_data: dict) -> dict:
160168

161169

162170
def _format_leaderboard(leaderboard: dict[str, dict], self_placement_name: str | None = None) -> str:
163-
"""Format the leaderboard using the AOC_TABLE_TEMPLATE."""
171+
"""
172+
Format the leaderboard using the AOC_TABLE_TEMPLATE.
173+
174+
If the rank of self_placement_name is within AdventOfCode.leader_displayed_members, it is placed
175+
in the correct position; otherwise, it is placed just below the header.
176+
"""
164177
leaderboard_lines = [HEADER]
165178
self_placement_exists = False
166179
for rank, data in enumerate(leaderboard.values(), start=1):
167180
if self_placement_name and data["name"].lower() == self_placement_name.lower():
168181
leaderboard_lines.insert(
169-
1,
182+
# Plus one to account for the user being one rank outside of the shown users
183+
rank if rank <= AdventOfCode.leaderboard_displayed_members + 1 else 1,
170184
AOC_TABLE_TEMPLATE.format(
171185
rank=rank,
172186
name=f"(You) {data['name']}",
173187
score=str(data["score"]),
174-
stars=f"({data['star_1']}, {data['star_2']})"
175-
)
188+
stars=f"({data['star_1']}, {data['star_2']})",
189+
),
176190
)
177191
self_placement_exists = True
178192
continue
193+
179194
leaderboard_lines.append(
180195
AOC_TABLE_TEMPLATE.format(
181196
rank=rank,
@@ -279,9 +294,16 @@ async def _upload_leaderboard(leaderboard: str) -> str:
279294
return paste.link
280295

281296

282-
def _get_top_leaderboard(full_leaderboard: str) -> str:
283-
"""Get the leaderboard up to the maximum specified entries."""
284-
return "\n".join(full_leaderboard.splitlines()[:TOP_LEADERBOARD_LINES])
297+
def _get_top_leaderboard(full_leaderboard: str, *, include_self: bool = False) -> str:
298+
"""
299+
Get the leaderboard up to the maximum specified entries.
300+
301+
Include_self specifies whether to include an extra line for the user's placement.
302+
If the user is within the top entries, include_self should be False to avoid an additional entry.
303+
"""
304+
return "\n".join(
305+
full_leaderboard.splitlines()[: TOP_LEADERBOARD_LINES + (1 if include_self else 0)]
306+
) # +1 if including self placement
285307

286308

287309
@_caches.leaderboard_cache.atomic_transaction
@@ -336,8 +358,14 @@ async def fetch_leaderboard(invalidate_cache: bool = False, self_placement_name:
336358
formatted_placement_leaderboard = _parse_raw_leaderboard_data(
337359
json.loads(cached_leaderboard["placement_leaderboard"])
338360
)["leaderboard"]
361+
full_formatted_leaderboard = _format_leaderboard(
362+
formatted_placement_leaderboard, self_placement_name=self_placement_name
363+
)
364+
user_placement = _get_user_placement(self_placement_name, formatted_placement_leaderboard)
365+
include_self = bool(user_placement and user_placement > AdventOfCode.leaderboard_displayed_members)
339366
cached_leaderboard["placement_leaderboard"] = _get_top_leaderboard(
340-
_format_leaderboard(formatted_placement_leaderboard, self_placement_name=self_placement_name)
367+
full_formatted_leaderboard,
368+
include_self=include_self
341369
)
342370
return cached_leaderboard
343371

0 commit comments

Comments
 (0)