diff options
Diffstat (limited to 'bot/exts/pride')
| -rw-r--r-- | bot/exts/pride/drag_queen_name.py | 24 | ||||
| -rw-r--r-- | bot/exts/pride/pride_anthem.py | 28 | ||||
| -rw-r--r-- | bot/exts/pride/pride_avatar.py | 177 | ||||
| -rw-r--r-- | bot/exts/pride/pride_facts.py | 32 |
4 files changed, 32 insertions, 229 deletions
diff --git a/bot/exts/pride/drag_queen_name.py b/bot/exts/pride/drag_queen_name.py index fca9750f..15ca6576 100644 --- a/bot/exts/pride/drag_queen_name.py +++ b/bot/exts/pride/drag_queen_name.py @@ -5,28 +5,22 @@ from pathlib import Path from discord.ext import commands +from bot.bot import Bot + log = logging.getLogger(__name__) +NAMES = json.loads(Path("bot/resources/pride/drag_queen_names.json").read_text("utf8")) + class DragNames(commands.Cog): """Gives a random drag queen name!""" - def __init__(self, bot: commands.Bot): - self.bot = bot - self.names = self.load_names() - - @staticmethod - def load_names() -> list: - """Loads a list of drag queen names.""" - with open(Path("bot/resources/pride/drag_queen_names.json"), "r", encoding="utf8") as f: - return json.load(f) - - @commands.command(name="dragname", aliases=["dragqueenname", "queenme"]) + @commands.command(name="dragname", aliases=("dragqueenname", "queenme")) async def dragname(self, ctx: commands.Context) -> None: """Sends a message with a drag queen name.""" - await ctx.send(random.choice(self.names)) + await ctx.send(random.choice(NAMES)) -def setup(bot: commands.Bot) -> None: - """Cog loader for drag queen name generator.""" - bot.add_cog(DragNames(bot)) +def setup(bot: Bot) -> None: + """Load the Drag Names Cog.""" + bot.add_cog(DragNames()) diff --git a/bot/exts/pride/pride_anthem.py b/bot/exts/pride/pride_anthem.py index 33cb2a9d..4650595a 100644 --- a/bot/exts/pride/pride_anthem.py +++ b/bot/exts/pride/pride_anthem.py @@ -2,20 +2,21 @@ import json import logging import random from pathlib import Path +from typing import Optional from discord.ext import commands +from bot.bot import Bot + log = logging.getLogger(__name__) +VIDEOS = json.loads(Path("bot/resources/pride/anthems.json").read_text("utf8")) + class PrideAnthem(commands.Cog): """Embed a random youtube video for a gay anthem!""" - def __init__(self, bot: commands.Bot): - self.bot = bot - self.anthems = self.load_vids() - - def get_video(self, genre: str = None) -> dict: + def get_video(self, genre: Optional[str] = None) -> dict: """ Picks a random anthem from the list. @@ -25,20 +26,13 @@ class PrideAnthem(commands.Cog): if not genre: return random.choice(self.anthems) else: - songs = [song for song in self.anthems if genre.casefold() in song["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.") - @staticmethod - def load_vids() -> list: - """Loads a list of videos from the resources folder as dictionaries.""" - with open(Path("bot/resources/pride/anthems.json"), "r", encoding="utf8") as f: - anthems = json.load(f) - return anthems - - @commands.command(name="prideanthem", aliases=["anthem", "pridesong"]) + @commands.command(name="prideanthem", aliases=("anthem", "pridesong")) async def prideanthem(self, ctx: commands.Context, genre: str = None) -> None: """ Sends a message with a video of a random pride anthem. @@ -52,6 +46,6 @@ class PrideAnthem(commands.Cog): await ctx.send("I couldn't find a video, sorry!") -def setup(bot: commands.Bot) -> None: - """Cog loader for pride anthem.""" - bot.add_cog(PrideAnthem(bot)) +def setup(bot: Bot) -> None: + """Load the Pride Anthem Cog.""" + bot.add_cog(PrideAnthem()) diff --git a/bot/exts/pride/pride_avatar.py b/bot/exts/pride/pride_avatar.py deleted file mode 100644 index 2eade796..00000000 --- a/bot/exts/pride/pride_avatar.py +++ /dev/null @@ -1,177 +0,0 @@ -import logging -from io import BytesIO -from pathlib import Path -from typing import Tuple - -import aiohttp -import discord -from PIL import Image, ImageDraw, UnidentifiedImageError -from discord.ext.commands import Bot, Cog, Context, group - -from bot.constants import Colours - -log = logging.getLogger(__name__) - -OPTIONS = { - "agender": "agender", - "androgyne": "androgyne", - "androgynous": "androgyne", - "aromantic": "aromantic", - "aro": "aromantic", - "ace": "asexual", - "asexual": "asexual", - "bigender": "bigender", - "bisexual": "bisexual", - "bi": "bisexual", - "demiboy": "demiboy", - "demigirl": "demigirl", - "demi": "demisexual", - "demisexual": "demisexual", - "gay": "gay", - "lgbt": "gay", - "queer": "gay", - "homosexual": "gay", - "fluid": "genderfluid", - "genderfluid": "genderfluid", - "genderqueer": "genderqueer", - "intersex": "intersex", - "lesbian": "lesbian", - "non-binary": "nonbinary", - "enby": "nonbinary", - "nb": "nonbinary", - "nonbinary": "nonbinary", - "omnisexual": "omnisexual", - "omni": "omnisexual", - "pansexual": "pansexual", - "pan": "pansexual", - "pangender": "pangender", - "poly": "polysexual", - "polysexual": "polysexual", - "polyamory": "polyamory", - "polyamorous": "polyamory", - "transgender": "transgender", - "trans": "transgender", - "trigender": "trigender" -} - - -class PrideAvatar(Cog): - """Put an LGBT spin on your avatar!""" - - def __init__(self, bot: Bot): - self.bot = bot - - @staticmethod - def crop_avatar(avatar: Image) -> Image: - """This crops the avatar into a circle.""" - mask = Image.new("L", avatar.size, 0) - draw = ImageDraw.Draw(mask) - draw.ellipse((0, 0) + avatar.size, fill=255) - avatar.putalpha(mask) - return avatar - - @staticmethod - def crop_ring(ring: Image, px: int) -> Image: - """This crops the ring into a circle.""" - mask = Image.new("L", ring.size, 0) - draw = ImageDraw.Draw(mask) - draw.ellipse((0, 0) + ring.size, fill=255) - draw.ellipse((px, px, 1024-px, 1024-px), fill=0) - ring.putalpha(mask) - return ring - - @staticmethod - def process_options(option: str, pixels: int) -> Tuple[str, int, str]: - """Does some shared preprocessing for the prideavatar commands.""" - return option.lower(), max(0, min(512, pixels)), OPTIONS.get(option) - - async def process_image(self, ctx: Context, image_bytes: bytes, pixels: int, flag: str, option: str) -> None: - """Constructs the final image, embeds it, and sends it.""" - try: - avatar = Image.open(BytesIO(image_bytes)) - except UnidentifiedImageError: - return await ctx.send("Cannot identify image from provided URL") - avatar = avatar.convert("RGBA").resize((1024, 1024)) - - avatar = self.crop_avatar(avatar) - - ring = Image.open(Path(f"bot/resources/pride/flags/{flag}.png")).resize((1024, 1024)) - ring = ring.convert("RGBA") - ring = self.crop_ring(ring, pixels) - - avatar.alpha_composite(ring, (0, 0)) - bufferedio = BytesIO() - avatar.save(bufferedio, format="PNG") - bufferedio.seek(0) - - file = discord.File(bufferedio, filename="pride_avatar.png") # Creates file to be used in embed - embed = discord.Embed( - name="Your Lovely Pride Avatar", - description=f"Here is your lovely avatar, surrounded by\n a beautiful {option} flag. Enjoy :D" - ) - embed.set_image(url="attachment://pride_avatar.png") - embed.set_footer(text=f"Made by {ctx.author.display_name}", icon_url=ctx.author.avatar_url) - await ctx.send(file=file, embed=embed) - - @group(aliases=["avatarpride", "pridepfp", "prideprofile"], invoke_without_command=True) - async def prideavatar(self, ctx: Context, option: str = "lgbt", pixels: int = 64) -> None: - """ - This surrounds an avatar with a border of a specified LGBT flag. - - This defaults to the LGBT rainbow flag if none is given. - The amount of pixels can be given which determines the thickness of the flag border. - This has a maximum of 512px and defaults to a 64px border. - The full image is 1024x1024. - """ - option, pixels, flag = self.process_options(option, pixels) - if flag is None: - return await ctx.send("I don't have that flag!") - - async with ctx.typing(): - image_bytes = await ctx.author.avatar_url.read() - await self.process_image(ctx, image_bytes, pixels, flag, option) - - @prideavatar.command() - async def image(self, ctx: Context, url: str, option: str = "lgbt", pixels: int = 64) -> None: - """ - This surrounds the image specified by the URL with a border of a specified LGBT flag. - - This defaults to the LGBT rainbow flag if none is given. - The amount of pixels can be given which determines the thickness of the flag border. - This has a maximum of 512px and defaults to a 64px border. - The full image is 1024x1024. - """ - option, pixels, flag = self.process_options(option, pixels) - if flag is None: - return await ctx.send("I don't have that flag!") - - async with ctx.typing(): - async with aiohttp.ClientSession() as session: - try: - response = await session.get(url) - except aiohttp.client_exceptions.ClientConnectorError: - return await ctx.send("Cannot connect to provided URL!") - except aiohttp.client_exceptions.InvalidURL: - return await ctx.send("Invalid URL!") - if response.status != 200: - return await ctx.send("Bad response from provided URL!") - image_bytes = await response.read() - await self.process_image(ctx, image_bytes, pixels, flag, option) - - @prideavatar.command() - async def flags(self, ctx: Context) -> None: - """This lists the flags that can be used with the prideavatar command.""" - choices = sorted(set(OPTIONS.values())) - options = "• " + "\n• ".join(choices) - embed = discord.Embed( - title="I have the following flags:", - description=options, - colour=Colours.soft_red - ) - - await ctx.send(embed=embed) - - -def setup(bot: Bot) -> None: - """Cog load.""" - bot.add_cog(PrideAvatar(bot)) diff --git a/bot/exts/pride/pride_facts.py b/bot/exts/pride/pride_facts.py index 5bd5d0ce..631e2e8b 100644 --- a/bot/exts/pride/pride_facts.py +++ b/bot/exts/pride/pride_facts.py @@ -15,7 +15,7 @@ from bot.utils.decorators import seasonal_task log = logging.getLogger(__name__) -Sendable = Union[commands.Context, discord.TextChannel] +FACTS = json.loads(Path("bot/resources/pride/facts.json").read_text("utf8")) class PrideFacts(commands.Cog): @@ -23,16 +23,8 @@ class PrideFacts(commands.Cog): def __init__(self, bot: Bot): self.bot = bot - self.facts = self.load_facts() - self.daily_fact_task = self.bot.loop.create_task(self.send_pride_fact_daily()) - @staticmethod - def load_facts() -> dict: - """Loads a dictionary of years mapping to lists of facts.""" - with open(Path("bot/resources/pride/facts.json"), "r", encoding="utf8") as f: - return json.load(f) - @seasonal_task(Month.JUNE) async def send_pride_fact_daily(self) -> None: """Background task to post the daily pride fact every day.""" @@ -44,15 +36,15 @@ class PrideFacts(commands.Cog): async def send_random_fact(self, ctx: commands.Context) -> None: """Provides a fact from any previous day, or today.""" now = datetime.utcnow() - previous_years_facts = (self.facts[x] for x in self.facts.keys() if int(x) < now.year) - current_year_facts = self.facts.get(str(now.year), [])[:now.day] + 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] try: await ctx.send(embed=self.make_embed(random.choice(previous_facts))) except IndexError: await ctx.send("No facts available") - async def send_select_fact(self, target: Sendable, _date: Union[str, datetime]) -> None: + async def send_select_fact(self, target: discord.abc.Messageable, _date: Union[str, datetime]) -> None: """Provides the fact for the specified day, if the day is today, or is in the past.""" now = datetime.utcnow() if isinstance(_date, str): @@ -75,8 +67,8 @@ class PrideFacts(commands.Cog): else: await target.send("The fact for the selected day is not yet available.") - @commands.command(name="pridefact", aliases=["pridefacts"]) - async def pridefact(self, ctx: commands.Context) -> None: + @commands.command(name="pridefact", aliases=("pridefacts",)) + async def pridefact(self, ctx: commands.Context, option: str = None) -> None: """ Sends a message with a pride fact of the day. @@ -85,15 +77,15 @@ class PrideFacts(commands.Cog): If a date is given as an argument, and the date is in the past, the fact from that day will be provided. """ - message_body = ctx.message.content[len(ctx.invoked_with) + 2:] - if message_body == "": + if not option: await self.send_select_fact(ctx, datetime.utcnow()) - elif message_body.lower().startswith("rand"): + elif option.lower().startswith("rand"): await self.send_random_fact(ctx) else: - await self.send_select_fact(ctx, message_body) + await self.send_select_fact(ctx, option) - def make_embed(self, fact: str) -> discord.Embed: + @staticmethod + def make_embed(fact: str) -> discord.Embed: """Makes a nice embed for the fact to be sent.""" return discord.Embed( colour=Colours.pink, @@ -103,5 +95,5 @@ class PrideFacts(commands.Cog): def setup(bot: Bot) -> None: - """Cog loader for pride facts.""" + """Load the Pride Facts Cog.""" bot.add_cog(PrideFacts(bot)) |