From 40ad07bef549c692b11289aba2379a6051887bc1 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Tue, 26 Apr 2022 18:24:05 +0100 Subject: Simplify when a message can not be found when bookmarking --- bot/exts/utilities/bookmark.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index b50205a0..ef0daac0 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -16,6 +16,13 @@ log = logging.getLogger(__name__) # Number of seconds to wait for other users to bookmark the same message TIMEOUT = 120 BOOKMARK_EMOJI = "📌" +MESSAGE_NOT_FOUND_ERROR = ( + "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** be in the current channel)" + "\n3. Lookup by message URL" +) class Bookmark(commands.Cog): @@ -95,17 +102,16 @@ class Bookmark(commands.Cog): *, title: str = "Bookmark" ) -> None: - """Send the author a link to `target_message` via DMs.""" - if not target_message: - if not ctx.message.reference: - raise commands.UserInputError( - "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** be in the context channel)" - "\n3. Lookup by message URL" - ) - target_message = ctx.message.reference.resolved + """ + Send the author a link to the specified message via DMs. + + Members can either give a message as an argument, or reply to a message. + + Bookmarks can subsequently be deleted by using the `bookmark delete` command. + """ + target_message: Optional[discord.Message] = target_message or getattr(ctx.message.reference, "resolved", None) + if target_message is None: + raise commands.UserInputError(MESSAGE_NOT_FOUND_ERROR) # Prevent users from bookmarking a message in a channel they don't have access to permissions = target_message.channel.permissions_for(ctx.author) -- cgit v1.2.3 From 2ecdaf4951c70234f58f888fabbd285564d1c1b8 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Tue, 26 Apr 2022 18:33:51 +0100 Subject: Simplify bookmark error embed helper --- bot/exts/utilities/bookmark.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index ef0daac0..d6b16f56 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -49,30 +49,31 @@ class Bookmark(commands.Cog): return embed @staticmethod - def build_error_embed(user: discord.Member) -> discord.Embed: - """Builds an error embed for when a bookmark requester has DMs disabled.""" + def build_error_embed(message: str) -> discord.Embed: + """Builds an error embed for a given message.""" return discord.Embed( title=random.choice(ERROR_REPLIES), - description=f"{user.mention}, please enable your DMs to receive the bookmark.", + description=message, colour=Colours.soft_red ) async def action_bookmark( self, channel: discord.TextChannel, - user: discord.Member, + member: discord.Member, target_message: discord.Message, title: str ) -> None: - """Sends the bookmark DM, or sends an error embed when a user bookmarks a message.""" + """Sends the bookmark DM, or sends an error embed when a member bookmarks a message.""" + embed = self.build_bookmark_dm(target_message, title) try: - embed = self.build_bookmark_dm(target_message, title) - await user.send(embed=embed) + await member.send(embed=embed) except discord.Forbidden: - error_embed = self.build_error_embed(user) - await channel.send(embed=error_embed) + error_embed = self.build_error_embed(f"{member.mention}, please enable your DMs to receive the bookmark.") else: - log.info(f"{user} bookmarked {target_message.jump_url} with title '{title}'") + log.info(f"{member} bookmarked {target_message.jump_url} with title '{title}'") + return + await channel.send(embed=error_embed) @staticmethod async def send_reaction_embed( @@ -117,11 +118,7 @@ class Bookmark(commands.Cog): permissions = target_message.channel.permissions_for(ctx.author) if not permissions.read_messages: log.info(f"{ctx.author} tried to bookmark a message in #{target_message.channel} but has no permissions.") - embed = discord.Embed( - title=random.choice(ERROR_REPLIES), - color=Colours.soft_red, - description="You don't have permission to view this channel." - ) + embed = self.build_error_embed(f"{ctx.author.mention} You don't have permission to view this channel.") await ctx.send(embed=embed) return -- cgit v1.2.3 From 4d9477bf72eba8c6110c59a5edbb12ed617092a3 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Tue, 26 Apr 2022 18:35:32 +0100 Subject: Remove need for additional abstraction in bookmark command --- bot/exts/utilities/bookmark.py | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index d6b16f56..32f6faa1 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -75,25 +75,6 @@ class Bookmark(commands.Cog): return await channel.send(embed=error_embed) - @staticmethod - async def send_reaction_embed( - channel: discord.TextChannel, - target_message: discord.Message - ) -> discord.Message: - """Sends an embed, with a reaction, so users can react to bookmark the message too.""" - message = await channel.send( - embed=discord.Embed( - description=( - f"React with {BOOKMARK_EMOJI} to be sent your very own bookmark to " - f"[this message]({target_message.jump_url})." - ), - colour=Colours.soft_green - ) - ) - - await message.add_reaction(BOOKMARK_EMOJI) - return message - @commands.command(name="bookmark", aliases=("bm", "pin")) @whitelist_override(roles=(Roles.everyone,)) async def bookmark( @@ -122,6 +103,21 @@ class Bookmark(commands.Cog): await ctx.send(embed=embed) return + await self.action_bookmark(ctx.channel, ctx.author, target_message, title) + + # Keep track of who has already bookmarked, so users can't spam reactions and cause loads of DMs + bookmarked_users = [ctx.author.id] + + reaction_embed = discord.Embed( + description=( + f"React with {BOOKMARK_EMOJI} to be sent your very own bookmark to " + f"[this message]({ctx.message.jump_url})." + ), + colour=Colours.soft_green + ) + reaction_message = await ctx.send(embed=reaction_embed) + await reaction_message.add_reaction(BOOKMARK_EMOJI) + def event_check(reaction: discord.Reaction, user: discord.Member) -> bool: """Make sure that this reaction is what we want to operate on.""" return ( @@ -137,11 +133,6 @@ class Bookmark(commands.Cog): user.id != self.bot.user.id )) ) - await self.action_bookmark(ctx.channel, ctx.author, target_message, title) - - # Keep track of who has already bookmarked, so users can't spam reactions and cause loads of DMs - bookmarked_users = [ctx.author.id] - reaction_message = await self.send_reaction_embed(ctx.channel, target_message) while True: try: -- cgit v1.2.3 From 5689ea0a8ad7e46a5c8f758b083b742d951cef40 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Tue, 26 Apr 2022 18:36:07 +0100 Subject: Add command to delete bot messages in DMs with sir-lancebot --- bot/exts/utilities/bookmark.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index 32f6faa1..521a7bfa 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -75,7 +75,8 @@ class Bookmark(commands.Cog): return await channel.send(embed=error_embed) - @commands.command(name="bookmark", aliases=("bm", "pin")) + @commands.group(name="bookmark", aliases=("bm", "pin"), invoke_without_command=True) + @commands.guild_only() @whitelist_override(roles=(Roles.everyone,)) async def bookmark( self, @@ -146,6 +147,30 @@ class Bookmark(commands.Cog): await reaction_message.delete() + @commands.dm_only() + @bookmark.command(name="delete", aliases=("del", "rm"), root_aliases=("unbm", "unbookmark", "dmdelete", "dmdel")) + async def delete_bookmark( + self, + ctx: commands.Context, + target_message: Optional[WrappedMessageConverter] + ) -> None: + """ + Delete the referenced DM message by the member. + + Members can either give a message as an argument, or reply to a message. + This allows deleting any message in the user's DM with sir-lancebot. + """ + target_message: Optional[discord.Message] = target_message or getattr(ctx.message.reference, "resolved", None) + if target_message is None: + raise commands.UserInputError(MESSAGE_NOT_FOUND_ERROR) + + if target_message.channel != ctx.channel: + raise commands.UserInputError(":x: You can only delete messages in your own DMs!") + elif target_message.author != self.bot.user: + raise commands.UserInputError(":x: You can only delete messages sent by Sir Lancebot!") + + await target_message.delete() + def setup(bot: Bot) -> None: """Load the Bookmark cog.""" -- cgit v1.2.3 From 631c7da337435e3667b5f4af89fbd7657ff5bc3c Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Tue, 26 Apr 2022 18:41:30 +0100 Subject: Improve the docstring for the action_bookmark function --- bot/exts/utilities/bookmark.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index 521a7bfa..2d21fa8a 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -64,7 +64,11 @@ class Bookmark(commands.Cog): target_message: discord.Message, title: str ) -> None: - """Sends the bookmark DM, or sends an error embed when a member bookmarks a message.""" + """ + Sends the given target_message as a bookmark to the member in DMs to the user. + + Send an error embed instead if the member has DMs disabled. + """ embed = self.build_bookmark_dm(target_message, title) try: await member.send(embed=embed) -- cgit v1.2.3 From 50439bc33019d2c79f6e613c2d586c29adc07ec9 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sun, 1 May 2022 18:44:56 +0100 Subject: Fix unbm DM only logic The DM only check was interfering with our global check against DM messages. This commit also makes the docstring a little more explanatory, as this is what the user sees when running the help command. --- bot/exts/utilities/bookmark.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index 2d21fa8a..7d44fa71 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -151,27 +151,31 @@ class Bookmark(commands.Cog): await reaction_message.delete() - @commands.dm_only() @bookmark.command(name="delete", aliases=("del", "rm"), root_aliases=("unbm", "unbookmark", "dmdelete", "dmdel")) + @whitelist_override(bypass_defaults=True, allow_dm=True) async def delete_bookmark( self, ctx: commands.Context, target_message: Optional[WrappedMessageConverter] ) -> None: """ - Delete the referenced DM message by the member. + Delete the target message specified by the member. Must be ran in DMs targetting a message sent by Sir-Lancebot. - Members can either give a message as an argument, or reply to a message. - This allows deleting any message in the user's DM with sir-lancebot. + `target_message` may be a message link, or an ID that references the message, + Instead of giving a `target_message` the user may also reply to the message to delete. + + This command allows deleting any message sent by Sir-Lancebot in the user's DMs. """ target_message: Optional[discord.Message] = target_message or getattr(ctx.message.reference, "resolved", None) if target_message is None: raise commands.UserInputError(MESSAGE_NOT_FOUND_ERROR) - if target_message.channel != ctx.channel: - raise commands.UserInputError(":x: You can only delete messages in your own DMs!") + if not isinstance(ctx.channel, discord.DMChannel): + raise commands.UserInputError("You can only run this command your own DMs!") + elif target_message.channel != ctx.channel: + raise commands.UserInputError("You can only delete messages in your own DMs!") elif target_message.author != self.bot.user: - raise commands.UserInputError(":x: You can only delete messages sent by Sir Lancebot!") + raise commands.UserInputError("You can only delete messages sent by Sir Lancebot!") await target_message.delete() -- cgit v1.2.3 From 1607da06a3078abf179c39cb06014fd529ba66d8 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sun, 29 May 2022 09:46:51 +0100 Subject: fixup: Improved docstring and error message in bookmark command --- bot/exts/utilities/bookmark.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index 7d44fa71..58f3044c 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -17,7 +17,7 @@ log = logging.getLogger(__name__) TIMEOUT = 120 BOOKMARK_EMOJI = "📌" MESSAGE_NOT_FOUND_ERROR = ( - "You must either provide a valid message to bookmark, or reply to one." + "You must either provide a reference to a valid message, 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** be in the current channel)" @@ -94,7 +94,7 @@ class Bookmark(commands.Cog): Members can either give a message as an argument, or reply to a message. - Bookmarks can subsequently be deleted by using the `bookmark delete` command. + Bookmarks can subsequently be deleted by using the `bookmark delete` command in DMs. """ target_message: Optional[discord.Message] = target_message or getattr(ctx.message.reference, "resolved", None) if target_message is None: -- cgit v1.2.3 From c4b45fe512f71776f8d4ef6698b88ed8bc4606c9 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Sun, 10 Jul 2022 12:50:41 +0100 Subject: Update help command to work with root_aliases Specifying root_aliases causes bookmark delete to be registered as a command rather than subcommand, which causes it to be listed even though subcommands usually aren't, and this isn't done correctly. Co-authored-by: wookie184 --- bot/exts/core/help.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/core/help.py b/bot/exts/core/help.py index b5df70ca..7d8066df 100644 --- a/bot/exts/core/help.py +++ b/bot/exts/core/help.py @@ -286,7 +286,7 @@ class HelpSession: else: results.append(f"<{name}>") - return f"{cmd.name} {' '.join(results)}" + return f"{cmd.qualified_name} {' '.join(results)}" async def build_pages(self) -> None: """Builds the list of content pages to be paginated through in the help message, as a list of str.""" @@ -313,6 +313,8 @@ class HelpSession: prefix = constants.Client.prefix signature = self._get_command_params(self.query) + paginator.add_line(f"**```\n{prefix}{signature}\n```**") + parent = self.query.full_parent_name + " " if self.query.parent else "" paginator.add_line(f"**```\n{prefix}{parent}{signature}\n```**") aliases = [f"`{alias}`" if not parent else f"`{parent}{alias}`" for alias in self.query.aliases] -- cgit v1.2.3 From aa2cdf594892b563f3d8ba24aa4f04d43a85e331 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Thu, 18 Aug 2022 18:34:51 +0100 Subject: Don't output command name twice in help command --- bot/exts/core/help.py | 1 - 1 file changed, 1 deletion(-) (limited to 'bot') diff --git a/bot/exts/core/help.py b/bot/exts/core/help.py index 7d8066df..7384c27d 100644 --- a/bot/exts/core/help.py +++ b/bot/exts/core/help.py @@ -316,7 +316,6 @@ class HelpSession: paginator.add_line(f"**```\n{prefix}{signature}\n```**") parent = self.query.full_parent_name + " " if self.query.parent else "" - paginator.add_line(f"**```\n{prefix}{parent}{signature}\n```**") aliases = [f"`{alias}`" if not parent else f"`{parent}{alias}`" for alias in self.query.aliases] aliases += [f"`{alias}`" for alias in getattr(self.query, "root_aliases", ())] aliases = ", ".join(sorted(aliases)) -- cgit v1.2.3 From 702144d1ac88696cf045f12e1972cfe6f58335e5 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Thu, 18 Aug 2022 18:35:25 +0100 Subject: Allow help in DMs Since there are some comands that work in DMs, we should allow the command to be ran there. --- bot/exts/core/help.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'bot') diff --git a/bot/exts/core/help.py b/bot/exts/core/help.py index 7384c27d..eb7a9762 100644 --- a/bot/exts/core/help.py +++ b/bot/exts/core/help.py @@ -13,6 +13,7 @@ from bot import constants from bot.bot import Bot from bot.constants import Emojis from bot.utils.commands import get_command_suggestions +from bot.utils.decorators import whitelist_override from bot.utils.pagination import FIRST_EMOJI, LAST_EMOJI, LEFT_EMOJI, LinePaginator, RIGHT_EMOJI DELETE_EMOJI = Emojis.trashcan @@ -512,6 +513,7 @@ class Help(DiscordCog): """Custom Embed Pagination Help feature.""" @commands.command("help") + @whitelist_override(allow_dm=True) async def new_help(self, ctx: Context, *commands) -> None: """Shows Command Help.""" try: -- cgit v1.2.3 From fabfa9074e76b5e8577b1fc068fbb02627ff9577 Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Fri, 19 Aug 2022 10:27:12 +0100 Subject: Update bookmark error handling This moves sending the error response to within the except block, making it easier to parse what the code is doing. --- bot/exts/utilities/bookmark.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index 58f3044c..70175c80 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -74,10 +74,9 @@ class Bookmark(commands.Cog): await member.send(embed=embed) except discord.Forbidden: error_embed = self.build_error_embed(f"{member.mention}, please enable your DMs to receive the bookmark.") + await channel.send(embed=error_embed) else: log.info(f"{member} bookmarked {target_message.jump_url} with title '{title}'") - return - await channel.send(embed=error_embed) @commands.group(name="bookmark", aliases=("bm", "pin"), invoke_without_command=True) @commands.guild_only() -- cgit v1.2.3 From 36eb3d19c742dac3351ff90e44509115867a512b Mon Sep 17 00:00:00 2001 From: Chris Lovering Date: Fri, 19 Aug 2022 13:50:42 +0100 Subject: Require dm delete command be invoceed by replying to a lance message --- bot/exts/utilities/bookmark.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'bot') diff --git a/bot/exts/utilities/bookmark.py b/bot/exts/utilities/bookmark.py index 70175c80..2e3458d8 100644 --- a/bot/exts/utilities/bookmark.py +++ b/bot/exts/utilities/bookmark.py @@ -155,19 +155,16 @@ class Bookmark(commands.Cog): async def delete_bookmark( self, ctx: commands.Context, - target_message: Optional[WrappedMessageConverter] ) -> None: """ - Delete the target message specified by the member. Must be ran in DMs targetting a message sent by Sir-Lancebot. + Delete the Sir-Lancebot message that the command invocation is replying to. - `target_message` may be a message link, or an ID that references the message, - Instead of giving a `target_message` the user may also reply to the message to delete. - - This command allows deleting any message sent by Sir-Lancebot in the user's DMs. + This command allows deleting any message sent by Sir-Lancebot in the user's DM channel with the bot. + The command invocation must be a reply to the message that is to be deleted. """ - target_message: Optional[discord.Message] = target_message or getattr(ctx.message.reference, "resolved", None) + target_message: Optional[discord.Message] = getattr(ctx.message.reference, "resolved", None) if target_message is None: - raise commands.UserInputError(MESSAGE_NOT_FOUND_ERROR) + raise commands.UserInputError("You must reply to the message from Sir-Lancebot you wish to delete.") if not isinstance(ctx.channel, discord.DMChannel): raise commands.UserInputError("You can only run this command your own DMs!") -- cgit v1.2.3