ryuko-ng/cogs/admin.py
2018-12-23 16:25:34 +03:00

177 lines
6.4 KiB
Python

import discord
from discord.ext import commands
import traceback
import inspect
import re
import config
class AdminCog:
def __init__(self, bot):
self.bot = bot
self.last_eval_result = None
self.previous_eval_code = None
def check_if_staff(ctx):
return any(r.id in config.staff_role_ids for r in ctx.author.roles)
def check_if_bot_manager(ctx):
return any(r.id == config.bot_manager_role_id for r in ctx.author.roles)
@commands.check(check_if_staff)
@commands.command(aliases=['echo'], hidden=True)
async def say(self, ctx, *, the_text: str):
"""Repeats a given text, staff only."""
await ctx.send(the_text)
@commands.check(check_if_bot_manager)
@commands.command(name='exit', hidden=True)
async def _exit(self, ctx):
"""Shuts down the bot, bot manager only."""
await ctx.send(":wave: Exiting bot, goodbye!")
await self.bot.logout()
@commands.check(check_if_bot_manager)
@commands.command(hidden=True)
async def load(self, ctx, ext: str):
"""Loads a cog, bot manager only."""
try:
self.bot.load_extension("cogs." + ext)
except:
await ctx.send(f':x: Cog loading failed, traceback: '
f'```\n{traceback.format_exc()}\n```')
return
self.bot.log.info(f'Loaded ext {ext}')
await ctx.send(f':white_check_mark: `{ext}` successfully loaded.')
@commands.check(check_if_bot_manager)
@commands.command(hidden=True)
async def fetchlog(self, ctx):
"""Returns log"""
await ctx.send(file=discord.File(f"{self.bot.script_name}.log"),
content="Here's the current log file:")
@commands.check(check_if_bot_manager)
@commands.command(name='eval', hidden=True)
async def _eval(self, ctx, *, code: str):
"""Evaluates some code, bot manager only."""
try:
code = code.strip('` ')
env = {
'bot': self.bot,
'ctx': ctx,
'message': ctx.message,
'server': ctx.guild,
'guild': ctx.guild,
'channel': ctx.message.channel,
'author': ctx.message.author,
# modules
'discord': discord,
'commands': commands,
# utilities
'_get': discord.utils.get,
'_find': discord.utils.find,
# last result
'_': self.last_eval_result,
'_p': self.previous_eval_code,
}
env.update(globals())
self.bot.log.info(f"Evaling {repr(code)}:")
result = eval(code, env)
if inspect.isawaitable(result):
result = await result
if result is not None:
self.last_eval_result = result
self.previous_eval_code = code
sliced_message = await self.bot.slice_message(repr(result),
prefix="```",
suffix="```")
for msg in sliced_message:
await ctx.send(msg)
except:
sliced_message = \
await self.bot.slice_message(traceback.format_exc(),
prefix="```",
suffix="```")
for msg in sliced_message:
await ctx.send(msg)
@commands.check(check_if_bot_manager)
@commands.command(hidden=True)
async def pull(self, ctx, auto=False):
"""Does a git pull, bot manager only."""
tmp = await ctx.send('Pulling...')
git_output = await self.bot.async_call_shell("git pull")
await tmp.edit(content=f"Pull complete. Output: ```{git_output}```")
if auto:
cogs_to_reload = re.findall(r'cogs/([a-z]*).py[ ]*\|', git_output)
for cog in cogs_to_reload:
try:
self.bot.unload_extension("cogs." + cog)
self.bot.load_extension("cogs." + cog)
self.bot.log.info(f'Reloaded ext {cog}')
await ctx.send(f':white_check_mark: `{cog}` '
'successfully reloaded.')
except:
await ctx.send(f':x: Cog reloading failed, traceback: '
f'```\n{traceback.format_exc()}\n```')
return
@commands.check(check_if_bot_manager)
@commands.command(hidden=True)
async def sh(self, ctx, *, command: str):
"""Runs a command on shell, bot manager only."""
command = command.strip('`')
tmp = await ctx.send(f'Running `{command}`...')
self.bot.log.info(f"Running {command}")
shell_output = await self.bot.async_call_shell(command)
shell_output = f"\"{command}\" output:\n\n{shell_output}"
self.bot.log.info(shell_output)
sliced_message = await self.bot.slice_message(shell_output,
prefix="```",
suffix="```")
if len(sliced_message) == 1:
await tmp.edit(content=sliced_message[0])
return
await tmp.delete()
for msg in sliced_message:
await ctx.send(msg)
@commands.check(check_if_bot_manager)
@commands.command(hidden=True)
async def unload(self, ctx, ext: str):
"""Unloads a cog, bot manager only."""
self.bot.unload_extension("cogs." + ext)
self.bot.log.info(f'Unloaded ext {ext}')
await ctx.send(f':white_check_mark: `{ext}` successfully unloaded.')
@commands.check(check_if_bot_manager)
@commands.command(hidden=True)
async def reload(self, ctx, ext="_"):
"""Reloads a cog, bot manager only."""
if ext == "_":
ext = self.lastreload
else:
self.lastreload = ext
try:
self.bot.unload_extension("cogs." + ext)
self.bot.load_extension("cogs." + ext)
except:
await ctx.send(f':x: Cog reloading failed, traceback: '
f'```\n{traceback.format_exc()}\n```')
return
self.bot.log.info(f'Reloaded ext {ext}')
await ctx.send(f':white_check_mark: `{ext}` successfully reloaded.')
def setup(bot):
bot.add_cog(AdminCog(bot))