diff options
| author | 2021-11-18 21:02:15 +0100 | |
|---|---|---|
| committer | 2021-11-18 21:45:25 +0100 | |
| commit | c56c5a9ab01a45a50877c228843fa27625f03512 (patch) | |
| tree | 4fac94e212c740a10c293ae49b3ed30942bcc684 /bot/exts/events | |
| parent | Merge pull request #842 from brad90four/color-677 (diff) | |
Introduce command changes in the AoC Cog
- The AoC day and star browser has been separated from the leaderboard command, from now on it's a separate command
- The leaderboard command has a new `self_placement_name` option, that shows the personal stats for the specified profile name.
Diffstat (limited to 'bot/exts/events')
| -rw-r--r-- | bot/exts/events/advent_of_code/_cog.py | 72 | ||||
| -rw-r--r-- | bot/exts/events/advent_of_code/_helpers.py | 25 | 
2 files changed, 66 insertions, 31 deletions
| diff --git a/bot/exts/events/advent_of_code/_cog.py b/bot/exts/events/advent_of_code/_cog.py index 2c1f4541..7f35c306 100644 --- a/bot/exts/events/advent_of_code/_cog.py +++ b/bot/exts/events/advent_of_code/_cog.py @@ -180,24 +180,18 @@ class AdventOfCode(commands.Cog):      @in_month(Month.DECEMBER)      @adventofcode_group.command( -        name="leaderboard", -        aliases=("board", "lb"), -        brief="Get a snapshot of the PyDis private AoC leaderboard", +        name="dayandstar", +        aliases=("daynstar", "daystar"), +        brief="Get a view that lets you filter the leaderboard by day and star",      )      @whitelist_override(channels=AOC_WHITELIST_RESTRICTED) -    async def aoc_leaderboard( +    async def aoc_day_and_star_leaderboard(              self,              ctx: commands.Context, -            day_and_star: Optional[bool] = False, -            maximum_scorers: Optional[int] = 10 +            maximum_scorers_day_and_star: Optional[int] = 10      ) -> None: -        """ -        Get the current top scorers of the Python Discord Leaderboard. - -        Additionally, you can provide an argument `day_and_star` (Boolean) to have the bot send a View -        that will let you filter by day and star. -        """ -        if maximum_scorers > AocConfig.max_day_and_star_results or maximum_scorers <= 0: +        """Have the bot send a View that will let you filter the leaderboard by day and star.""" +        if maximum_scorers_day_and_star > AocConfig.max_day_and_star_results or maximum_scorers_day_and_star <= 0:              raise commands.BadArgument(                  f"The maximum number of results you can query is {AocConfig.max_day_and_star_results}"              ) @@ -207,25 +201,12 @@ class AdventOfCode(commands.Cog):              except _helpers.FetchingLeaderboardFailedError:                  await ctx.send(":x: Unable to fetch leaderboard!")                  return -        if not day_and_star: - -            number_of_participants = leaderboard["number_of_participants"] - -            top_count = min(AocConfig.leaderboard_displayed_members, number_of_participants) -            header = f"Here's our current top {top_count}! {Emojis.christmas_tree * 3}" - -            table = f"```\n{leaderboard['top_leaderboard']}\n```" -            info_embed = _helpers.get_summary_embed(leaderboard) - -            await ctx.send(content=f"{header}\n\n{table}", embed=info_embed) -            return -          # This is a dictionary that contains solvers in respect of day, and star.          # e.g. 1-1 means the solvers of the first star of the first day and their completion time          per_day_and_star = json.loads(leaderboard['leaderboard_per_day_and_star'])          view = AoCDropdownView(              day_and_star_data=per_day_and_star, -            maximum_scorers=maximum_scorers, +            maximum_scorers=maximum_scorers_day_and_star,              original_author=ctx.author          )          message = await ctx.send( @@ -237,6 +218,43 @@ class AdventOfCode(commands.Cog):      @in_month(Month.DECEMBER)      @adventofcode_group.command( +        name="leaderboard", +        aliases=("board", "lb"), +        brief="Get a snapshot of the PyDis private AoC leaderboard", +    ) +    @whitelist_override(channels=AOC_WHITELIST_RESTRICTED) +    async def aoc_leaderboard( +            self, +            ctx: commands.Context, +            self_placement_name: Optional[str] = None, +    ) -> None: +        """ +        Get the current top scorers of the Python Discord Leaderboard. + +        Additionaly you can specify a `self_placement_name` +        that will append the specified profile's personal stats to the top of the leaderboard +        """ +        async with ctx.typing(): +            try: +                leaderboard = await _helpers.fetch_leaderboard(self_placement_name=self_placement_name) +            except _helpers.FetchingLeaderboardFailedError: +                await ctx.send(":x: Unable to fetch leaderboard!") +                return + +        number_of_participants = leaderboard["number_of_participants"] + +        top_count = min(AocConfig.leaderboard_displayed_members, number_of_participants) +        self_placement_header = "(and your personal stats compared to the top 10)" if self_placement_name else "" +        header = f"Here's our current top {top_count}{self_placement_header}! {Emojis.christmas_tree * 3}" + +        table = f"```\n{leaderboard['top_leaderboard']}\n```" +        info_embed = _helpers.get_summary_embed(leaderboard) + +        await ctx.send(content=f"{header}\n\n{table}", embed=info_embed) +        return + +    @in_month(Month.DECEMBER) +    @adventofcode_group.command(          name="global",          aliases=("globalboard", "gb"),          brief="Get a link to the global leaderboard", diff --git a/bot/exts/events/advent_of_code/_helpers.py b/bot/exts/events/advent_of_code/_helpers.py index af64bc81..58fc3054 100644 --- a/bot/exts/events/advent_of_code/_helpers.py +++ b/bot/exts/events/advent_of_code/_helpers.py @@ -10,6 +10,7 @@ from typing import Any, Optional  import aiohttp  import arrow  import discord +from discord.ext import commands  from bot.bot import Bot  from bot.constants import AdventOfCode, Channels, Colours @@ -160,10 +161,23 @@ def _parse_raw_leaderboard_data(raw_leaderboard_data: dict) -> dict:      return {"daily_stats": daily_stats, "leaderboard": sorted_leaderboard, 'per_day_and_star': per_day_star_stats} -def _format_leaderboard(leaderboard: dict[str, dict]) -> str: +def _format_leaderboard(leaderboard: dict[str, dict], self_placement_name: str = None) -> str:      """Format the leaderboard using the AOC_TABLE_TEMPLATE."""      leaderboard_lines = [HEADER] +    self_placement_exists = False      for rank, data in enumerate(leaderboard.values(), start=1): +        if self_placement_name and data["name"].lower() == self_placement_name.lower(): +            leaderboard_lines.insert( +                1, +                AOC_TABLE_TEMPLATE.format( +                    rank=rank, +                    name=f"(You) {data['name']}", +                    score=str(data["score"]), +                    stars=f"({data['star_1']}, {data['star_2']})" +                ) +            ) +            self_placement_exists = True +            continue          leaderboard_lines.append(              AOC_TABLE_TEMPLATE.format(                  rank=rank, @@ -172,7 +186,10 @@ def _format_leaderboard(leaderboard: dict[str, dict]) -> str:                  stars=f"({data['star_1']}, {data['star_2']})"              )          ) - +    if self_placement_name and not self_placement_exists: +        raise commands.BadArgument( +            "Sorry, your profile does not exist in this leaderboard." +        )      return "\n".join(leaderboard_lines) @@ -260,7 +277,7 @@ def _get_top_leaderboard(full_leaderboard: str) -> str:  @_caches.leaderboard_cache.atomic_transaction -async def fetch_leaderboard(invalidate_cache: bool = False) -> dict: +async def fetch_leaderboard(invalidate_cache: bool = False, self_placement_name: str = None) -> dict:      """      Get the current Python Discord combined leaderboard. @@ -284,7 +301,7 @@ async def fetch_leaderboard(invalidate_cache: bool = False) -> dict:          leaderboard = parsed_leaderboard_data["leaderboard"]          number_of_participants = len(leaderboard) -        formatted_leaderboard = _format_leaderboard(leaderboard) +        formatted_leaderboard = _format_leaderboard(leaderboard, self_placement_name)          full_leaderboard_url = await _upload_leaderboard(formatted_leaderboard)          leaderboard_fetched_at = datetime.datetime.utcnow().isoformat() | 
