aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/cogs/bot.py104
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):