1
0
mirror of https://github.com/osmarks/autobotrobot synced 2024-06-13 16:56:54 +00:00
autobotrobot/src/main.py

129 lines
4.1 KiB
Python
Raw Normal View History

2019-10-21 20:07:17 +00:00
import discord
import toml
import logging
import subprocess
import discord.ext.commands as commands
import re
import asyncio
import json
import tio
data = {}
data_file = "bot-data.json"
def save_data():
try:
with open(data_file, "w") as f:
global data
json.dump(data, f)
except Exception as e:
logging.error(f"Error saving data file: {repr(e)}.")
def load_data():
try:
with open(data_file, "r") as f:
global data
data = json.load(f)
except Exception as e:
logging.warning(f"Error loading data file: {repr(e)}. This is not a critical error.")
load_data()
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(asctime)s %(message)s", datefmt="%H:%M:%S %d/%m/%Y")
config = toml.load(open("config.toml", "r"))
bot = commands.Bot(command_prefix='++', description="AutoBotRobot, the most useless bot in the known universe.", case_insensitive=True)
bot._skip_check = lambda x, y: False
cleaner = discord.ext.commands.clean_content()
def clean(ctx, text):
return cleaner.convert(ctx, text)
@bot.event
async def on_ready():
await bot.change_presence(status=discord.Status.online, activity=discord.Activity(type=discord.ActivityType.listening, name="commands beginning with ++"))
@bot.event
async def on_message(message):
print(message.content)
await bot.process_commands(message)
@bot.command(help="Gives you a random fortune as generated by `fortune`.")
async def fortune(ctx):
await ctx.send(subprocess.run(["fortune"], stdout=subprocess.PIPE, encoding="UTF-8").stdout)
@bot.command(help="Says Pong.")
async def ping(ctx):
await ctx.send("Pong.")
@bot.command(help="Deletes the specified target.", rest_is_raw=True)
async def delete(ctx, *, raw_target):
target = await clean(ctx, raw_target.strip())
async with ctx.typing():
await ctx.send(f"Deleting {target}...")
await asyncio.sleep(1)
deleted = data.get("deleted", [])
data["deleted"] = deleted + [target]
save_data()
await ctx.send(f"Deleted {target} successfully.")
@bot.command(help="View recently deleted things, optionally matching a filter.")
async def list_deleted(ctx, search=None):
acc = "Recently deleted:\n"
for thing in reversed(data.get("deleted", [])):
to_add = "- " + thing + "\n"
if len(acc + to_add) > 2000:
break
if search == None or search in thing: acc += to_add
await ctx.send(acc)
EXEC_REGEX = "^(.*)\n```([a-zA-Z0-9_\\-+]+)\n(.*)```$"
def make_embed(*, fields=[], footer_text=None, **kwargs):
embed = discord.Embed(**kwargs)
for field in fields:
if len(field) > 2:
embed.add_field(name=field[0], value=field[1], inline=field[2])
else:
embed.add_field(name=field[0], value=field[1], inline=False)
if footer_text:
embed.set_footer(text=footer_text)
return embed
def error_embed(msg, title="Error"):
return make_embed(color=config["colors"]["error"], description=msg, title=title)
@bot.command(rest_is_raw=True, help="Execute provided code (in a codeblock) using TIO.run.")
async def exec(ctx, *, arg):
match = re.match(EXEC_REGEX, arg, flags=re.DOTALL)
if match == None:
await ctx.send(embed=error_embed("Invalid format. Expected a codeblock with language."))
return
flags = match.group(1)
lang = match.group(2)
code = match.group(3)
async with ctx.typing():
ok, result, debug = await tio.run(lang, code)
if not ok:
await ctx.send(embed=error_embed(result, "Execution error"))
else:
out = result
if "debug" in flags: out += debug
out = out[:2000]
await ctx.send(out)
@bot.command(help="List supported languages, optionally matching a filter.")
async def supported_langs(ctx, search=None):
langs = sorted(tio.languages())
acc = ""
for lang in langs:
if len(acc + lang) > 2000:
await ctx.send(acc)
acc = ""
if search == None or search in lang: acc += lang + " "
await ctx.send(acc)
bot.run(config["token"])