diff options
Diffstat (limited to 'bot/exts/holidays')
18 files changed, 75 insertions, 88 deletions
diff --git a/bot/exts/holidays/easter/bunny_name_generator.py b/bot/exts/holidays/easter/bunny_name_generator.py index 50872ebc..3034da4a 100644 --- a/bot/exts/holidays/easter/bunny_name_generator.py +++ b/bot/exts/holidays/easter/bunny_name_generator.py @@ -3,7 +3,6 @@ import logging import random import re from pathlib import Path -from typing import Optional from discord.ext import commands @@ -18,7 +17,7 @@ class BunnyNameGenerator(commands.Cog): """Generate a random bunny name, or bunnify your Discord username!""" @staticmethod - def find_separators(displayname: str) -> Optional[list[str]]: + def find_separators(displayname: str) -> list[str] | None: """Check if Discord name contains spaces so we can bunnify an individual word in the name.""" new_name = re.split(r"[_.\s]", displayname) if displayname not in new_name: @@ -26,7 +25,7 @@ class BunnyNameGenerator(commands.Cog): return None @staticmethod - def find_vowels(displayname: str) -> Optional[str]: + def find_vowels(displayname: str) -> str | None: """ Finds vowels in the user's display name. @@ -46,6 +45,7 @@ class BunnyNameGenerator(commands.Cog): new_name = re.sub(exp, vowel_sub, displayname) if new_name != displayname: return new_name + return None @staticmethod def append_name(displayname: str) -> str: @@ -77,7 +77,7 @@ class BunnyNameGenerator(commands.Cog): unmatched_name = self.append_name(username) if spaces_in_name is not None: - replacements = ["Cotton", "Fluff", "Floof" "Bounce", "Snuffle", "Nibble", "Cuddle", "Velvetpaw", "Carrot"] + replacements = ["Cotton", "Fluff", "Floof", "Bounce", "Snuffle", "Nibble", "Cuddle", "Velvetpaw", "Carrot"] word_to_replace = random.choice(spaces_in_name) substitute = random.choice(replacements) bunnified_name = username.replace(word_to_replace, substitute) diff --git a/bot/exts/holidays/easter/earth_photos.py b/bot/exts/holidays/easter/earth_photos.py index 013122c8..66f1b07b 100644 --- a/bot/exts/holidays/easter/earth_photos.py +++ b/bot/exts/holidays/easter/earth_photos.py @@ -12,7 +12,7 @@ API_URL = "https://api.unsplash.com/photos/random" class EarthPhotos(commands.Cog): - """This cog contains the command for earth photos.""" + """The earth photos cog.""" def __init__(self, bot: Bot): self.bot = bot diff --git a/bot/exts/holidays/easter/easter_riddle.py b/bot/exts/holidays/easter/easter_riddle.py index c5d7b164..6c29dd17 100644 --- a/bot/exts/holidays/easter/easter_riddle.py +++ b/bot/exts/holidays/easter/easter_riddle.py @@ -18,7 +18,7 @@ TIMELIMIT = 10 class EasterRiddle(commands.Cog): - """This cog contains the command for the Easter quiz!""" + """The Easter quiz cog.""" def __init__(self, bot: Bot): self.bot = bot diff --git a/bot/exts/holidays/easter/egg_decorating.py b/bot/exts/holidays/easter/egg_decorating.py index a9334820..1327f4d0 100644 --- a/bot/exts/holidays/easter/egg_decorating.py +++ b/bot/exts/holidays/easter/egg_decorating.py @@ -4,7 +4,6 @@ import random from contextlib import suppress from io import BytesIO from pathlib import Path -from typing import Optional, Union import discord from PIL import Image @@ -33,7 +32,7 @@ class EggDecorating(commands.Cog): """Decorate some easter eggs!""" @staticmethod - def replace_invalid(colour: str) -> Optional[int]: + def replace_invalid(colour: str) -> int | None: """Attempts to match with HTML or XKCD colour names, returning the int value.""" with suppress(KeyError): return int(HTML_COLOURS[colour], 16) @@ -43,8 +42,8 @@ class EggDecorating(commands.Cog): @commands.command(aliases=("decorateegg",)) async def eggdecorate( - self, ctx: commands.Context, *colours: Union[discord.Colour, str] - ) -> Optional[Image.Image]: + self, ctx: commands.Context, *colours: discord.Colour | str + ) -> Image.Image | None: """ Picks a random egg design and decorates it using the given colours. @@ -53,7 +52,7 @@ class EggDecorating(commands.Cog): """ if len(colours) < 2: await ctx.send("You must include at least 2 colours!") - return + return None invalid = [] colours = list(colours) @@ -68,10 +67,10 @@ class EggDecorating(commands.Cog): if len(invalid) > 1: await ctx.send(f"Sorry, I don't know these colours: {' '.join(invalid)}") - return - elif len(invalid) == 1: + return None + if len(invalid) == 1: await ctx.send(f"Sorry, I don't know the colour {invalid[0]}!") - return + return None async with ctx.typing(): # Expand list to 8 colours diff --git a/bot/exts/holidays/easter/egghead_quiz.py b/bot/exts/holidays/easter/egghead_quiz.py index 2e4d1931..046f9fac 100644 --- a/bot/exts/holidays/easter/egghead_quiz.py +++ b/bot/exts/holidays/easter/egghead_quiz.py @@ -3,7 +3,6 @@ import logging import random from json import loads from pathlib import Path -from typing import Union import discord from discord.ext import commands @@ -29,7 +28,7 @@ TIMELIMIT = 30 class EggheadQuiz(commands.Cog): - """This cog contains the command for the Easter quiz!""" + """The Egghead quiz cog.""" def __init__(self): self.quiz_messages = {} @@ -117,9 +116,10 @@ class EggheadQuiz(commands.Cog): ) await ctx.send(content, embed=a_embed) + return None @staticmethod - async def already_reacted(new_reaction: discord.Reaction, user: Union[discord.Member, discord.User]) -> bool: + async def already_reacted(new_reaction: discord.Reaction, user: discord.Member | discord.User) -> bool: """Returns whether a given user has reacted more than once to a given message.""" message = new_reaction.message for reaction in message.reactions: @@ -131,16 +131,17 @@ class EggheadQuiz(commands.Cog): return False @commands.Cog.listener() - async def on_reaction_add(self, reaction: discord.Reaction, user: Union[discord.Member, discord.User]) -> None: + async def on_reaction_add(self, reaction: discord.Reaction, user: discord.Member | discord.User) -> None: """Listener to listen specifically for reactions of quiz messages.""" if user.bot: - return + return None if reaction.message.id not in self.quiz_messages: - return + return None if str(reaction.emoji) not in self.quiz_messages[reaction.message.id]: return await reaction.message.remove_reaction(reaction, user) if await self.already_reacted(reaction, user): return await reaction.message.remove_reaction(reaction, user) + return None async def setup(bot: Bot) -> None: diff --git a/bot/exts/holidays/halloween/candy_collection.py b/bot/exts/holidays/halloween/candy_collection.py index 683114f9..ca68888b 100644 --- a/bot/exts/holidays/halloween/candy_collection.py +++ b/bot/exts/holidays/halloween/candy_collection.py @@ -1,6 +1,5 @@ import logging import random -from typing import Union import discord from async_rediscache import RedisCache @@ -18,17 +17,17 @@ ADD_CANDY_EXISTING_REACTION_CHANCE = 10 # 10% ADD_SKULL_REACTION_CHANCE = 50 # 2% ADD_SKULL_EXISTING_REACTION_CHANCE = 20 # 5% -EMOJIS = dict( - CANDY="\N{CANDY}", - SKULL="\N{SKULL}", - MEDALS=( +EMOJIS = { + "CANDY": "\N{CANDY}", + "SKULL": "\N{SKULL}", + "MEDALS": ( "\N{FIRST PLACE MEDAL}", "\N{SECOND PLACE MEDAL}", "\N{THIRD PLACE MEDAL}", "\N{SPORTS MEDAL}", "\N{SPORTS MEDAL}", ), -) +} class CandyCollection(commands.Cog): @@ -69,7 +68,7 @@ class CandyCollection(commands.Cog): @in_month(Month.OCTOBER) @commands.Cog.listener() - async def on_reaction_add(self, reaction: discord.Reaction, user: Union[discord.User, discord.Member]) -> None: + async def on_reaction_add(self, reaction: discord.Reaction, user: discord.User | discord.Member) -> None: """Add/remove candies from a person if the reaction satisfies criteria.""" message = reaction.message # check to ensure the reactor is human @@ -140,7 +139,7 @@ class CandyCollection(commands.Cog): @staticmethod async def send_spook_msg( - author: discord.Member, channel: discord.TextChannel, candies: Union[str, int] + author: discord.Member, channel: discord.TextChannel, candies: str | int ) -> None: """Send a spooky message.""" e = discord.Embed(colour=author.colour) diff --git a/bot/exts/holidays/halloween/8ball.py b/bot/exts/holidays/halloween/eight_ball.py index 21b55a01..21b55a01 100644 --- a/bot/exts/holidays/halloween/8ball.py +++ b/bot/exts/holidays/halloween/eight_ball.py diff --git a/bot/exts/holidays/halloween/monstersurvey.py b/bot/exts/holidays/halloween/monstersurvey.py index 517f1bcb..d129f3cc 100644 --- a/bot/exts/holidays/halloween/monstersurvey.py +++ b/bot/exts/holidays/halloween/monstersurvey.py @@ -9,8 +9,8 @@ from discord.ext.commands import Bot, Cog, Context log = logging.getLogger(__name__) EMOJIS = { - "SUCCESS": u"\u2705", - "ERROR": u"\u274C" + "SUCCESS": "\u2705", + "ERROR": "\u274C" } diff --git a/bot/exts/holidays/halloween/spookynamerate.py b/bot/exts/holidays/halloween/spookynamerate.py index a76e5e12..78e8be8e 100644 --- a/bot/exts/holidays/halloween/spookynamerate.py +++ b/bot/exts/holidays/halloween/spookynamerate.py @@ -2,11 +2,10 @@ import asyncio import json import random from collections import defaultdict -from datetime import datetime, timedelta +from datetime import UTC, datetime, timedelta from logging import getLogger from os import getenv from pathlib import Path -from typing import Optional from async_rediscache import RedisCache from discord import Embed, Reaction, TextChannel, User @@ -146,7 +145,7 @@ class SpookyNameRate(Cog): ) return - elif data["name"] == name: + if data["name"] == name: await ctx.send("TOO LATE. Someone has already added this name.") return @@ -261,12 +260,8 @@ class SpookyNameRate(Cog): winners = [] for i, winner in enumerate(winner_messages): winners.append(winner) - if len(winner_messages) > i + 1: - if winner_messages[i + 1][1]["score"] != winner[1]["score"]: - break - elif len(winner_messages) == (i + 1) + 1: # The next element is the last element - if winner_messages[i + 1][1]["score"] != winner[1]["score"]: - break + if len(winner_messages) > i + 1 and winner_messages[i + 1][1]["score"] != winner[1]["score"]: + break # one iteration is complete await channel.send("Today's Spooky Name Rate Game ends now, and the winner(s) is(are)...") @@ -313,7 +308,7 @@ class SpookyNameRate(Cog): if SpookyNameRate.debug: return - now = datetime.utcnow() + now = datetime.now(tz=UTC) if now.hour < 12: twelve_pm = now.replace(hour=12, minute=0, second=0, microsecond=0) time_left = twelve_pm - now @@ -353,7 +348,7 @@ class SpookyNameRate(Cog): return embed - async def get_channel(self) -> Optional[TextChannel]: + async def get_channel(self) -> TextChannel | None: """Gets the sir-lancebot-channel after waiting until ready.""" channel = self.bot.get_channel( Channels.sir_lancebot_playground @@ -369,7 +364,7 @@ class SpookyNameRate(Cog): return True if not Client.month_override: - return datetime.utcnow().month == Month.OCTOBER + return datetime.now(tz=UTC).month == Month.OCTOBER return Client.month_override == Month.OCTOBER def cog_check(self, ctx: Context) -> bool: diff --git a/bot/exts/holidays/hanukkah/hanukkah_embed.py b/bot/exts/holidays/hanukkah/hanukkah_embed.py index 1ebc21e8..fd8edca1 100644 --- a/bot/exts/holidays/hanukkah/hanukkah_embed.py +++ b/bot/exts/holidays/hanukkah/hanukkah_embed.py @@ -1,5 +1,5 @@ -import datetime import logging +from datetime import UTC, date, datetime from discord import Embed from discord.ext import commands @@ -21,18 +21,18 @@ class HanukkahEmbed(commands.Cog): def __init__(self, bot: Bot): self.bot = bot - self.hanukkah_dates: list[datetime.date] = [] + self.hanukkah_dates: list[date] = [] - def _parse_time_to_datetime(self, date: list[str]) -> datetime.datetime: + def _parse_time_to_datetime(self, date: list[str]) -> datetime: """Format the times provided by the api to datetime forms.""" try: - return datetime.datetime.strptime(date, "%Y-%m-%dT%H:%M:%S%z") + return datetime.strptime(date, "%Y-%m-%dT%H:%M:%S%z") except ValueError: # there is a possibility of an event not having a time, just a day # to catch this, we try again without time information - return datetime.datetime.strptime(date, "%Y-%m-%d") + return datetime.strptime(date, "%Y-%m-%d").replace(tzinfo=UTC) - async def fetch_hanukkah_dates(self) -> list[datetime.date]: + async def fetch_hanukkah_dates(self) -> list[date]: """Gets the dates for hanukkah festival.""" # clear the datetime objects to prevent a memory link self.hanukkah_dates = [] @@ -52,11 +52,11 @@ class HanukkahEmbed(commands.Cog): hanukkah_dates = await self.fetch_hanukkah_dates() start_day = hanukkah_dates[0] end_day = hanukkah_dates[-1] - today = datetime.date.today() + today = datetime.now(tz=UTC).date() embed = Embed(title="Hanukkah", colour=Colours.blue) if start_day <= today <= end_day: if start_day == today: - now = datetime.datetime.utcnow() + now = datetime.now(tz=UTC) hours = now.hour + 4 # using only hours hanukkah_start_hour = 18 if hours < hanukkah_start_hour: @@ -66,7 +66,8 @@ class HanukkahEmbed(commands.Cog): ) await ctx.send(embed=embed) return - elif hours > hanukkah_start_hour: + + if hours > hanukkah_start_hour: embed.description = ( "It is the starting day of Hanukkah! " f"Its been {hours - hanukkah_start_hour} hours hanukkah started!" diff --git a/bot/exts/holidays/holidayreact.py b/bot/exts/holidays/holidayreact.py index ee20b792..c3686fab 100644 --- a/bot/exts/holidays/holidayreact.py +++ b/bot/exts/holidays/holidayreact.py @@ -72,9 +72,9 @@ HOLIDAYS_TO_REACT = [ Valentines, Easter, EarthDay, Pride, Halloween, Hanukkah, Christmas ] # Type (or order) doesn't matter here - set is for de-duplication -MONTHS_TO_REACT = set( +MONTHS_TO_REACT = { month for holiday in HOLIDAYS_TO_REACT for month in holiday.months -) +} class HolidayReact(Cog): diff --git a/bot/exts/holidays/pride/pride_anthem.py b/bot/exts/holidays/pride/pride_anthem.py index 6b78cba1..c719e388 100644 --- a/bot/exts/holidays/pride/pride_anthem.py +++ b/bot/exts/holidays/pride/pride_anthem.py @@ -2,7 +2,6 @@ import json import logging import random from pathlib import Path -from typing import Optional from discord.ext import commands @@ -16,7 +15,7 @@ VIDEOS = json.loads(Path("bot/resources/holidays/pride/anthems.json").read_text( class PrideAnthem(commands.Cog): """Embed a random youtube video for a gay anthem!""" - def get_video(self, genre: Optional[str] = None) -> dict: + def get_video(self, genre: str | None = None) -> dict: """ Picks a random anthem from the list. @@ -25,12 +24,12 @@ class PrideAnthem(commands.Cog): """ if not genre: return random.choice(VIDEOS) - else: - songs = [song for song in VIDEOS if genre.casefold() in song["genre"]] - try: - return random.choice(songs) - except IndexError: - log.info("No videos for that genre.") + + songs = [song for song in VIDEOS if genre.casefold() in song["genre"]] + try: + return random.choice(songs) + except IndexError: + log.info("No videos for that genre.") @commands.command(name="prideanthem", aliases=("anthem", "pridesong")) async def prideanthem(self, ctx: commands.Context, genre: str = None) -> None: diff --git a/bot/exts/holidays/pride/pride_facts.py b/bot/exts/holidays/pride/pride_facts.py index 36a9415e..f3ce50a9 100644 --- a/bot/exts/holidays/pride/pride_facts.py +++ b/bot/exts/holidays/pride/pride_facts.py @@ -1,9 +1,8 @@ import json import logging import random -from datetime import datetime +from datetime import UTC, datetime from pathlib import Path -from typing import Union import dateutil.parser import discord @@ -29,11 +28,11 @@ class PrideFacts(commands.Cog): async def send_pride_fact_daily(self) -> None: """Background task to post the daily pride fact every day.""" channel = self.bot.get_channel(Channels.sir_lancebot_playground) - await self.send_select_fact(channel, datetime.utcnow()) + await self.send_select_fact(channel, datetime.now(tz=UTC)) async def send_random_fact(self, ctx: commands.Context) -> None: """Provides a fact from any previous day, or today.""" - now = datetime.utcnow() + now = datetime.now(tz=UTC) previous_years_facts = (y for x, y in FACTS.items() if int(x) < now.year) current_year_facts = FACTS.get(str(now.year), [])[:now.day] previous_facts = current_year_facts + [x for y in previous_years_facts for x in y] @@ -42,9 +41,9 @@ class PrideFacts(commands.Cog): except IndexError: await ctx.send("No facts available") - async def send_select_fact(self, target: discord.abc.Messageable, _date: Union[str, datetime]) -> None: + async def send_select_fact(self, target: discord.abc.Messageable, _date: str | datetime) -> None: """Provides the fact for the specified day, if the day is today, or is in the past.""" - now = datetime.utcnow() + now = datetime.now(tz=UTC) if isinstance(_date, str): try: date = dateutil.parser.parse(_date, dayfirst=False, yearfirst=False, fuzzy=True) @@ -76,7 +75,7 @@ class PrideFacts(commands.Cog): will be provided. """ if not option: - await self.send_select_fact(ctx, datetime.utcnow()) + await self.send_select_fact(ctx, datetime.now(tz=UTC)) elif option.lower().startswith("rand"): await self.send_random_fact(ctx) else: diff --git a/bot/exts/holidays/pride/pride_leader.py b/bot/exts/holidays/pride/pride_leader.py index 120e9e16..b4a98892 100644 --- a/bot/exts/holidays/pride/pride_leader.py +++ b/bot/exts/holidays/pride/pride_leader.py @@ -2,7 +2,6 @@ import json import logging import random from pathlib import Path -from typing import Optional import discord from discord.ext import commands @@ -90,7 +89,7 @@ class PrideLeader(commands.Cog): return embed @commands.command(aliases=("pl", "prideleader")) - async def pride_leader(self, ctx: commands.Context, *, pride_leader_name: Optional[str]) -> None: + async def pride_leader(self, ctx: commands.Context, *, pride_leader_name: str | None) -> None: """ Information about a Pride Leader. diff --git a/bot/exts/holidays/valentines/be_my_valentine.py b/bot/exts/holidays/valentines/be_my_valentine.py index 3a2beef3..c2dd8bb6 100644 --- a/bot/exts/holidays/valentines/be_my_valentine.py +++ b/bot/exts/holidays/valentines/be_my_valentine.py @@ -126,15 +126,14 @@ class BeMyValentine(commands.Cog): if valentine_type is None: return self.random_valentine() - elif valentine_type.lower() in ["p", "poem"]: + if valentine_type.lower() in ["p", "poem"]: return self.valentine_poem(), "A poem dedicated to" - elif valentine_type.lower() in ["c", "compliment"]: + if valentine_type.lower() in ["c", "compliment"]: return self.valentine_compliment(), "A compliment for" - else: - # in this case, the user decides to type his own valentine. - return valentine_type, "A message for" + # in this case, the user decides to type his own valentine. + return valentine_type, "A message for" @staticmethod def random_emoji() -> tuple[str, str]: @@ -148,10 +147,7 @@ class BeMyValentine(commands.Cog): valentine_poem = random.choice(self.valentines["valentine_poems"]) valentine_compliment = random.choice(self.valentines["valentine_compliments"]) random_valentine = random.choice([valentine_compliment, valentine_poem]) - if random_valentine == valentine_poem: - title = "A poem dedicated to" - else: - title = "A compliment for " + title = "A poem dedicated to" if random_valentine == valentine_poem else "A compliment for " return random_valentine, title def valentine_poem(self) -> str: diff --git a/bot/exts/holidays/valentines/lovecalculator.py b/bot/exts/holidays/valentines/lovecalculator.py index eab3d083..9b363c5e 100644 --- a/bot/exts/holidays/valentines/lovecalculator.py +++ b/bot/exts/holidays/valentines/lovecalculator.py @@ -3,8 +3,8 @@ import hashlib import json import logging import random +from collections.abc import Coroutine from pathlib import Path -from typing import Coroutine, Optional import discord from discord import Member @@ -27,7 +27,7 @@ class LoveCalculator(Cog): @in_month(Month.FEBRUARY) @commands.command(aliases=("love_calculator", "love_calc")) @commands.cooldown(rate=1, per=5, type=commands.BucketType.user) - async def love(self, ctx: commands.Context, who: Member, whom: Optional[Member] = None) -> None: + async def love(self, ctx: commands.Context, who: Member, whom: Member | None = None) -> None: """ Tells you how much the two love each other. diff --git a/bot/exts/holidays/valentines/myvalenstate.py b/bot/exts/holidays/valentines/myvalenstate.py index 8d8772d4..fcef24bc 100644 --- a/bot/exts/holidays/valentines/myvalenstate.py +++ b/bot/exts/holidays/valentines/myvalenstate.py @@ -47,7 +47,7 @@ class MyValenstate(commands.Cog): else: author = name.lower().replace(" ", "") - for state in STATES.keys(): + for state in STATES: lower_state = state.lower().replace(" ", "") eq_chars[state] = self.levenshtein(author, lower_state) @@ -64,8 +64,7 @@ class MyValenstate(commands.Cog): embed_text = f"You have another match, this being {matches[0]}." else: embed_title = "You have a true match!" - embed_text = "This state is your true Valenstate! There are no states that would suit" \ - " you better" + embed_text = "This state is your true Valenstate! There are no states that would suit you better" embed = discord.Embed( title=f"Your Valenstate is {valenstate} \u2764", diff --git a/bot/exts/holidays/valentines/valentine_zodiac.py b/bot/exts/holidays/valentines/valentine_zodiac.py index 0a28a5c5..f0c8978d 100644 --- a/bot/exts/holidays/valentines/valentine_zodiac.py +++ b/bot/exts/holidays/valentines/valentine_zodiac.py @@ -2,9 +2,8 @@ import calendar import json import logging import random -from datetime import datetime +from datetime import UTC, datetime from pathlib import Path -from typing import Union import discord from discord.ext import commands @@ -78,6 +77,7 @@ class ValentineZodiac(commands.Cog): if zodiac_data["start_at"].date() <= query_date.date() <= zodiac_data["end_at"].date(): log.trace("Zodiac name sent.") return zodiac_name + return None @commands.group(name="zodiac", invoke_without_command=True) async def zodiac(self, ctx: commands.Context, zodiac_sign: str) -> None: @@ -87,7 +87,7 @@ class ValentineZodiac(commands.Cog): log.trace("Embed successfully sent.") @zodiac.command(name="date") - async def date_and_month(self, ctx: commands.Context, date: int, month: Union[int, str]) -> None: + async def date_and_month(self, ctx: commands.Context, date: int, month: int | str) -> None: """Provides information about zodiac sign by taking month and date as input.""" if isinstance(month, str): month = month.capitalize() @@ -103,7 +103,7 @@ class ValentineZodiac(commands.Cog): final_embed = self.zodiac_build_embed(zodiac) else: try: - zodiac_sign_based_on_date = self.zodiac_date_verifier(datetime(2020, month, date)) + zodiac_sign_based_on_date = self.zodiac_date_verifier(datetime(2020, month, date, tzinfo=UTC)) log.trace("zodiac sign based on month and date received.") except ValueError as e: final_embed = discord.Embed() |