diff options
| author | 2020-11-15 15:28:11 +0300 | |
|---|---|---|
| committer | 2020-11-15 15:28:11 +0300 | |
| commit | d303557fc601c8b617d34dded401bf85038500ce (patch) | |
| tree | a9e9c420801997fb22e6a1a3564fea9a648f0f30 | |
| parent | CI: disable 'continueOnError' (diff) | |
Implements Channel Converter
Adds a converter that can decipher more forms of channel mentions, to
lay foundation for voice channel muting.
Signed-off-by: Hassan Abouelela <[email protected]>
| -rw-r--r-- | bot/converters.py | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/bot/converters.py b/bot/converters.py index 2e118d476..b9db37fce 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -536,6 +536,46 @@ class FetchedUser(UserConverter): raise BadArgument(f"User `{arg}` does not exist") +class AnyChannelConverter(UserConverter): + """ + Converts to a `discord.Channel` or, raises an error. + + Unlike the default Channel Converter, this converter can handle channels given + in string, id, or mention formatting for both `TextChannel`s and `VoiceChannel`s. + Always returns 1 or fewer channels, errors if more than one match exists. + + It is able to handle the following formats (caveats noted below:) + 1. Convert from ID - Example: 267631170882240512 + 2. Convert from Explicit Mention - Example: #welcome + 3. Convert from ID Mention - Example: <#267631170882240512> + 4. Convert from Unmentioned Name: - Example: welcome + + All the previous conversions are valid for both text and voice channels, but explicit + raw names (#4) do not work for non-unique channels, instead opting for an error. + Explicit mentions (#2) do not work for non-unique voice channels either. + """ + + async def convert(self, ctx: Context, arg: str) -> t.Union[discord.TextChannel, discord.VoiceChannel]: + """Convert the `arg` to a `TextChannel` or `VoiceChannel`.""" + stripped = arg.strip().lstrip("<").lstrip("#").rstrip(">") + + # Filter channels by name and ID + channels = [channel for channel in ctx.guild.channels if stripped in (channel.name, str(channel.id))] + + if len(channels) == 0: + # Couldn't find a matching channel + log.debug(f"Could not convert `{arg}` to channel, no matches found.") + raise BadArgument("The provided argument returned no matches.") + + elif len(channels) > 1: + # Couldn't discern the desired channel + log.debug(f"Could not convert `{arg}` to channel, {len(channels)} matches found.") + raise BadArgument(f"The provided argument returned too many matches ({len(channels)}).") + + else: + return channels[0] + + def _snowflake_from_regex(pattern: t.Pattern, arg: str) -> int: """ Extract the snowflake from `arg` using a regex `pattern` and return it as an int. |