1
0
mirror of https://github.com/osmarks/autobotrobot synced 2024-06-17 18:49:58 +00:00
autobotrobot/src/debug.py
ubq323 3c3ffbb036 add tel searchrecent and tel delrecent commands
these look through all discord channels bridged to the given channel
(including that channel itself) and search for messages matching
the given query. the delrecent command, after asking for confirmation,
will then delete all of those messages that it can across all the channels.
it is capable of deleting messages sent by our own webhooks even if
we don't have manage message permissions in the channel in question.

the user interface is not amazing but these are both extpriv-only and
only send any outputs in dms so this probably isn't very important.
2022-01-18 23:58:39 +00:00

82 lines
3.2 KiB
Python

import asyncio
import traceback
import re
from discord.ext import commands
import util
import eventbus
def setup(bot):
@bot.group(help="Debug/random messing around utilities. Owner-only.")
@commands.check(util.admin_check)
async def magic(ctx):
if ctx.invoked_subcommand == None:
return await ctx.send("Invalid magic command.")
@magic.command(rest_is_raw=True, brief="Execute Python.")
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())))
@magic.command(rest_is_raw=True, help="Execute SQL code against the database.")
async def sql(ctx, *, code):
"Executes SQL (and commits). You may use a codeblock, similarly to with py."
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())))
@magic.command(help="Reload configuration file.")
async def reload_config(ctx):
util.load_config()
await ctx.send("Done!")
@magic.command(help="Reload extensions (all or the specified one).")
async def reload_ext(ctx, ext="all"):
if ext == "all":
for ext in util.extensions: bot.reload_extension(ext)
else: bot.reload_extension(ext)
await ctx.send("Done!")