From eeafc9363f0497e2faebdf331375f0a456300d97 Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 15 Jan 2021 20:26:03 +1000 Subject: [PATCH] [commands] Add PartialMessageConverter --- discord/ext/commands/converter.py | 48 ++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py index a33924822ef7..aff96aac5dc8 100644 --- a/discord/ext/commands/converter.py +++ b/discord/ext/commands/converter.py @@ -37,6 +37,7 @@ 'MemberConverter', 'UserConverter', 'MessageConverter', + 'PartialMessageConverter', 'TextChannelConverter', 'InviteConverter', 'RoleConverter', @@ -251,21 +252,18 @@ async def convert(self, ctx, argument): return result -class MessageConverter(Converter): - """Converts to a :class:`discord.Message`. - - .. versionadded:: 1.1 +class PartialMessageConverter(Converter): + """Converts to a :class:`discord.PartialMessage`. - The lookup strategy is as follows (in order): + .. versionadded:: 1.7 - 1. Lookup by "{channel ID}-{message ID}" (retrieved by shift-clicking on "Copy ID") - 2. Lookup by message ID (the message **must** be in the context channel) - 3. Lookup by message URL + The creation strategy is as follows (in order): - .. versionchanged:: 1.5 - Raise :exc:`.ChannelNotFound`, :exc:`.MessageNotFound` or :exc:`.ChannelNotReadable` instead of generic :exc:`.BadArgument` + 1. By "{channel ID}-{message ID}" (retrieved by shift-clicking on "Copy ID") + 2. By message ID (The message is assumed to be in the context channel.) + 3. By message URL """ - async def convert(self, ctx, argument): + def _get_id_matches(self, argument): id_regex = re.compile(r'(?:(?P[0-9]{15,21})-)?(?P[0-9]{15,21})$') link_regex = re.compile( r'https?://(?:(ptb|canary|www)\.)?discord(?:app)?\.com/channels/' @@ -275,12 +273,36 @@ async def convert(self, ctx, argument): match = id_regex.match(argument) or link_regex.match(argument) if not match: raise MessageNotFound(argument) - message_id = int(match.group("message_id")) channel_id = match.group("channel_id") + return int(match.group("message_id")), int(channel_id) if channel_id else None + + async def convert(self, ctx, argument): + message_id, channel_id = self._get_id_matches(argument) + channel = ctx.bot.get_channel(channel_id) if channel_id else ctx.channel + if not channel: + raise ChannelNotFound(channel_id) + return discord.PartialMessage(channel=channel, id=message_id) + +class MessageConverter(PartialMessageConverter): + """Converts to a :class:`discord.Message`. + + .. versionadded:: 1.1 + + The lookup strategy is as follows (in order): + + 1. Lookup by "{channel ID}-{message ID}" (retrieved by shift-clicking on "Copy ID") + 2. Lookup by message ID (the message **must** be in the context channel) + 3. Lookup by message URL + + .. versionchanged:: 1.5 + Raise :exc:`.ChannelNotFound`, :exc:`.MessageNotFound` or :exc:`.ChannelNotReadable` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + message_id, channel_id = self._get_id_matches(argument) message = ctx.bot._connection._get_message(message_id) if message: return message - channel = ctx.bot.get_channel(int(channel_id)) if channel_id else ctx.channel + channel = ctx.bot.get_channel(channel_id) if channel_id else ctx.channel if not channel: raise ChannelNotFound(channel_id) try: