diff options
| -rw-r--r-- | bot/cogs/bot.py | 104 | 
1 files changed, 66 insertions, 38 deletions
diff --git a/bot/cogs/bot.py b/bot/cogs/bot.py index 2663b79a8..a29aff9d5 100644 --- a/bot/cogs/bot.py +++ b/bot/cogs/bot.py @@ -1,5 +1,6 @@  # coding=utf-8  import ast +import re  import time  from discord import Embed, Message @@ -22,11 +23,11 @@ class Bot:          self.bot = bot          # Stores allowed channels plus unix timestamp from last call -        self.previous_format_times = {HELP1_CHANNEL: 0, -                                      HELP2_CHANNEL: 0, -                                      HELP3_CHANNEL: 0, -                                      PYTHON_CHANNEL: 0, -                                      DEVTEST_CHANNEL: 0 +        self.channel_cooldowns = {HELP1_CHANNEL: 0, +                                  HELP2_CHANNEL: 0, +                                  HELP3_CHANNEL: 0, +                                  PYTHON_CHANNEL: 0, +                                  DEVTEST_CHANNEL: 0          }  # noqa. E124      @group(invoke_without_command=True, name="bot", hidden=True) @@ -73,40 +74,67 @@ class Bot:          await ctx.invoke(self.info) +    def codeblock_stripping(self, msg: str): +        """ +        Strip msg in order to find Python code. + +        Tries to strip out Python code out of msg and returns the stripped block or +        None if the block is a valid Python codeblock. +        """ +        if msg.count("\n") >= 3: +            # Filtering valid Python codeblocks and exiting if a valid Python codeblock is found +            if re.search("```(python|py)\n((?:.*\n*)+)```", msg, re.IGNORECASE): +                return None +            else: +                # Stripping backticks from every line of the message. +                content = "" +                for line in msg.splitlines(): +                    content += line.strip("`") + "\n" + +                content = content.strip() + +                # Remove "Python" or "Py" from top of the message if exists +                if content.lower().startswith("python"): +                    content = content[6:] +                elif content.lower().startswith("py"): +                    content = content[2:] + +                # Strip again to remove the whitespace(s) left before the code +                # If the msg looked like "Python <code>" before removing Python +                content = content.strip() +                return content +      async def on_message(self, msg: Message): -        if msg.channel.id in self.previous_format_times: -            if time.time()-self.previous_format_times[msg.channel.id] > 300 or msg.channel.id == DEVTEST_CHANNEL: -                if msg.content.count("\n") >= 3: -                    try: -                        # Some users formatted multi-line code using `'sip(" -                        # This fixes that by treating them as nothing. -                        if "`" in msg.content: -                            msg.content = msg.content[:-1][1:] -                        tree = ast.parse(msg.content) - -                        # Attempts to parse the message into an AST node. -                        # Invalid Python code will raise a SyntaxError. -                        if not all(isinstance(node, ast.Expr) for node in tree.body): - -                            # Multiple lines of single words could be interpreted as expressions. -                            # This check is to avoid all nodes being parsed as expressions. -                            # (e.g. words over multiple lines) -                            howto = ("Please use syntax highlighted blocks, as it makes " -                                     "your code more legible for other users.\n" -                                     "\nTo do this, you should input your content like this:\n" -                                     "\n\`\`\`python\n" -                                     "print(\"Hello world!\")\n" -                                     "\`\`\`\n" -                                     "\nThis will result in the following:\n" -                                     "```python\n" -                                     "print(\"Hello world!\")" -                                     "```" -                            )  # noqa. E124 -                            information = Embed(title="Code formatting", description=howto) -                            await msg.channel.send(embed=information) -                            self.previous_format_times[msg.channel.id] = time.time() -                    except SyntaxError: -                        pass +        if msg.channel.id in self.channel_cooldowns: +            on_cooldown = time.time() - self.channel_cooldowns[msg.channel.id] < 300 +            if not on_cooldown or msg.channel.id == DEVTEST_CHANNEL: +                try: +                    content = self.codeblock_stripping(msg.content) +                    if not content: +                        return + +                    # Attempts to parse the message into an AST node. +                    # Invalid Python code will raise a SyntaxError. +                    tree = ast.parse(content) + +                    # Multiple lines of single words could be interpreted as expressions. +                    # This check is to avoid all nodes being parsed as expressions. +                    # (e.g. words over multiple lines) +                    if not all(isinstance(node, ast.Expr) for node in tree.body): +                        codeblock_tag = await self.bot.get_cog("Tags").get_tag_data("codeblock") +                        if codeblock_tag == {}: +                            # todo: add logging +                            return +                        howto = (f"Hey {msg.author.mention}!\n\n" +                                 "I noticed you were trying to paste code into this channel.\n\n" +                                 f"{codeblock_tag['tag_content']}") + +                        howto_embed = Embed(description=howto) +                        await msg.channel.send(embed=howto_embed) +                        self.channel_cooldowns[msg.channel.id] = time.time() +                except SyntaxError: +                    # todo: add logging +                    pass  def setup(bot):  |