aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/cogs/snekbox.py78
1 files changed, 51 insertions, 27 deletions
diff --git a/bot/cogs/snekbox.py b/bot/cogs/snekbox.py
index da33e27b2..1688c0278 100644
--- a/bot/cogs/snekbox.py
+++ b/bot/cogs/snekbox.py
@@ -1,3 +1,4 @@
+import asyncio
import datetime
import logging
import re
@@ -36,6 +37,8 @@ RAW_CODE_REGEX = re.compile(
MAX_PASTE_LEN = 1000
EVAL_ROLES = (Roles.helpers, Roles.moderator, Roles.admin, Roles.owner, Roles.rockstars, Roles.partners)
+SIGKILL = 9
+
class Snekbox(Cog):
"""Safe evaluation of Python code using Snekbox."""
@@ -101,7 +104,7 @@ class Snekbox(Cog):
if returncode is None:
msg = "Your eval job has failed"
error = stdout.strip()
- elif returncode == 128 + Signals.SIGKILL:
+ elif returncode == 128 + SIGKILL:
msg = "Your eval job timed out or ran out of memory"
elif returncode == 255:
msg = "Your eval job has failed"
@@ -135,7 +138,7 @@ class Snekbox(Cog):
"""
log.trace("Formatting output...")
- output = output.strip(" \n")
+ output = output.rstrip("\n")
original_output = output # To be uploaded to a pasting service if needed
paste_link = None
@@ -152,7 +155,7 @@ class Snekbox(Cog):
lines = output.count("\n")
if lines > 0:
- output = output.split("\n")[:10] # Only first 10 cause the rest is truncated anyway
+ output = output.split("\n")[:11] # Only first 11 cause the rest is truncated anyway
output = (f"{i:03d} | {line}" for i, line in enumerate(output, 1))
output = "\n".join(output)
@@ -169,7 +172,6 @@ class Snekbox(Cog):
if truncated:
paste_link = await self.upload_output(original_output)
- output = output.strip()
if not output:
output = "[No output]"
@@ -199,32 +201,54 @@ class Snekbox(Cog):
log.info(f"Received code from {ctx.author} for evaluation:\n{code}")
- self.jobs[ctx.author.id] = datetime.datetime.now()
- code = self.prepare_input(code)
+ while True:
+ self.jobs[ctx.author.id] = datetime.datetime.now()
+ code = self.prepare_input(code)
- try:
- async with ctx.typing():
- results = await self.post_eval(code)
- msg, error = self.get_results_message(results)
-
- if error:
- output, paste_link = error, None
- else:
- output, paste_link = await self.format_output(results["stdout"])
-
- icon = self.get_status_emoji(results)
- msg = f"{ctx.author.mention} {icon} {msg}.\n\n```py\n{output}\n```"
- if paste_link:
- msg = f"{msg}\nFull output: {paste_link}"
-
- response = await ctx.send(msg)
- self.bot.loop.create_task(
- wait_for_deletion(response, user_ids=(ctx.author.id,), client=ctx.bot)
+ try:
+ async with ctx.typing():
+ results = await self.post_eval(code)
+ msg, error = self.get_results_message(results)
+
+ if error:
+ output, paste_link = error, None
+ else:
+ output, paste_link = await self.format_output(results["stdout"])
+
+ icon = self.get_status_emoji(results)
+ msg = f"{ctx.author.mention} {icon} {msg}.\n\n```py\n{output}\n```"
+ if paste_link:
+ msg = f"{msg}\nFull output: {paste_link}"
+
+ response = await ctx.send(msg)
+ self.bot.loop.create_task(
+ wait_for_deletion(response, user_ids=(ctx.author.id,), client=ctx.bot)
+ )
+
+ log.info(f"{ctx.author}'s job had a return code of {results['returncode']}")
+ finally:
+ del self.jobs[ctx.author.id]
+
+ try:
+ _, new_message = await self.bot.wait_for(
+ 'message_edit',
+ check=lambda o, n: n.id == ctx.message.id and o.content != n.content,
+ timeout=10
+ )
+ await ctx.message.add_reaction('🔁')
+ await self.bot.wait_for(
+ 'reaction_add',
+ check=lambda r, u: r.message.id == ctx.message.id and u.id == ctx.author.id and str(r) == '🔁',
+ timeout=10
)
- log.info(f"{ctx.author}'s job had a return code of {results['returncode']}")
- finally:
- del self.jobs[ctx.author.id]
+ log.info(f"Re-evaluating message {ctx.message.id}")
+ code = new_message.content.split(' ', maxsplit=1)[1]
+ await ctx.message.clear_reactions()
+ await response.delete()
+ except asyncio.TimeoutError:
+ await ctx.message.clear_reactions()
+ return
def setup(bot: Bot) -> None: