From 9d3ae7f11c86e918c7c5dcb25c3b12b68a0ab09a Mon Sep 17 00:00:00 2001 From: AbooMinister25 Date: Wed, 13 Jul 2022 19:57:11 -0400 Subject: Fix issue with .uwu failing to uwuify embeds in replies --- bot/exts/fun/uwu.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'bot') diff --git a/bot/exts/fun/uwu.py b/bot/exts/fun/uwu.py index e70d1c0f..d294dc6a 100644 --- a/bot/exts/fun/uwu.py +++ b/bot/exts/fun/uwu.py @@ -118,27 +118,39 @@ class Uwu(Cog): # If `text` isn't provided then we try to get message content of a replied message text = text or getattr(ctx.message.reference, "resolved", None) if isinstance(text, discord.Message): + embeds = text.embeds text = text.content + else: + embeds = None if text is None: # If we weren't able to get the content of a replied message raise commands.UserInputError("Your message must have content or you must reply to a message.") - + await clean_content(fix_channel_mentions=True).convert(ctx, text) - - if fun_cog := ctx.bot.get_cog("Fun"): + + fun_cog = ctx.bot.get_cog("Fun") + if fun_cog: text, embed = await fun_cog._get_text_and_embed(ctx, text) - - # Grabs the text from the embed for uwuification. + + # Grabs the text from the embed for uwuification if embed is not None: embed = fun_cog._convert_embed(self._uwuify, embed) + else: + # Only use the first embed since only a single one can be sent + embed = fun_cog._convert_embed(self._uwuify, embeds[0]) if embeds else None else: embed = None + converted_text = self._uwuify(text) converted_text = helpers.suppress_links(converted_text) # Adds the text harvested from an embed to be put into another quote block. - converted_text = f">>> {converted_text.lstrip('> ')}" + if text: + converted_text = f">>> {converted_text.lstrip('> ')}" + else: + converted_text = None + await ctx.send(content=converted_text, embed=embed) -- cgit v1.2.3 From 51aa4bb5579bf871c4cbd6788dd31474f3291810 Mon Sep 17 00:00:00 2001 From: AbooMinister25 Date: Sun, 17 Jul 2022 22:32:30 -0400 Subject: Ran lints :p --- bot/exts/fun/uwu.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'bot') diff --git a/bot/exts/fun/uwu.py b/bot/exts/fun/uwu.py index d294dc6a..9e228065 100644 --- a/bot/exts/fun/uwu.py +++ b/bot/exts/fun/uwu.py @@ -126,19 +126,19 @@ class Uwu(Cog): if text is None: # If we weren't able to get the content of a replied message raise commands.UserInputError("Your message must have content or you must reply to a message.") - + await clean_content(fix_channel_mentions=True).convert(ctx, text) - + fun_cog = ctx.bot.get_cog("Fun") if fun_cog: text, embed = await fun_cog._get_text_and_embed(ctx, text) - + # Grabs the text from the embed for uwuification if embed is not None: embed = fun_cog._convert_embed(self._uwuify, embed) else: # Only use the first embed since only a single one can be sent - embed = fun_cog._convert_embed(self._uwuify, embeds[0]) if embeds else None + embed = fun_cog._convert_embed(self._uwuify, embeds[0]) if embeds else None else: embed = None -- cgit v1.2.3 From eb6d711f49297ec361fbe045bd4c596edada29a2 Mon Sep 17 00:00:00 2001 From: AbooMinister25 Date: Mon, 8 Aug 2022 10:15:04 -0400 Subject: Fixed conflicts from PR 1078 --- bot/exts/fun/uwu.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/fun/uwu.py b/bot/exts/fun/uwu.py index 9e228065..0d650de0 100644 --- a/bot/exts/fun/uwu.py +++ b/bot/exts/fun/uwu.py @@ -10,6 +10,9 @@ from discord.ext.commands import Cog, Context, clean_content from bot.bot import Bot from bot.utils import helpers +if t.TYPE_CHECKING: + from bot.exts.fun.fun import Fun # pragma: no cover + WORD_REPLACE = { "small": "smol", "cute": "kawaii~", @@ -129,7 +132,8 @@ class Uwu(Cog): await clean_content(fix_channel_mentions=True).convert(ctx, text) - fun_cog = ctx.bot.get_cog("Fun") + fun_cog: t.Optional[Fun] = ctx.bot.get_cog("Fun") + if fun_cog: text, embed = await fun_cog._get_text_and_embed(ctx, text) -- cgit v1.2.3 From 7a41518c9cce2be0cd3ace05d7d3035e8bcbd8bf Mon Sep 17 00:00:00 2001 From: AbooMinister25 Date: Mon, 8 Aug 2022 17:46:12 -0400 Subject: Add a check for whether an embed is already available via the embeds list, and to use that --- bot/exts/fun/uwu.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'bot') diff --git a/bot/exts/fun/uwu.py b/bot/exts/fun/uwu.py index 0d75b0e2..ed8925e5 100644 --- a/bot/exts/fun/uwu.py +++ b/bot/exts/fun/uwu.py @@ -183,22 +183,23 @@ class Uwu(Cog): fun_cog: t.Optional[Fun] = ctx.bot.get_cog("Fun") if fun_cog: - text, embed = await fun_cog._get_text_and_embed(ctx, text) - # Grabs the text from the embed for uwuification - if embed is not None: - embed = fun_cog._convert_embed(self._uwuify, embed) + if embeds: + embed = fun_cog._convert_embed(self._uwuify, embeds[0]) else: - # Only use the first embed since only a single one can be sent - embed = fun_cog._convert_embed(self._uwuify, embeds[0]) if embeds else None + # Parse potential message links in text + text, embed = await fun_cog._get_text_and_embed(ctx, text) + + # If an embed is found, grab and uwuify its text + if embed: + embed = fun_cog._convert_embed(self._uwuify, embed) else: embed = None - converted_text = self._uwuify(text) - converted_text = helpers.suppress_links(converted_text) - # Adds the text harvested from an embed to be put into another quote block. if text: + converted_text = self._uwuify(text) + converted_text = helpers.suppress_links(converted_text) converted_text = f">>> {converted_text.lstrip('> ')}" else: converted_text = None -- cgit v1.2.3 From 6be0e91d1b7282febd39415fd33e6d3f6a0b0581 Mon Sep 17 00:00:00 2001 From: AbooMinister25 Date: Mon, 8 Aug 2022 18:09:24 -0400 Subject: Refactored methods _get_discord_message, _get_text_and_embed, and _convert_embed into bot/utils/messages.py --- bot/exts/fun/fun.py | 78 ++++++--------------------------------------------- bot/exts/fun/uwu.py | 8 +++--- bot/utils/messages.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 75 deletions(-) (limited to 'bot') diff --git a/bot/exts/fun/fun.py b/bot/exts/fun/fun.py index 9ec9b9ee..e7337cb6 100644 --- a/bot/exts/fun/fun.py +++ b/bot/exts/fun/fun.py @@ -3,16 +3,16 @@ import logging import random from collections.abc import Iterable from pathlib import Path -from typing import Callable, Literal, Optional, Union +from typing import Literal import pyjokes -from discord import Embed, Message +from discord import Embed from discord.ext import commands -from discord.ext.commands import BadArgument, Cog, Context, MessageConverter, clean_content +from discord.ext.commands import BadArgument, Cog, Context, clean_content from bot.bot import Bot from bot.constants import Client, Colours, Emojis -from bot.utils import helpers +from bot.utils import helpers, messages log = logging.getLogger(__name__) @@ -67,10 +67,10 @@ class Fun(Cog): return "".join( char.upper() if round(random.random()) else char.lower() for char in text ) - text, embed = await Fun._get_text_and_embed(ctx, text) + text, embed = await messages.get_text_and_embed(ctx, text) # Convert embed if it exists if embed is not None: - embed = Fun._convert_embed(conversion_func, embed) + embed = messages.convert_embed(conversion_func, embed) converted_text = conversion_func(text) converted_text = helpers.suppress_links(converted_text) # Don't put >>> if only embed present @@ -116,10 +116,10 @@ class Fun(Cog): """Encrypts the given string using the Caesar Cipher.""" return "".join(caesar_cipher(text, offset)) - text, embed = await Fun._get_text_and_embed(ctx, msg) + text, embed = await messages.get_text_and_embed(ctx, msg) if embed is not None: - embed = Fun._convert_embed(conversion_func, embed) + embed = messages.convert_embed(conversion_func, embed) converted_text = conversion_func(text) @@ -150,68 +150,6 @@ class Fun(Cog): """ await self._caesar_cipher(ctx, offset, msg, left_shift=True) - @staticmethod - async def _get_text_and_embed(ctx: Context, text: str) -> tuple[str, Optional[Embed]]: - """ - Attempts to extract the text and embed from a possible link to a discord Message. - - Does not retrieve the text and embed from the Message if it is in a channel the user does - not have read permissions in. - - Returns a tuple of: - str: If `text` is a valid discord Message, the contents of the message, else `text`. - Optional[Embed]: The embed if found in the valid Message, else None - """ - embed = None - - msg = await Fun._get_discord_message(ctx, text) - # Ensure the user has read permissions for the channel the message is in - if isinstance(msg, Message): - permissions = msg.channel.permissions_for(ctx.author) - if permissions.read_messages: - text = msg.clean_content - # Take first embed because we can't send multiple embeds - if msg.embeds: - embed = msg.embeds[0] - - return (text, embed) - - @staticmethod - async def _get_discord_message(ctx: Context, text: str) -> Union[Message, str]: - """ - Attempts to convert a given `text` to a discord Message object and return it. - - Conversion will succeed if given a discord Message ID or link. - Returns `text` if the conversion fails. - """ - try: - text = await MessageConverter().convert(ctx, text) - except commands.BadArgument: - log.debug(f"Input '{text:.20}...' is not a valid Discord Message") - return text - - @staticmethod - def _convert_embed(func: Callable[[str, ], str], embed: Embed) -> Embed: - """ - Converts the text in an embed using a given conversion function, then return the embed. - - Only modifies the following fields: title, description, footer, fields - """ - embed_dict = embed.to_dict() - - embed_dict["title"] = func(embed_dict.get("title", "")) - embed_dict["description"] = func(embed_dict.get("description", "")) - - if "footer" in embed_dict: - embed_dict["footer"]["text"] = func(embed_dict["footer"].get("text", "")) - - if "fields" in embed_dict: - for field in embed_dict["fields"]: - field["name"] = func(field.get("name", "")) - field["value"] = func(field.get("value", "")) - - return Embed.from_dict(embed_dict) - @commands.command() async def joke(self, ctx: commands.Context, category: Literal["neutral", "chuck", "all"] = "all") -> None: """Retrieves a joke of the specified `category` from the pyjokes api.""" diff --git a/bot/exts/fun/uwu.py b/bot/exts/fun/uwu.py index ed8925e5..60a5834d 100644 --- a/bot/exts/fun/uwu.py +++ b/bot/exts/fun/uwu.py @@ -9,7 +9,7 @@ from discord.ext import commands from discord.ext.commands import Cog, Context, clean_content from bot.bot import Bot -from bot.utils import helpers +from bot.utils import helpers, messages if t.TYPE_CHECKING: from bot.exts.fun.fun import Fun # pragma: no cover @@ -185,14 +185,14 @@ class Uwu(Cog): if fun_cog: # Grabs the text from the embed for uwuification if embeds: - embed = fun_cog._convert_embed(self._uwuify, embeds[0]) + embed = messages.convert_embed(self._uwuify, embeds[0]) else: # Parse potential message links in text - text, embed = await fun_cog._get_text_and_embed(ctx, text) + text, embed = await messages.get_text_and_embed(ctx, text) # If an embed is found, grab and uwuify its text if embed: - embed = fun_cog._convert_embed(self._uwuify, embed) + embed = messages.convert_embed(self._uwuify, embed) else: embed = None diff --git a/bot/utils/messages.py b/bot/utils/messages.py index a6c035f9..ccc8b61c 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -1,5 +1,12 @@ +import logging import re -from typing import Optional +from typing import Callable, Optional, Union + +from discord import Embed, Message +from discord.ext import commands +from discord.ext.commands import Context, MessageConverter + +log = logging.getLogger(__name__) def sub_clyde(username: Optional[str]) -> Optional[str]: @@ -17,3 +24,66 @@ def sub_clyde(username: Optional[str]) -> Optional[str]: return re.sub(r"(clyd)(e)", replace_e, username, flags=re.I) else: return username # Empty string or None + + +async def get_discord_message(ctx: Context, text: str) -> Union[Message, str]: + """ + Attempts to convert a given `text` to a discord Message object and return it. + + Conversion will succeed if given a discord Message ID or link. + Returns `text` if the conversion fails. + """ + try: + text = await MessageConverter().convert(ctx, text) + except commands.BadArgument: + log.debug(f"Input '{text:.20}...' is not a valid Discord Message") + + return text + + +async def get_text_and_embed(ctx: Context, text: str) -> tuple[str, Optional[Embed]]: + """ + Attempts to extract the text and embed from a possible link to a discord Message. + + Does not retrieve the text and embed from the Message if it is in a channel the user does + not have read permissions in. + + Returns a tuple of: + str: If `text` is a valid discord Message, the contents of the message, else `text`. + Optional[Embed]: The embed if found in the valid Message, else None + """ + embed: Optional[Embed] = None + + msg = await get_discord_message(ctx, text) + # Ensure the user has read permissions for the channel the message is in + if isinstance(msg, Message): + permissions = msg.channel.permissions_for(ctx.author) + if permissions.read_messages: + text = msg.clean_content + # Take first embed because we can't send multiple embeds + if msg.embeds: + embed = msg.embeds[0] + + return (text, embed) + + +def convert_embed(func: Callable[[str, ], str], embed: Embed) -> Embed: + """ + Converts the text in an embed using a given conversion function, then return the embed. + + Only modifies the following fields: title, description, footer, fields + """ + embed_dict = embed.to_dict() + + embed_dict["title"] = func(embed_dict.get("title", "")) + embed_dict["description"] = func(embed_dict.get("description", "")) + + if "footer" in embed_dict: + embed_dict["footer"]["text"] = func(embed_dict["footer"].get("text", "")) + + if "fields" in embed_dict: + for field in embed_dict["fields"]: + field["name"] = func(field.get("name", "")) + field["value"] = func(field.get("value", "")) + + return Embed.from_dict(embed_dict) -- cgit v1.2.3 From f0455f9ae865e5d424e84cafdb52bc17f25b3db5 Mon Sep 17 00:00:00 2001 From: AbooMinister25 Date: Mon, 8 Aug 2022 20:44:18 -0400 Subject: Refactored get_discord_message to not unnecessarily log, and cleaned up uwu_command --- bot/exts/fun/uwu.py | 26 +++++++++----------------- bot/utils/messages.py | 8 ++------ 2 files changed, 11 insertions(+), 23 deletions(-) (limited to 'bot') diff --git a/bot/exts/fun/uwu.py b/bot/exts/fun/uwu.py index 60a5834d..83497893 100644 --- a/bot/exts/fun/uwu.py +++ b/bot/exts/fun/uwu.py @@ -11,9 +11,6 @@ from discord.ext.commands import Cog, Context, clean_content from bot.bot import Bot from bot.utils import helpers, messages -if t.TYPE_CHECKING: - from bot.exts.fun.fun import Fun # pragma: no cover - WORD_REPLACE = { "small": "smol", "cute": "kawaii~", @@ -180,21 +177,16 @@ class Uwu(Cog): await clean_content(fix_channel_mentions=True).convert(ctx, text) - fun_cog: t.Optional[Fun] = ctx.bot.get_cog("Fun") - - if fun_cog: - # Grabs the text from the embed for uwuification - if embeds: - embed = messages.convert_embed(self._uwuify, embeds[0]) - else: - # Parse potential message links in text - text, embed = await messages.get_text_and_embed(ctx, text) - - # If an embed is found, grab and uwuify its text - if embed: - embed = messages.convert_embed(self._uwuify, embed) + # Grabs the text from the embed for uwuification + if embeds: + embed = messages.convert_embed(self._uwuify, embeds[0]) else: - embed = None + # Parse potential message links in text + text, embed = await messages.get_text_and_embed(ctx, text) + + # If an embed is found, grab and uwuify its text + if embed: + embed = messages.convert_embed(self._uwuify, embed) # Adds the text harvested from an embed to be put into another quote block. if text: diff --git a/bot/utils/messages.py b/bot/utils/messages.py index ccc8b61c..71b634e8 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -3,7 +3,6 @@ import re from typing import Callable, Optional, Union from discord import Embed, Message -from discord.ext import commands from discord.ext.commands import Context, MessageConverter log = logging.getLogger(__name__) @@ -33,10 +32,7 @@ async def get_discord_message(ctx: Context, text: str) -> Union[Message, str]: Conversion will succeed if given a discord Message ID or link. Returns `text` if the conversion fails. """ - try: - text = await MessageConverter().convert(ctx, text) - except commands.BadArgument: - log.debug(f"Input '{text:.20}...' is not a valid Discord Message") + text = await MessageConverter().convert(ctx, text) return text @@ -64,7 +60,7 @@ async def get_text_and_embed(ctx: Context, text: str) -> tuple[str, Optional[Emb if msg.embeds: embed = msg.embeds[0] - return (text, embed) + return text, embed def convert_embed(func: Callable[[str, ], str], embed: Embed) -> Embed: -- cgit v1.2.3 From 2354d05a1a3ec029a5d85d753e5147c000f53044 Mon Sep 17 00:00:00 2001 From: AbooMinister25 Date: Tue, 9 Aug 2022 18:48:39 -0400 Subject: Add error handling to get_discord_message --- bot/utils/messages.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/utils/messages.py b/bot/utils/messages.py index 71b634e8..b0c95583 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -3,6 +3,7 @@ import re from typing import Callable, Optional, Union from discord import Embed, Message +from discord.ext import commands from discord.ext.commands import Context, MessageConverter log = logging.getLogger(__name__) @@ -32,7 +33,10 @@ async def get_discord_message(ctx: Context, text: str) -> Union[Message, str]: Conversion will succeed if given a discord Message ID or link. Returns `text` if the conversion fails. """ - text = await MessageConverter().convert(ctx, text) + try: + text = await MessageConverter().convert(ctx, text) + except commands.BadArgument: + pass return text -- cgit v1.2.3