async def exec(ctx, *, arg): match = re.match(EXEC_REGEX, arg, flags=re.DOTALL) if match == None: await ctx.send( embed=util.error_embed("Invalid format. Expected a codeblock.")) return flags_raw = match.group(1) flags = exec_flag_parser.parse_args(flags_raw.split()) lang = flags.language or match.group(2) if not lang: await ctx.send(embed=util.error_embed( "No language specified. Use the -L flag or add a language to your codeblock." )) return lang = lang.strip() code = match.group(3) async with ctx.typing(): ok, real_lang, result, debug = await tio.run(lang, code) if not ok: await ctx.send(embed=util.error_embed(util.gen_codeblock(result), "Execution failed")) else: out = result if flags.verbose: debug_block = "\n" + util.gen_codeblock( f"""{debug}\nLanguage: {real_lang}""") out = out[:2000 - len(debug_block)] + debug_block else: out = out[:2000] await ctx.send(out)
async def sql(ctx, *, code): code = util.extract_codeblock(code) try: csr = bot.database.execute(code) out = "" async with csr as cursor: async for row in cursor: out += " ".join(map(repr, row)) + "\n" await ctx.send(util.gen_codeblock(out)) await bot.database.commit() except Exception as e: await ctx.send(embed=util.error_embed( util.gen_codeblock(traceback.format_exc())))
async def on_command_error(ctx, err): if isinstance(err, (commands.CommandNotFound, commands.CheckFailure)): return if isinstance(err, commands.CommandInvokeError) and isinstance( err.original, ValueError): return await ctx.send(embed=util.error_embed( str(err.original), title=f"Error in {ctx.invoked_with}")) # TODO: really should find a way to detect ALL user errors here? if isinstance(err, (commands.UserInputError)): return await ctx.send(embed=util.error_embed( str(err), title=f"Error in {ctx.invoked_with}")) try: command_errors.inc() trace = re.sub( "\n\n+", "\n", "\n".join(traceback.format_exception(err, err, err.__traceback__))) logging.error("Command error occured (in %s)", ctx.invoked_with, exc_info=err) await ctx.send(embed=util.error_embed( util.gen_codeblock(trace), title=f"Internal error in {ctx.invoked_with}")) await achievement.achieve(ctx.bot, ctx.message, "error") except Exception as e: logging.exception("Error in command error handling.")
async def py(ctx, *, code): "Executes Python. You may supply a codeblock. Comments in the form #timeout:([0-9]+) will be used as a timeout specifier. React with :x: to stop, probably." timeout = 5.0 timeout_match = re.search("#timeout:([0-9]+)", code, re.IGNORECASE) if timeout_match: timeout = int(timeout_match.group(1)) if timeout == 0: timeout = None code = util.extract_codeblock(code) try: loc = { **locals(), "bot": bot, "ctx": ctx, "db": bot.database, "util": util, "eventbus": eventbus } def check(re, u): return str(re.emoji) == "❌" and u == ctx.author result = None async def run(): nonlocal result result = await util.async_exec(code, loc, globals()) halt_task = asyncio.create_task( bot.wait_for("reaction_add", check=check)) exec_task = asyncio.create_task(run()) done, pending = await asyncio.wait( (exec_task, halt_task), timeout=timeout, return_when=asyncio.FIRST_COMPLETED) for task in done: task.result() # get exceptions for task in pending: task.cancel() if result != None: if isinstance(result, str): await ctx.send(result[:2000]) else: await ctx.send(util.gen_codeblock(repr(result))) except (TimeoutError, asyncio.CancelledError): await ctx.send(embed=util.error_embed("Timed out.")) except BaseException as e: await ctx.send(embed=util.error_embed( util.gen_codeblock(traceback.format_exc())))
async def py(ctx, *, code): code = util.extract_codeblock(code) try: loc = {**locals(), "bot": bot, "ctx": ctx, "db": bot.database} result = await asyncio.wait_for(util.async_exec( code, loc, globals()), timeout=5.0) if result != None: if isinstance(result, str): await ctx.send(result[:1999]) else: await ctx.send(util.gen_codeblock(repr(result))) except TimeoutError: await ctx.send(embed=util.error_embed("Timed out.")) except BaseException as e: await ctx.send(embed=util.error_embed( util.gen_codeblock(traceback.format_exc())))
async def on_command_error(ctx, err): #print(ctx, err) if isinstance(err, (commands.CommandNotFound, commands.CheckFailure)): return if isinstance(err, commands.MissingRequiredArgument): return await ctx.send(embed=util.error_embed(str(err))) try: trace = re.sub( "\n\n+", "\n", "\n".join(traceback.format_exception(err, err, err.__traceback__))) #print(trace) logging.error("command error occured (in %s)", ctx.invoked_with, exc_info=err) await ctx.send(embed=util.error_embed(util.gen_codeblock(trace), title="Internal error")) except Exception as e: print("meta-error:", e)