@@ -90,6 +90,14 @@ def leaderboard_sorting_function(entry: tuple[str, dict]) -> tuple[int, int]:
9090 return result ["score" ], result ["star_2" ] + result ["star_1" ]
9191
9292
93+ def _get_user_placement (user_name : str , leaderboard : dict [int , dict ]) -> int | None :
94+ """Get the placement of a specific user in the leaderboard."""
95+ for rank , data in enumerate (leaderboard .values (), start = 1 ):
96+ if data ["name" ] == user_name :
97+ return rank
98+ return None
99+
100+
93101def _parse_raw_leaderboard_data (raw_leaderboard_data : dict ) -> dict :
94102 """
95103 Parse the leaderboard data received from the AoC website.
@@ -170,22 +178,29 @@ def _parse_raw_leaderboard_data(raw_leaderboard_data: dict) -> dict:
170178
171179
172180def _format_leaderboard (leaderboard : dict [str , dict ], self_placement_name : str | None = None ) -> str :
173- """Format the leaderboard using the AOC_TABLE_TEMPLATE."""
181+ """
182+ Format the leaderboard using the AOC_TABLE_TEMPLATE.
183+
184+ If the rank of self_placement_name is within AdventOfCode.leader_displayed_members, it is placed
185+ in the correct position; otherwise, it is placed just below the header.
186+ """
174187 leaderboard_lines = [HEADER ]
175188 self_placement_exists = False
176189 for rank , data in enumerate (leaderboard .values (), start = 1 ):
177190 if self_placement_name and data ["name" ].lower () == self_placement_name .lower ():
178191 leaderboard_lines .insert (
179- 1 ,
192+ # Plus one to account for the user being one rank outside of the shown users
193+ rank if rank <= AdventOfCode .leaderboard_displayed_members + 1 else 1 ,
180194 AOC_TABLE_TEMPLATE .format (
181195 rank = rank ,
182196 name = f"(You) { data ['name' ]} " ,
183197 score = str (data ["score" ]),
184- stars = f"({ data ['star_1' ]} , { data ['star_2' ]} )"
185- )
198+ stars = f"({ data ['star_1' ]} , { data ['star_2' ]} )" ,
199+ ),
186200 )
187201 self_placement_exists = True
188202 continue
203+
189204 leaderboard_lines .append (
190205 AOC_TABLE_TEMPLATE .format (
191206 rank = rank ,
@@ -289,9 +304,16 @@ async def _upload_leaderboard(leaderboard: str) -> str:
289304 return paste .link
290305
291306
292- def _get_top_leaderboard (full_leaderboard : str ) -> str :
293- """Get the leaderboard up to the maximum specified entries."""
294- return "\n " .join (full_leaderboard .splitlines ()[:TOP_LEADERBOARD_LINES ])
307+ def _get_top_leaderboard (full_leaderboard : str , * , include_self : bool = False ) -> str :
308+ """
309+ Get the leaderboard up to the maximum specified entries.
310+
311+ Include_self specifies whether to include an extra line for the user's placement.
312+ If the user is within the top entries, include_self should be False to avoid an additional entry.
313+ """
314+ return "\n " .join (
315+ full_leaderboard .splitlines ()[: TOP_LEADERBOARD_LINES + (1 if include_self else 0 )]
316+ ) # +1 if including self placement
295317
296318
297319@_caches .leaderboard_cache .atomic_transaction
@@ -346,8 +368,14 @@ async def fetch_leaderboard(invalidate_cache: bool = False, self_placement_name:
346368 formatted_placement_leaderboard = _parse_raw_leaderboard_data (
347369 json .loads (cached_leaderboard ["placement_leaderboard" ])
348370 )["leaderboard" ]
371+ full_formatted_leaderboard = _format_leaderboard (
372+ formatted_placement_leaderboard , self_placement_name = self_placement_name
373+ )
374+ user_placement = _get_user_placement (self_placement_name , formatted_placement_leaderboard )
375+ include_self = bool (user_placement and user_placement > AdventOfCode .leaderboard_displayed_members )
349376 cached_leaderboard ["placement_leaderboard" ] = _get_top_leaderboard (
350- _format_leaderboard (formatted_placement_leaderboard , self_placement_name = self_placement_name )
377+ full_formatted_leaderboard ,
378+ include_self = include_self
351379 )
352380 return cached_leaderboard
353381
0 commit comments