diff options
| author | 2021-02-25 10:37:18 +0100 | |
|---|---|---|
| committer | 2021-02-25 10:37:18 +0100 | |
| commit | c4cd7a59e66e513a7b4706ac5cfeefaa68ff223f (patch) | |
| tree | 1e0f29a5c1a919668f3847d9b8b231d2cf177e57 | |
| parent | Merge pull request #1433 from python-discord/etiquette-off-topic-tag (diff) | |
| parent | Merge branch 'master' into insensitive-otn-search (diff) | |
Merge pull request #1409 from HassanAbouelela/insensitive-otn-search
Makes Off Topic Name Search Insensitive
| -rw-r--r-- | bot/converters.py | 25 | ||||
| -rw-r--r-- | bot/exts/fun/off_topic_names.py | 18 | 
2 files changed, 32 insertions, 11 deletions
| diff --git a/bot/converters.py b/bot/converters.py index 0d9a519df..80ce99459 100644 --- a/bot/converters.py +++ b/bot/converters.py @@ -357,27 +357,38 @@ class Duration(DurationDelta):  class OffTopicName(Converter):      """A converter that ensures an added off-topic name is valid.""" +    ALLOWED_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!?'`-" + +    @classmethod +    def translate_name(cls, name: str, *, from_unicode: bool = True) -> str: +        """ +        Translates `name` into a format that is allowed in discord channel names. + +        If `from_unicode` is True, the name is translated from a discord-safe format, back to normalized text. +        """ +        if from_unicode: +            table = str.maketrans(cls.ALLOWED_CHARACTERS, '๐ ๐ก๐ข๐ฃ๐ค๐ฅ๐ฆ๐ง๐จ๐ฉ๐ช๐ซ๐ฌ๐ญ๐ฎ๐ฏ๐ฐ๐ฑ๐ฒ๐ณ๐ด๐ต๐ถ๐ท๐ธ๐นว๏ผโโ-') +        else: +            table = str.maketrans('๐ ๐ก๐ข๐ฃ๐ค๐ฅ๐ฆ๐ง๐จ๐ฉ๐ช๐ซ๐ฌ๐ญ๐ฎ๐ฏ๐ฐ๐ฑ๐ฒ๐ณ๐ด๐ต๐ถ๐ท๐ธ๐นว๏ผโโ-', cls.ALLOWED_CHARACTERS) + +        return name.translate(table) +      async def convert(self, ctx: Context, argument: str) -> str:          """Attempt to replace any invalid characters with their approximate Unicode equivalent.""" -        allowed_characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!?'`-" -          # Chain multiple words to a single one          argument = "-".join(argument.split())          if not (2 <= len(argument) <= 96):              raise BadArgument("Channel name must be between 2 and 96 chars long") -        elif not all(c.isalnum() or c in allowed_characters for c in argument): +        elif not all(c.isalnum() or c in self.ALLOWED_CHARACTERS for c in argument):              raise BadArgument(                  "Channel name must only consist of "                  "alphanumeric characters, minus signs or apostrophes."              )          # Replace invalid characters with unicode alternatives. -        table = str.maketrans( -            allowed_characters, '๐ ๐ก๐ข๐ฃ๐ค๐ฅ๐ฆ๐ง๐จ๐ฉ๐ช๐ซ๐ฌ๐ญ๐ฎ๐ฏ๐ฐ๐ฑ๐ฒ๐ณ๐ด๐ต๐ถ๐ท๐ธ๐นว๏ผโโ-' -        ) -        return argument.translate(table) +        return self.translate_name(argument)  class ISODateTime(Converter): diff --git a/bot/exts/fun/off_topic_names.py b/bot/exts/fun/off_topic_names.py index 7fc93b88c..845b8175c 100644 --- a/bot/exts/fun/off_topic_names.py +++ b/bot/exts/fun/off_topic_names.py @@ -139,10 +139,20 @@ class OffTopicNames(Cog):      @has_any_role(*MODERATION_ROLES)      async def search_command(self, ctx: Context, *, query: OffTopicName) -> None:          """Search for an off-topic name.""" -        result = await self.bot.api_client.get('bot/off-topic-channel-names') -        in_matches = {name for name in result if query in name} -        close_matches = difflib.get_close_matches(query, result, n=10, cutoff=0.70) -        lines = sorted(f"โข {name}" for name in in_matches.union(close_matches)) +        query = OffTopicName.translate_name(query, from_unicode=False).lower() + +        # Map normalized names to returned names for search purposes +        result = { +            OffTopicName.translate_name(name, from_unicode=False).lower(): name +            for name in await self.bot.api_client.get('bot/off-topic-channel-names') +        } + +        # Search normalized keys +        in_matches = {name for name in result.keys() if query in name} +        close_matches = difflib.get_close_matches(query, result.keys(), n=10, cutoff=0.70) + +        # Send Results +        lines = sorted(f"โข {result[name]}" for name in in_matches.union(close_matches))          embed = Embed(              title="Query results",              colour=Colour.blue() | 
