From 7cb5c5517043c0006b001c15373b664b86cc6b43 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Fri, 3 Dec 2021 17:28:15 -0500 Subject: feat: implement moving commands add exceptions and handler for commands that move locations --- bot/constants.py | 3 +++ bot/exts/core/error_handler.py | 10 +++++++++- bot/utils/exceptions.py | 7 +++++++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/constants.py b/bot/constants.py index f4b1cab0..854fbe55 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -23,6 +23,7 @@ __all__ = ( "Reddit", "RedisConfig", "RedirectOutput", + "PYTHON_PREFIX" "MODERATION_ROLES", "STAFF_ROLES", "WHITELISTED_CHANNELS", @@ -34,6 +35,8 @@ __all__ = ( log = logging.getLogger(__name__) +PYTHON_PREFIX = "!" + @dataclasses.dataclass class AdventOfCodeLeaderboard: id: str diff --git a/bot/exts/core/error_handler.py b/bot/exts/core/error_handler.py index fd2123e7..676a1e70 100644 --- a/bot/exts/core/error_handler.py +++ b/bot/exts/core/error_handler.py @@ -12,7 +12,7 @@ from sentry_sdk import push_scope from bot.bot import Bot from bot.constants import Channels, Colours, ERROR_REPLIES, NEGATIVE_REPLIES, RedirectOutput from bot.utils.decorators import InChannelCheckFailure, InMonthCheckFailure -from bot.utils.exceptions import APIError, UserNotPlayingError +from bot.utils.exceptions import APIError, MovedCommandError, UserNotPlayingError log = logging.getLogger(__name__) @@ -130,6 +130,14 @@ class CommandErrorHandler(commands.Cog): ) return + if isinstance(error, MovedCommandError): + description = ( + f"This command, `{ctx.prefix}{ctx.command.qualified_name}` has moved to `{error.new_command_name}`.\n" + f"Please use `{error.new_command_name}` instead." + ) + await ctx.send(embed=self.error_embed(description, NEGATIVE_REPLIES)) + return + with push_scope() as scope: scope.user = { "id": ctx.author.id, diff --git a/bot/utils/exceptions.py b/bot/utils/exceptions.py index bf0e5813..3cd96325 100644 --- a/bot/utils/exceptions.py +++ b/bot/utils/exceptions.py @@ -15,3 +15,10 @@ class APIError(Exception): self.api = api self.status_code = status_code self.error_msg = error_msg + + +class MovedCommandError(Exception): + """Raised when a command has moved locations.""" + + def __init__(self, new_command_name: str): + self.new_command_name = new_command_name -- cgit v1.2.3 From c7f62d3d63b4fe84c8f96bf38b66198838fdb538 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Fri, 3 Dec 2021 17:28:39 -0500 Subject: yank lovefest role management commands --- bot/exts/holidays/valentines/be_my_valentine.py | 31 +++++++++---------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'bot') diff --git a/bot/exts/holidays/valentines/be_my_valentine.py b/bot/exts/holidays/valentines/be_my_valentine.py index 4d454c3a..a9a4731f 100644 --- a/bot/exts/holidays/valentines/be_my_valentine.py +++ b/bot/exts/holidays/valentines/be_my_valentine.py @@ -7,14 +7,17 @@ import discord from discord.ext import commands from bot.bot import Bot -from bot.constants import Channels, Colours, Lovefest, Month +from bot.constants import Channels, Colours, Lovefest, Month, PYTHON_PREFIX from bot.utils.decorators import in_month +from bot.utils.exceptions import MovedCommandError from bot.utils.extensions import invoke_help_command log = logging.getLogger(__name__) HEART_EMOJIS = [":heart:", ":gift_heart:", ":revolving_hearts:", ":sparkling_heart:", ":two_hearts:"] +MOVED_COMMAND = f"{PYTHON_PREFIX}subscribe" + class BeMyValentine(commands.Cog): """A cog that sends Valentines to other users!""" @@ -30,7 +33,7 @@ class BeMyValentine(commands.Cog): return loads(p.read_text("utf8")) @in_month(Month.FEBRUARY) - @commands.group(name="lovefest") + @commands.group(name="lovefest", help=f"This command has been moved to {MOVED_COMMAND}") async def lovefest_role(self, ctx: commands.Context) -> None: """ Subscribe or unsubscribe from the lovefest role. @@ -43,27 +46,15 @@ class BeMyValentine(commands.Cog): if not ctx.invoked_subcommand: await invoke_help_command(ctx) - @lovefest_role.command(name="sub") + @lovefest_role.command(name="sub", help=f"This command has been moved to {MOVED_COMMAND}") async def add_role(self, ctx: commands.Context) -> None: - """Adds the lovefest role.""" - user = ctx.author - role = ctx.guild.get_role(Lovefest.role_id) - if role not in ctx.author.roles: - await user.add_roles(role) - await ctx.send("The Lovefest role has been added !") - else: - await ctx.send("You already have the role !") + """NOTE: This command has been moved to bot.""" + raise MovedCommandError(MOVED_COMMAND) - @lovefest_role.command(name="unsub") + @lovefest_role.command(name="unsub", help=f"This command has been moved to {MOVED_COMMAND}") async def remove_role(self, ctx: commands.Context) -> None: - """Removes the lovefest role.""" - user = ctx.author - role = ctx.guild.get_role(Lovefest.role_id) - if role not in ctx.author.roles: - await ctx.send("You dont have the lovefest role.") - else: - await user.remove_roles(role) - await ctx.send("The lovefest role has been successfully removed!") + """NOTE: This command has been moved to bot.""" + raise MovedCommandError(MOVED_COMMAND) @commands.cooldown(1, 1800, commands.BucketType.user) @commands.group(name="bemyvalentine", invoke_without_command=True) -- cgit v1.2.3 From 2d0760821b629bcb3269534ed46c0a9af4026264 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Fri, 3 Dec 2021 17:19:57 -0500 Subject: chore: remove subcommands entirely --- bot/exts/holidays/valentines/be_my_valentine.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'bot') diff --git a/bot/exts/holidays/valentines/be_my_valentine.py b/bot/exts/holidays/valentines/be_my_valentine.py index a9a4731f..1e13e424 100644 --- a/bot/exts/holidays/valentines/be_my_valentine.py +++ b/bot/exts/holidays/valentines/be_my_valentine.py @@ -10,7 +10,6 @@ from bot.bot import Bot from bot.constants import Channels, Colours, Lovefest, Month, PYTHON_PREFIX from bot.utils.decorators import in_month from bot.utils.exceptions import MovedCommandError -from bot.utils.extensions import invoke_help_command log = logging.getLogger(__name__) @@ -33,7 +32,7 @@ class BeMyValentine(commands.Cog): return loads(p.read_text("utf8")) @in_month(Month.FEBRUARY) - @commands.group(name="lovefest", help=f"This command has been moved to {MOVED_COMMAND}") + @commands.command(name="lovefest", help=f"NOTE: This command has been moved to {MOVED_COMMAND}") async def lovefest_role(self, ctx: commands.Context) -> None: """ Subscribe or unsubscribe from the lovefest role. @@ -43,17 +42,6 @@ class BeMyValentine(commands.Cog): 1) use the command \".lovefest sub\" to get the lovefest role. 2) use the command \".lovefest unsub\" to get rid of the lovefest role. """ - if not ctx.invoked_subcommand: - await invoke_help_command(ctx) - - @lovefest_role.command(name="sub", help=f"This command has been moved to {MOVED_COMMAND}") - async def add_role(self, ctx: commands.Context) -> None: - """NOTE: This command has been moved to bot.""" - raise MovedCommandError(MOVED_COMMAND) - - @lovefest_role.command(name="unsub", help=f"This command has been moved to {MOVED_COMMAND}") - async def remove_role(self, ctx: commands.Context) -> None: - """NOTE: This command has been moved to bot.""" raise MovedCommandError(MOVED_COMMAND) @commands.cooldown(1, 1800, commands.BucketType.user) -- cgit v1.2.3 From cfb2cc69287f0aefab0937d0e8e8f99811d50948 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Fri, 3 Dec 2021 18:26:33 -0500 Subject: chore: update lovefest docstring to reflect deprecation --- bot/exts/holidays/valentines/be_my_valentine.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'bot') diff --git a/bot/exts/holidays/valentines/be_my_valentine.py b/bot/exts/holidays/valentines/be_my_valentine.py index 1e13e424..1572d474 100644 --- a/bot/exts/holidays/valentines/be_my_valentine.py +++ b/bot/exts/holidays/valentines/be_my_valentine.py @@ -35,12 +35,9 @@ class BeMyValentine(commands.Cog): @commands.command(name="lovefest", help=f"NOTE: This command has been moved to {MOVED_COMMAND}") async def lovefest_role(self, ctx: commands.Context) -> None: """ - Subscribe or unsubscribe from the lovefest role. + Deprecated lovefest role command. - The lovefest role makes you eligible to receive anonymous valentines from other users. - - 1) use the command \".lovefest sub\" to get the lovefest role. - 2) use the command \".lovefest unsub\" to get rid of the lovefest role. + This command has been moved to bot, and will be removed in the future. """ raise MovedCommandError(MOVED_COMMAND) -- cgit v1.2.3 From 163a6e14c22b7992f44dca699de9e71c11362613 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sun, 5 Dec 2021 13:11:03 +0000 Subject: Patch d.py's message converters to infer channelID from the given context Discord.py's message converter is supposed to infer channelID based on ctx.channel if only a messageID is given. A refactor (linked below) a few weeks before d.py's archival broke this, so that if only a messageID is given to the converter, it will only find that message if it's in the bot's cache. --- bot/__init__.py | 5 +++++ bot/monkey_patches.py | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'bot') diff --git a/bot/__init__.py b/bot/__init__.py index ae53a5a5..3136c863 100644 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -43,6 +43,11 @@ if os.name == "nt": monkey_patches.patch_typing() +# This patches any convertors that use PartialMessage, but not the PartialMessageConverter itself +# as library objects are made by this mapping. +# https://github.com/Rapptz/discord.py/blob/1a4e73d59932cdbe7bf2c281f25e32529fc7ae1f/discord/ext/commands/converter.py#L984-L1004 +commands.converter.PartialMessageConverter = monkey_patches.FixedPartialMessageConverter + # Monkey-patch discord.py decorators to use the both the Command and Group subclasses which supports root aliases. # Must be patched before any cogs are added. commands.command = partial(commands.command, cls=monkey_patches.Command) diff --git a/bot/monkey_patches.py b/bot/monkey_patches.py index fa6627d1..19965c19 100644 --- a/bot/monkey_patches.py +++ b/bot/monkey_patches.py @@ -1,10 +1,12 @@ import logging +import re from datetime import datetime, timedelta from discord import Forbidden, http from discord.ext import commands log = logging.getLogger(__name__) +MESSAGE_ID_RE = re.compile(r'(?P[0-9]{15,20})$') class Command(commands.Command): @@ -65,3 +67,25 @@ def patch_typing() -> None: pass http.HTTPClient.send_typing = honeybadger_type + + +class FixedPartialMessageConverter(commands.PartialMessageConverter): + """ + Make the Message converter infer channelID from the given context if only a messageID is given. + + Discord.py's Message converter is supposed to infer channelID based + on ctx.channel if only a messageID is given. A refactor commit, linked below, + a few weeks before d.py's archival broke this defined behaviour of the converter. + Currently, if only a messageID is given to the converter, it will only find that message + if it's in the bot's cache. + + https://github.com/Rapptz/discord.py/commit/1a4e73d59932cdbe7bf2c281f25e32529fc7ae1f + """ + + @staticmethod + def _get_id_matches(ctx: commands.Context, argument: str) -> tuple[int, int, int]: + """Inserts ctx.channel.id before calling super method if argument is just a messageID.""" + match = MESSAGE_ID_RE.match(argument) + if match: + argument = f"{ctx.channel.id}-{match.group('message_id')}" + return commands.PartialMessageConverter._get_id_matches(ctx, argument) -- cgit v1.2.3 From 598cf151cfaaa8e6777cd602714c10666ad45b4a Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sun, 5 Dec 2021 13:12:41 +0000 Subject: Reflect new message converter behaviour in bm help message Since w epatched the message converter to work as intended, the help message given to a user when failing to resolve a message reference to a message object has been updated. --- bot/exts/utilities/bookmark.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index a11c366b..b50205a0 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -102,7 +102,7 @@ class Bookmark(commands.Cog): "You must either provide a valid message to bookmark, or reply to one." "\n\nThe lookup strategy for a message is as follows (in order):" "\n1. Lookup by '{channel ID}-{message ID}' (retrieved by shift-clicking on 'Copy ID')" - "\n2. Lookup by message ID (the message **must** have been sent after the bot last started)" + "\n2. Lookup by message ID (the message **must** be in the context channel)" "\n3. Lookup by message URL" ) target_message = ctx.message.reference.resolved -- cgit v1.2.3