diff options
Diffstat (limited to '')
| -rw-r--r-- | bot/cogs/duck_pond.py | 4 | ||||
| -rw-r--r-- | bot/cogs/python_news.py | 3 | ||||
| -rw-r--r-- | bot/cogs/reddit.py | 8 | ||||
| -rw-r--r-- | bot/cogs/watchchannels/watchchannel.py | 1 | ||||
| -rw-r--r-- | bot/utils/messages.py | 22 | ||||
| -rw-r--r-- | tests/bot/utils/test_messages.py | 27 | 
6 files changed, 57 insertions, 8 deletions
| diff --git a/bot/cogs/duck_pond.py b/bot/cogs/duck_pond.py index 37d1786a2..5b6a7fd62 100644 --- a/bot/cogs/duck_pond.py +++ b/bot/cogs/duck_pond.py @@ -7,7 +7,7 @@ from discord.ext.commands import Cog  from bot import constants  from bot.bot import Bot -from bot.utils.messages import send_attachments +from bot.utils.messages import send_attachments, sub_clyde  log = logging.getLogger(__name__) @@ -58,7 +58,7 @@ class DuckPond(Cog):          try:              await self.webhook.send(                  content=content, -                username=username, +                username=sub_clyde(username),                  avatar_url=avatar_url,                  embed=embed              ) diff --git a/bot/cogs/python_news.py b/bot/cogs/python_news.py index d15d0371e..adefd5c7c 100644 --- a/bot/cogs/python_news.py +++ b/bot/cogs/python_news.py @@ -10,6 +10,7 @@ from discord.ext.tasks import loop  from bot import constants  from bot.bot import Bot +from bot.utils.messages import sub_clyde  PEPS_RSS_URL = "https://www.python.org/dev/peps/peps.rss/" @@ -208,7 +209,7 @@ class PythonNews(Cog):          return await self.webhook.send(              embed=embed, -            username=webhook_profile_name, +            username=sub_clyde(webhook_profile_name),              avatar_url=AVATAR_URL,              wait=True          ) diff --git a/bot/cogs/reddit.py b/bot/cogs/reddit.py index 3b77538a0..d853ab2ea 100644 --- a/bot/cogs/reddit.py +++ b/bot/cogs/reddit.py @@ -16,6 +16,7 @@ from bot.constants import Channels, ERROR_REPLIES, Emojis, Reddit as RedditConfi  from bot.converters import Subreddit  from bot.decorators import with_role  from bot.pagination import LinePaginator +from bot.utils.messages import sub_clyde  log = logging.getLogger(__name__) @@ -218,7 +219,8 @@ class Reddit(Cog):          for subreddit in RedditConfig.subreddits:              top_posts = await self.get_top_posts(subreddit=subreddit, time="day") -            message = await self.webhook.send(username=f"{subreddit} Top Daily Posts", embed=top_posts, wait=True) +            username = sub_clyde(f"{subreddit} Top Daily Posts") +            message = await self.webhook.send(username=username, embed=top_posts, wait=True)              if message.channel.is_news():                  await message.publish() @@ -228,8 +230,8 @@ class Reddit(Cog):          for subreddit in RedditConfig.subreddits:              # Send and pin the new weekly posts.              top_posts = await self.get_top_posts(subreddit=subreddit, time="week") - -            message = await self.webhook.send(wait=True, username=f"{subreddit} Top Weekly Posts", embed=top_posts) +            username = sub_clyde(f"{subreddit} Top Weekly Posts") +            message = await self.webhook.send(wait=True, username=username, embed=top_posts)              if subreddit.lower() == "r/python":                  if not self.channel: diff --git a/bot/cogs/watchchannels/watchchannel.py b/bot/cogs/watchchannels/watchchannel.py index 436778c46..7c58a0fb5 100644 --- a/bot/cogs/watchchannels/watchchannel.py +++ b/bot/cogs/watchchannels/watchchannel.py @@ -204,6 +204,7 @@ class WatchChannel(metaclass=CogABCMeta):          embed: Optional[Embed] = None,      ) -> None:          """Sends a message to the webhook with the specified kwargs.""" +        username = messages.sub_clyde(username)          try:              await self.webhook.send(content=content, username=username, avatar_url=avatar_url, embed=embed)          except discord.HTTPException as exc: diff --git a/bot/utils/messages.py b/bot/utils/messages.py index 23519a514..a40a12e98 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -1,6 +1,7 @@  import asyncio  import contextlib  import logging +import re  from io import BytesIO  from typing import List, Optional, Sequence, Union @@ -86,7 +87,7 @@ async def send_attachments(                      else:                          await destination.send(                              file=attachment_file, -                            username=message.author.display_name, +                            username=sub_clyde(message.author.display_name),                              avatar_url=message.author.avatar_url                          )              elif link_large: @@ -109,8 +110,25 @@ async def send_attachments(          else:              await destination.send(                  embed=embed, -                username=message.author.display_name, +                username=sub_clyde(message.author.display_name),                  avatar_url=message.author.avatar_url              )      return urls + + +def sub_clyde(username: Optional[str]) -> Optional[str]: +    """ +    Replace "e"/"E" in any "clyde" in `username` with a Cyrillic "е"/"E" and return the new string. + +    Discord disallows "clyde" anywhere in the username for webhooks. It will return a 400. +    Return None only if `username` is None. +    """ +    def replace_e(match: re.Match) -> str: +        char = "е" if match[2] == "e" else "Е" +        return match[1] + char + +    if username: +        return re.sub(r"(clyd)(e)", replace_e, username, flags=re.I) +    else: +        return username  # Empty string or None diff --git a/tests/bot/utils/test_messages.py b/tests/bot/utils/test_messages.py new file mode 100644 index 000000000..9c22c9751 --- /dev/null +++ b/tests/bot/utils/test_messages.py @@ -0,0 +1,27 @@ +import unittest + +from bot.utils import messages + + +class TestMessages(unittest.TestCase): +    """Tests for functions in the `bot.utils.messages` module.""" + +    def test_sub_clyde(self): +        """Uppercase E's and lowercase e's are substituted with their cyrillic counterparts.""" +        sub_e = "\u0435" +        sub_E = "\u0415"  # noqa: N806: Uppercase E in variable name + +        test_cases = ( +            (None, None), +            ("", ""), +            ("clyde", f"clyd{sub_e}"), +            ("CLYDE", f"CLYD{sub_E}"), +            ("cLyDe", f"cLyD{sub_e}"), +            ("BIGclyde", f"BIGclyd{sub_e}"), +            ("small clydeus the unholy", f"small clyd{sub_e}us the unholy"), +            ("BIGCLYDE, babyclyde", f"BIGCLYD{sub_E}, babyclyd{sub_e}"), +        ) + +        for username_in, username_out in test_cases: +            with self.subTest(input=username_in, expected_output=username_out): +                self.assertEqual(messages.sub_clyde(username_in), username_out) | 
