change things, somehow

This commit is contained in:
osmarks 2021-01-14 09:38:32 +00:00
parent 2ff9497f61
commit 6d18a5c56e
6 changed files with 97 additions and 24 deletions

View File

@ -52,7 +52,7 @@ def setup(bot):
async def achievements(ctx): pass
@achievements.command(help="Enable/disable achievement messages on this guild.")
@commands.check(util.server_mod_check(bot))
@commands.check(util.server_mod_check)
async def set_enabled(ctx, on: bool):
await bot.database.execute("INSERT OR REPLACE INTO guild_config VALUES (?, ?)", (ctx.guild.id, int(on)))
await bot.database.commit()
@ -69,4 +69,4 @@ def setup(bot):
if re.match("spect(re|er).{,20}(communism|☭)", content, re.IGNORECASE): await achieve(bot, msg, "spectre_of_communism")
if re.match(r"^(.+)\1+$", content) and len(content) >= 1950: await achieve(bot, msg, "spam")
if content_len > 30 and (len(re.findall("[\u0300-\u036f\U00040000-\U0010FFFF]", content)) / content_len) > 0.35: await achieve(bot, msg, "unicode_abuse")
if re.match("(RTFM|(read|look|view|use).{,20}(doc|man|instruction))", content, re.IGNORECASE): await achieve(bot, msg, "rtfm")
if re.match("(RTFM|(read|look|view|use).{,8}(document|man(page|ual)s?|instruction))", content, re.IGNORECASE): await achieve(bot, msg, "rtfm")

View File

@ -1,20 +1,24 @@
import util
import asyncio
import traceback
import re
from discord.ext import commands
import util
def setup(bot):
async def admin_check(ctx):
return await bot.is_owner(ctx.author)
@bot.group()
@commands.check(admin_check)
@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)
async def py(ctx, *, code):
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 = {
@ -23,13 +27,24 @@ def setup(bot):
"ctx": ctx,
"db": bot.database
}
result = await asyncio.wait_for(util.async_exec(code, loc, globals()), timeout=5.0)
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[:1999])
await ctx.send(result[:2000])
else:
await ctx.send(util.gen_codeblock(repr(result)))
except TimeoutError:
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())))
@ -51,4 +66,8 @@ def setup(bot):
@magic.command()
async def reload_config(ctx):
util.load_config()
ctx.send("Done!")
ctx.send("Done!")
@magic.command()
async def reload_ext(ctx):
for ext in util.extensions: bot.reload_extension(ext)

View File

@ -27,7 +27,7 @@ logging.basicConfig(level=logging.INFO, format="%(levelname)s %(asctime)s %(mess
#intents = discord.Intents.default()
#intents.members = True
bot = commands.Bot(command_prefix=config["prefix"], description="AutoBotRobot, the most useless bot in the known universe.",
bot = commands.Bot(command_prefix=config["prefix"], description="AutoBotRobot, the most useless bot in the known universe." + util.config.get("description_suffix", ""),
case_insensitive=True, allowed_mentions=discord.AllowedMentions(everyone=False, users=True, roles=True))
bot._skip_check = lambda x, y: False
@ -222,13 +222,8 @@ async def on_ready():
async def run_bot():
bot.database = await db.init(config["database"])
for ext in (
"reminders",
"debug",
"telephone",
"achievement",
"heavserver"
):
for ext in util.extensions:
logging.info("loaded %s", ext)
bot.load_extension(ext)
await bot.start(config["token"])

View File

@ -66,7 +66,7 @@ def setup(bot):
await asyncio.gather(*map(send_to, calls))
@telephone.command()
@commands.check(util.server_mod_check(bot))
@commands.check(util.server_mod_check)
async def setup(ctx):
num = generate_address(ctx)
await ctx.send(f"Your address is {num}.")

View File

@ -235,10 +235,11 @@ def gen_codeblock(content):
def json_encode(x): return json.dumps(x, separators=(',', ':'))
def server_mod_check(bot):
async def check(ctx):
return ctx.author.permissions_in(ctx.channel).manage_channels or (await bot.is_owner(ctx.author))
return check
async def server_mod_check(ctx):
return ctx.author.permissions_in(ctx.channel).manage_channels or (await ctx.bot.is_owner(ctx.author))
async def admin_check(ctx):
return await ctx.bot.is_owner(ctx.author)
async def get_asset(bot: commands.Bot, identifier):
safe_ident = re.sub("[^A-Za-z0-9_.-]", "_", identifier)
@ -252,4 +253,13 @@ async def get_asset(bot: commands.Bot, identifier):
return url
def hashbow(thing):
return int.from_bytes(hashlib.blake2b(thing.encode("utf-8")).digest()[:3], "little")
return int.from_bytes(hashlib.blake2b(thing.encode("utf-8")).digest()[:3], "little")
extensions = (
"reminders",
"debug",
"telephone",
"achievement",
"heavserver",
"voice"
)

49
src/voice.py Normal file
View File

@ -0,0 +1,49 @@
import util
import discord
from discord.oggparse import OggStream
# requests is for synchronous HTTP. This would be quite awful to use in the rest of the code, but is probably okay since voice code is in a separate thread
# This should, arguably, run in a separate process given python's GIL etc. but this would involve significant effort probably
import requests
import io
from discord.ext import commands
class HTTPSource(discord.AudioSource):
def __init__(self, url):
self.url = url
async def start(self):
bytestream = requests.get(self.url, stream=True).raw
self.packets = OggStream(io.BufferedReader(bytestream, buffer_size=2**10)).iter_packets()
def read(self): return next(self.packets, b"")
def is_opus(self): return True
def setup(bot):
# experimental, thus limit to me only
@bot.group()
@commands.check(util.admin_check)
async def radio(ctx): pass
@radio.command()
async def connect(ctx, thing="main"):
voice = ctx.author.voice
if not voice: return await ctx.send(embed=util.error_embed("You are not in a voice channel."))
if voice.mute: return await ctx.send(embed=util.error_embed("You are muted."))
thing_url = util.config["radio_urls"].get(thing, None)
if thing_url == None: return await ctx.send(embed=util.error_embed("No such radio thing."))
existing = ctx.guild.voice_client
if existing: await existing.disconnect()
vc = await voice.channel.connect()
src = HTTPSource(thing_url)
await src.start()
vc.play(src)
@radio.command()
async def disconnect(ctx):
if ctx.guild.voice_client:
ctx.guild.voice_client.stop()
await ctx.guild.voice_client.disconnect()
def teardown(bot):
for guild in bot.guilds:
if guild.voice_client:
guild.voice_client.stop()