diff options
Diffstat (limited to 'bot/exts/christmas')
| -rw-r--r-- | bot/exts/christmas/advent_of_code/_cog.py | 32 | ||||
| -rw-r--r-- | bot/exts/christmas/advent_of_code/_helpers.py | 30 | ||||
| -rw-r--r-- | bot/exts/christmas/hanukkah_embed.py | 85 | 
3 files changed, 77 insertions, 70 deletions
| diff --git a/bot/exts/christmas/advent_of_code/_cog.py b/bot/exts/christmas/advent_of_code/_cog.py index 8376987d..3d61753b 100644 --- a/bot/exts/christmas/advent_of_code/_cog.py +++ b/bot/exts/christmas/advent_of_code/_cog.py @@ -3,6 +3,7 @@ import logging  from datetime import datetime, timedelta  from pathlib import Path +import arrow  import discord  from discord.ext import commands @@ -72,11 +73,15 @@ class AdventOfCode(commands.Cog):          if role not in ctx.author.roles:              await ctx.author.add_roles(role) -            await ctx.send("Okay! You have been __subscribed__ to notifications about new Advent of Code tasks. " -                           f"You can run `{unsubscribe_command}` to disable them again for you.") +            await ctx.send( +                "Okay! You have been __subscribed__ to notifications about new Advent of Code tasks. " +                f"You can run `{unsubscribe_command}` to disable them again for you." +            )          else: -            await ctx.send("Hey, you already are receiving notifications about new Advent of Code tasks. " -                           f"If you don't want them any more, run `{unsubscribe_command}` instead.") +            await ctx.send( +                "Hey, you already are receiving notifications about new Advent of Code tasks. " +                f"If you don't want them any more, run `{unsubscribe_command}` instead." +            )      @in_month(Month.DECEMBER)      @adventofcode_group.command(name="unsubscribe", aliases=("unsub",), brief="Notifications for new days") @@ -96,11 +101,11 @@ class AdventOfCode(commands.Cog):      async def aoc_countdown(self, ctx: commands.Context) -> None:          """Return time left until next day."""          if not _helpers.is_in_advent(): -            datetime_now = datetime.now(_helpers.EST) +            datetime_now = arrow.now(_helpers.EST)              # Calculate the delta to this & next year's December 1st to see which one is closest and not in the past -            this_year = datetime(datetime_now.year, 12, 1, tzinfo=_helpers.EST) -            next_year = datetime(datetime_now.year + 1, 12, 1, tzinfo=_helpers.EST) +            this_year = arrow.get(datetime(datetime_now.year, 12, 1), _helpers.EST) +            next_year = arrow.get(datetime(datetime_now.year + 1, 12, 1), _helpers.EST)              deltas = (dec_first - datetime_now for dec_first in (this_year, next_year))              delta = min(delta for delta in deltas if delta >= timedelta())  # timedelta() gives 0 duration delta @@ -110,8 +115,10 @@ class AdventOfCode(commands.Cog):              else:                  delta_str = f"{delta.days} days" -            await ctx.send(f"The Advent of Code event is not currently running. " -                           f"The next event will start in {delta_str}.") +            await ctx.send( +                "The Advent of Code event is not currently running. " +                f"The next event will start in {delta_str}." +            )              return          tomorrow, time_left = _helpers.time_left_to_est_midnight() @@ -124,7 +131,7 @@ class AdventOfCode(commands.Cog):      @whitelist_override(channels=AOC_WHITELIST)      async def about_aoc(self, ctx: commands.Context) -> None:          """Respond with an explanation of all things Advent of Code.""" -        await ctx.send("", embed=self.cached_about_aoc) +        await ctx.send(embed=self.cached_about_aoc)      @adventofcode_group.command(name="join", aliases=("j",), brief="Learn how to join the leaderboard (via DM)")      @whitelist_override(channels=AOC_WHITELIST) @@ -135,7 +142,7 @@ class AdventOfCode(commands.Cog):              await ctx.send(f"The Python Discord leaderboard for {current_year} is not yet available!")              return -        author = ctx.message.author +        author = ctx.author          log.info(f"{author.name} ({author.id}) has requested a PyDis AoC leaderboard code")          if AocConfig.staff_leaderboard_id and any(r.id == Roles.helpers for r in author.roles): @@ -273,8 +280,7 @@ class AdventOfCode(commands.Cog):      def _build_about_embed(self) -> discord.Embed:          """Build and return the informational "About AoC" embed from the resources file.""" -        with self.about_aoc_filepath.open("r", encoding="utf8") as f: -            embed_fields = json.load(f) +        embed_fields = json.loads(self.about_aoc_filepath.read_text("utf8"))          about_embed = discord.Embed(              title=self._base_url, diff --git a/bot/exts/christmas/advent_of_code/_helpers.py b/bot/exts/christmas/advent_of_code/_helpers.py index a16a4871..96de90c4 100644 --- a/bot/exts/christmas/advent_of_code/_helpers.py +++ b/bot/exts/christmas/advent_of_code/_helpers.py @@ -9,8 +9,8 @@ import typing  from typing import Tuple  import aiohttp +import arrow  import discord -import pytz  from bot.bot import Bot  from bot.constants import AdventOfCode, Channels, Colours @@ -48,7 +48,7 @@ AOC_EMBED_THUMBNAIL = (  )  # Create an easy constant for the EST timezone -EST = pytz.timezone("EST") +EST = "America/New_York"  # Step size for the challenge countdown status  COUNTDOWN_STEP = 60 * 5 @@ -108,7 +108,7 @@ def _parse_raw_leaderboard_data(raw_leaderboard_data: dict) -> dict:      # star view. We need that per star view to compute rank scores per star.      for member in raw_leaderboard_data.values():          name = member["name"] if member["name"] else f"Anonymous #{member['id']}" -        member_id = member['id'] +        member_id = member["id"]          leaderboard[member_id] = {"name": name, "score": 0, "star_1": 0, "star_2": 0}          # Iterate over all days for this participant @@ -119,7 +119,7 @@ def _parse_raw_leaderboard_data(raw_leaderboard_data: dict) -> dict:                  leaderboard[member_id][f"star_{star}"] += 1                  # Record completion datetime for this participant for this day/star -                completion_time = datetime.datetime.fromtimestamp(int(data['get_star_ts'])) +                completion_time = datetime.datetime.fromtimestamp(int(data["get_star_ts"]))                  star_results[(day, star)].append(                      StarResult(member_id=member_id, completion_time=completion_time)                  ) @@ -133,7 +133,7 @@ def _parse_raw_leaderboard_data(raw_leaderboard_data: dict) -> dict:          if day in AdventOfCode.ignored_days:              continue -        sorted_result = sorted(results, key=operator.attrgetter('completion_time')) +        sorted_result = sorted(results, key=operator.attrgetter("completion_time"))          for rank, star_result in enumerate(sorted_result):              leaderboard[star_result.member_id]["score"] += max_score - rank @@ -307,7 +307,7 @@ async def fetch_leaderboard(invalidate_cache: bool = False) -> dict:  def get_summary_embed(leaderboard: dict) -> discord.Embed:      """Get an embed with the current summary stats of the leaderboard.""" -    leaderboard_url = leaderboard['full_leaderboard_url'] +    leaderboard_url = leaderboard["full_leaderboard_url"]      refresh_minutes = AdventOfCode.leaderboard_cache_expiry_seconds // 60      aoc_embed = discord.Embed( @@ -395,13 +395,13 @@ def is_in_advent() -> bool:      something for the next Advent of Code challenge should run. As the puzzle      published on the 25th is the last puzzle, this check excludes that date.      """ -    return datetime.datetime.now(EST).day in range(1, 25) and datetime.datetime.now(EST).month == 12 +    return arrow.now(EST).day in range(1, 25) and arrow.now(EST).month == 12  def time_left_to_est_midnight() -> Tuple[datetime.datetime, datetime.timedelta]:      """Calculate the amount of time left until midnight EST/UTC-5."""      # Change all time properties back to 00:00 -    todays_midnight = datetime.datetime.now(EST).replace( +    todays_midnight = arrow.now(EST).replace(          microsecond=0,          second=0,          minute=0, @@ -412,7 +412,7 @@ def time_left_to_est_midnight() -> Tuple[datetime.datetime, datetime.timedelta]:      tomorrow = todays_midnight + datetime.timedelta(days=1)      # Calculate the timedelta between the current time and midnight -    return tomorrow, tomorrow - datetime.datetime.now(EST) +    return tomorrow, tomorrow - arrow.now(EST)  async def wait_for_advent_of_code(*, hours_before: int = 1) -> None: @@ -430,9 +430,9 @@ async def wait_for_advent_of_code(*, hours_before: int = 1) -> None:      if we're already past the Advent of Code edition the bot is currently      configured for.      """ -    start = datetime.datetime(AdventOfCode.year, 12, 1, 0, 0, 0, tzinfo=EST) +    start = arrow.get(datetime.datetime(AdventOfCode.year, 12, 1), EST)      target = start - datetime.timedelta(hours=hours_before) -    now = datetime.datetime.now(EST) +    now = arrow.now(EST)      # If we've already reached or passed to target, we      # simply return immediately. @@ -474,10 +474,10 @@ async def countdown_status(bot: Bot) -> None:      # sleeping for the entire year, it will only wait in the currently      # configured year. This means that the task will only start hibernating once      # we start preparing the next event by changing environment variables. -    last_challenge = datetime.datetime(AdventOfCode.year, 12, 25, 0, 0, 0, tzinfo=EST) +    last_challenge = arrow.get(datetime.datetime(AdventOfCode.year, 12, 25), EST)      end = last_challenge + datetime.timedelta(hours=1) -    while datetime.datetime.now(EST) < end: +    while arrow.now(EST) < end:          _, time_left = time_left_to_est_midnight()          aligned_seconds = int(math.ceil(time_left.seconds / COUNTDOWN_STEP)) * COUNTDOWN_STEP @@ -534,8 +534,8 @@ async def new_puzzle_notification(bot: Bot) -> None:      # The last event day is 25 December, so we only have to schedule      # a reminder if the current day is before 25 December. -    end = datetime.datetime(AdventOfCode.year, 12, 25, tzinfo=EST) -    while datetime.datetime.now(EST) < end: +    end = arrow.get(datetime.datetime(AdventOfCode.year, 12, 25), EST) +    while arrow.now(EST) < end:          log.trace("Started puzzle notification loop.")          tomorrow, time_left = time_left_to_est_midnight() diff --git a/bot/exts/christmas/hanukkah_embed.py b/bot/exts/christmas/hanukkah_embed.py index 4f470a34..119f2446 100644 --- a/bot/exts/christmas/hanukkah_embed.py +++ b/bot/exts/christmas/hanukkah_embed.py @@ -5,19 +5,23 @@ from typing import List  from discord import Embed  from discord.ext import commands +from bot.bot import Bot  from bot.constants import Colours, Month  from bot.utils.decorators import in_month  log = logging.getLogger(__name__) +HEBCAL_URL = ( +    "https://www.hebcal.com/hebcal/?v=1&cfg=json&maj=on&min=on&mod=on&nx=on&" +    "year=now&month=x&ss=on&mf=on&c=on&geo=geoname&geonameid=3448439&m=50&s=on" +) +  class HanukkahEmbed(commands.Cog):      """A cog that returns information about Hanukkah festival.""" -    def __init__(self, bot: commands.Bot): +    def __init__(self, bot: Bot):          self.bot = bot -        self.url = ("https://www.hebcal.com/hebcal/?v=1&cfg=json&maj=on&min=on&mod=on&nx=on&" -                    "year=now&month=x&ss=on&mf=on&c=on&geo=geoname&geonameid=3448439&m=50&s=on")          self.hanukkah_days = []          self.hanukkah_months = []          self.hanukkah_years = [] @@ -25,17 +29,17 @@ class HanukkahEmbed(commands.Cog):      async def get_hanukkah_dates(self) -> List[str]:          """Gets the dates for hanukkah festival."""          hanukkah_dates = [] -        async with self.bot.http_session.get(self.url) as response: +        async with self.bot.http_session.get(HEBCAL_URL) as response:              json_data = await response.json() -        festivals = json_data['items'] +        festivals = json_data["items"]          for festival in festivals: -            if festival['title'].startswith('Chanukah'): -                date = festival['date'] +            if festival["title"].startswith("Chanukah"): +                date = festival["date"]                  hanukkah_dates.append(date)          return hanukkah_dates      @in_month(Month.DECEMBER) -    @commands.command(name='hanukkah', aliases=['chanukah']) +    @commands.command(name="hanukkah", aliases=("chanukah",))      async def hanukkah_festival(self, ctx: commands.Context) -> None:          """Tells you about the Hanukkah Festivaltime of festival, festival day, etc)."""          hanukkah_dates = await self.get_hanukkah_dates() @@ -54,49 +58,46 @@ class HanukkahEmbed(commands.Cog):          day = str(today.day)          month = str(today.month)          year = str(today.year) -        embed = Embed() -        embed.title = 'Hanukkah' -        embed.colour = Colours.blue +        embed = Embed(title="Hanukkah", colour=Colours.blue)          if day in self.hanukkah_days and month in self.hanukkah_months and year in self.hanukkah_years:              if int(day) == hanukkah_start_day:                  now = datetime.datetime.utcnow() -                now = str(now) -                hours = int(now[11:13]) + 4  # using only hours +                hours = now.hour + 4  # using only hours                  hanukkah_start_hour = 18                  if hours < hanukkah_start_hour: -                    embed.description = (f"Hanukkah hasnt started yet, " -                                         f"it will start in about {hanukkah_start_hour-hours} hour/s.") -                    return await ctx.send(embed=embed) +                    embed.description = ( +                        "Hanukkah hasnt started yet, " +                        f"it will start in about {hanukkah_start_hour - hours} hour/s." +                    ) +                    await ctx.send(embed=embed) +                    return                  elif hours > hanukkah_start_hour: -                    embed.description = (f'It is the starting day of Hanukkah ! ' -                                         f'Its been {hours-hanukkah_start_hour} hours hanukkah started !') -                    return await ctx.send(embed=embed) +                    embed.description = ( +                        "It is the starting day of Hanukkah! " +                        f"Its been {hours - hanukkah_start_hour} hours hanukkah started!" +                    ) +                    await ctx.send(embed=embed) +                    return              festival_day = self.hanukkah_days.index(day) -            number_suffixes = ['st', 'nd', 'rd', 'th'] -            suffix = '' -            if int(festival_day) == 1: -                suffix = number_suffixes[0] -            if int(festival_day) == 2: -                suffix = number_suffixes[1] -            if int(festival_day) == 3: -                suffix = number_suffixes[2] -            if int(festival_day) > 3: -                suffix = number_suffixes[3] -            message = '' -            for _ in range(1, festival_day + 1): -                message += ':menorah:' -            embed.description = f'It is the {festival_day}{suffix} day of Hanukkah ! \n {message}' +            number_suffixes = ["st", "nd", "rd", "th"] +            suffix = number_suffixes[festival_day - 1 if festival_day <= 3 else 3] +            message = ":menorah:" * festival_day +            embed.description = f"It is the {festival_day}{suffix} day of Hanukkah!\n{message}"              await ctx.send(embed=embed)          else:              if today < hanukkah_start: -                festival_starting_month = hanukkah_start.strftime('%B') -                embed.description = (f"Hanukkah has not started yet. " -                                     f"Hanukkah will start at sundown on {hanukkah_start_day}th " -                                     f"of {festival_starting_month}.") +                festival_starting_month = hanukkah_start.strftime("%B") +                embed.description = ( +                    f"Hanukkah has not started yet. " +                    f"Hanukkah will start at sundown on {hanukkah_start_day}th " +                    f"of {festival_starting_month}." +                )              else: -                festival_end_month = hanukkah_end.strftime('%B') -                embed.description = (f"Looks like you missed Hanukkah !" -                                     f"Hanukkah ended on {hanukkah_end_day}th of {festival_end_month}.") +                festival_end_month = hanukkah_end.strftime("%B") +                embed.description = ( +                    f"Looks like you missed Hanukkah!" +                    f"Hanukkah ended on {hanukkah_end_day}th of {festival_end_month}." +                )              await ctx.send(embed=embed) @@ -108,6 +109,6 @@ class HanukkahEmbed(commands.Cog):              self.hanukkah_years.append(date[0:4]) -def setup(bot: commands.Bot) -> None: -    """Cog load.""" +def setup(bot: Bot) -> None: +    """Load the Hanukkah Embed Cog."""      bot.add_cog(HanukkahEmbed(bot)) | 
