From 160bf89303436e3ba0ff566241a206a120a25d66 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Tue, 9 Feb 2021 13:37:28 +0300 Subject: Moves Off Topic Name Translator Breaks out the off topic name translation functionality into its own function. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/converters.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 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): -- cgit v1.2.3 From 66cda4fd2a0b26e2f9e983f1597a15bfb9527143 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Tue, 9 Feb 2021 13:38:12 +0300 Subject: Makes Off Topic Name Search Case Insensitive Modifies the off topic channel name search to match upper and lower cased letters, as well as punctuation. Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/exts/fun/off_topic_names.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) 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() -- cgit v1.2.3 From 0b11d7dfb408f4e5fe6248ae8377ddc7aa1aa5ee Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 03:48:35 +0100 Subject: Add truncate_message util --- bot/utils/messages.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bot/utils/messages.py b/bot/utils/messages.py index 077dd9569..c01fa5d0e 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -154,3 +154,12 @@ async def send_denial(ctx: Context, reason: str) -> None: def format_user(user: discord.abc.User) -> str: """Return a string for `user` which has their mention and ID.""" return f"{user.mention} (`{user.id}`)" + + +def truncate_message(message: discord.Message, limit: int) -> str: + """Returns a truncated version of the message content, up to the specified limit.""" + text = message.content + if len(text) > limit: + return text[:limit-3] + "..." + else: + return text -- cgit v1.2.3 From e1d269d82eed8a01d3d3b0ff33d05e3c79324007 Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 04:00:01 +0100 Subject: Add function to DM users when opening help channel --- bot/exts/help_channels/_message.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/bot/exts/help_channels/_message.py b/bot/exts/help_channels/_message.py index 2bbd4bdd6..12ac4035d 100644 --- a/bot/exts/help_channels/_message.py +++ b/bot/exts/help_channels/_message.py @@ -8,6 +8,7 @@ import bot from bot import constants from bot.exts.help_channels import _caches from bot.utils.channel import is_in_category +from bot.utils.messages import truncate_message log = logging.getLogger(__name__) @@ -92,6 +93,38 @@ async def is_empty(channel: discord.TextChannel) -> bool: return False +async def dm_on_open(message: discord.Message) -> None: + """ + DM claimant with a link to the claimed channel's first message, with a 100 letter preview of the message. + + Does nothing if the user has DMs disabled. + """ + embed = discord.Embed( + title="Help channel opened", + description=f"You claimed {message.channel.mention}.", + colour=bot.constants.Colours.bright_green, + timestamp=message.created_at, + ) + + embed.set_thumbnail(url=constants.Icons.green_questionmark) + embed.add_field( + name="Your message", value=truncate_message(message, limit=100), inline=False + ) + embed.add_field( + name="Want to go there?", + value=f"[Jump to message!]({message.jump_url})", + inline=False, + ) + + try: + await message.author.send(embed=embed) + log.trace(f"Sent DM to {message.author.id} after claiming help channel.") + except discord.errors.Forbidden: + log.trace( + f"Ignoring to send DM to {message.author.id} after claiming help channel: DMs disabled." + ) + + async def notify(channel: discord.TextChannel, last_notification: t.Optional[datetime]) -> t.Optional[datetime]: """ Send a message in `channel` notifying about a lack of available help channels. -- cgit v1.2.3 From e6483d633ac6ecc2a88051442108d9c88e5f7745 Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 04:00:58 +0100 Subject: Add green question mark to default config Add green question mark to default config Add green question mark to config --- bot/constants.py | 1 + config-default.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/bot/constants.py b/bot/constants.py index 8a93ff9cf..69bc82b89 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -326,6 +326,7 @@ class Icons(metaclass=YAMLGetter): filtering: str green_checkmark: str + green_questionmark: str guild_update: str hash_blurple: str diff --git a/config-default.yml b/config-default.yml index 8e9a29a51..7d9afaa0e 100644 --- a/config-default.yml +++ b/config-default.yml @@ -90,6 +90,7 @@ style: filtering: "https://cdn.discordapp.com/emojis/472472638594482195.png" green_checkmark: "https://raw.githubusercontent.com/python-discord/branding/master/icons/checkmark/green-checkmark-dist.png" + green_questionmark: "https://raw.githubusercontent.com/python-discord/branding/master/icons/checkmark/green-question-mark-dist.png" guild_update: "https://cdn.discordapp.com/emojis/469954765141442561.png" hash_blurple: "https://cdn.discordapp.com/emojis/469950142942806017.png" -- cgit v1.2.3 From e34ea2f1c108d1900e251d17b38563536345d2de Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 04:07:05 +0100 Subject: Send DM when user claims help channel --- bot/exts/help_channels/_cog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/exts/help_channels/_cog.py b/bot/exts/help_channels/_cog.py index 0995c8a79..a18ddc900 100644 --- a/bot/exts/help_channels/_cog.py +++ b/bot/exts/help_channels/_cog.py @@ -102,6 +102,7 @@ class HelpChannels(commands.Cog): await _cooldown.revoke_send_permissions(message.author, self.scheduler) await _message.pin(message) + await _message.dm_on_open(message) # Add user with channel for dormant check. await _caches.claimants.set(message.channel.id, message.author.id) -- cgit v1.2.3 From bb9e56c3cb874ef76ab82db02ce8242117e0da92 Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 11:08:41 +0100 Subject: Update embed field title to be more formal --- bot/exts/help_channels/_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/help_channels/_message.py b/bot/exts/help_channels/_message.py index 12ac4035d..95aca067a 100644 --- a/bot/exts/help_channels/_message.py +++ b/bot/exts/help_channels/_message.py @@ -111,7 +111,7 @@ async def dm_on_open(message: discord.Message) -> None: name="Your message", value=truncate_message(message, limit=100), inline=False ) embed.add_field( - name="Want to go there?", + name="Conversation", value=f"[Jump to message!]({message.jump_url})", inline=False, ) -- cgit v1.2.3 From cae0d84757e026976f1a9e87d52c581669b7b8e8 Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 11:14:31 +0100 Subject: Use textwrap.shorten instead of custom function This applies to the help channel DM embed, where the user is sent a truncated version of their message. --- bot/exts/help_channels/_message.py | 6 ++++-- bot/utils/messages.py | 9 --------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/bot/exts/help_channels/_message.py b/bot/exts/help_channels/_message.py index 95aca067a..4113e51c5 100644 --- a/bot/exts/help_channels/_message.py +++ b/bot/exts/help_channels/_message.py @@ -1,4 +1,5 @@ import logging +import textwrap import typing as t from datetime import datetime @@ -8,7 +9,6 @@ import bot from bot import constants from bot.exts.help_channels import _caches from bot.utils.channel import is_in_category -from bot.utils.messages import truncate_message log = logging.getLogger(__name__) @@ -108,7 +108,9 @@ async def dm_on_open(message: discord.Message) -> None: embed.set_thumbnail(url=constants.Icons.green_questionmark) embed.add_field( - name="Your message", value=truncate_message(message, limit=100), inline=False + name="Your message", + value=textwrap.shorten(message.content, width=100, placeholder="..."), + inline=False, ) embed.add_field( name="Conversation", diff --git a/bot/utils/messages.py b/bot/utils/messages.py index c01fa5d0e..077dd9569 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -154,12 +154,3 @@ async def send_denial(ctx: Context, reason: str) -> None: def format_user(user: discord.abc.User) -> str: """Return a string for `user` which has their mention and ID.""" return f"{user.mention} (`{user.id}`)" - - -def truncate_message(message: discord.Message, limit: int) -> str: - """Returns a truncated version of the message content, up to the specified limit.""" - text = message.content - if len(text) > limit: - return text[:limit-3] + "..." - else: - return text -- cgit v1.2.3 From d71ac9f6e240ffd2d4195d9dbbf5740a0c2413a1 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Tue, 23 Feb 2021 19:24:18 +0300 Subject: Fixes Problems With Help Channel DM Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/exts/help_channels/_cog.py | 5 ++++- bot/exts/help_channels/_message.py | 8 +++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/bot/exts/help_channels/_cog.py b/bot/exts/help_channels/_cog.py index a18ddc900..6abf99810 100644 --- a/bot/exts/help_channels/_cog.py +++ b/bot/exts/help_channels/_cog.py @@ -102,7 +102,10 @@ class HelpChannels(commands.Cog): await _cooldown.revoke_send_permissions(message.author, self.scheduler) await _message.pin(message) - await _message.dm_on_open(message) + try: + await _message.dm_on_open(message) + except Exception as e: + log.warning("Error occurred while sending DM:", exc_info=e) # Add user with channel for dormant check. await _caches.claimants.set(message.channel.id, message.author.id) diff --git a/bot/exts/help_channels/_message.py b/bot/exts/help_channels/_message.py index 4113e51c5..36388f9bd 100644 --- a/bot/exts/help_channels/_message.py +++ b/bot/exts/help_channels/_message.py @@ -107,11 +107,9 @@ async def dm_on_open(message: discord.Message) -> None: ) embed.set_thumbnail(url=constants.Icons.green_questionmark) - embed.add_field( - name="Your message", - value=textwrap.shorten(message.content, width=100, placeholder="..."), - inline=False, - ) + formatted_message = textwrap.shorten(message.content, width=100, placeholder="...") + if formatted_message: + embed.add_field(name="Your message", value=formatted_message, inline=False) embed.add_field( name="Conversation", value=f"[Jump to message!]({message.jump_url})", -- cgit v1.2.3 From 44eb00ca03dae1b3d5faf40be63fae04ca515790 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Wed, 24 Feb 2021 18:27:25 +0100 Subject: Add off-topic etiquette to the off-topic tag --- bot/resources/tags/off-topic.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bot/resources/tags/off-topic.md b/bot/resources/tags/off-topic.md index c7f98a813..6a864a1d5 100644 --- a/bot/resources/tags/off-topic.md +++ b/bot/resources/tags/off-topic.md @@ -6,3 +6,5 @@ There are three off-topic channels: โ€ข <#463035268514185226> Their names change randomly every 24 hours, but you can always find them under the `OFF-TOPIC/GENERAL` category in the channel list. + +Please read our [off-topic etiquette](https://pythondiscord.com/pages/resources/guides/off-topic-etiquette/) before participating in conversations. -- cgit v1.2.3