Red-DiscordBot/core/owner.py
2017-04-28 09:16:10 +02:00

116 lines
3.7 KiB
Python

from discord.ext import commands
from core.utils import checks
from core.utils.chat_formatting import box
import asyncio
import importlib
import os
import discord
class Owner:
"""All owner-only commands that relate to debug bot operations."""
def __init__(self, bot):
self.bot = bot
@commands.command()
@checks.is_owner()
async def load(self, ctx, *, cog_name: str):
"""Loads a package"""
if not cog_name.startswith("cogs."):
cog_name = "cogs." + cog_name
self.bot.load_extension(cog_name)
await ctx.send("Done.")
@commands.group()
@checks.is_owner()
async def unload(self, ctx, *, cog_name: str):
"""Unloads a package"""
if not cog_name.startswith("cogs."):
cog_name = "cogs." + cog_name
if cog_name in self.bot.extensions:
self.bot.unload_extension(cog_name)
await ctx.send("Done.")
else:
await ctx.send("That extension is not loaded.")
@commands.command(name="reload")
@checks.is_owner()
async def _reload(self, ctx, *, cog_name: str):
"""Reloads a package"""
if not cog_name.startswith("cogs."):
cog_name = "cogs." + cog_name
self.refresh_modules(cog_name)
self.bot.unload_extension(cog_name)
self.bot.load_extension(cog_name)
await ctx.send("Done.")
def refresh_modules(self, module):
"""Interally reloads modules so that changes are detected"""
module = module.replace(".", os.sep)
for root, dirs, files in os.walk(module):
for name in files:
if name.endswith(".py"):
path = os.path.join(root, name)
path, _ = os.path.splitext(path)
path = ".".join(path.split(os.sep))
print("Reloading " + path)
m = importlib.import_module(path)
importlib.reload(m)
@commands.command(hidden=True)
@checks.is_owner()
async def debug(self, ctx, *, code):
"""Evaluates code"""
author = ctx.message.author
channel = ctx.message.channel
code = code.strip('` ')
result = None
global_vars = globals().copy()
global_vars['bot'] = self.bot
global_vars['ctx'] = ctx
global_vars['message'] = ctx.message
global_vars['author'] = ctx.message.author
global_vars['channel'] = ctx.message.channel
global_vars['guild'] = ctx.message.guild
try:
result = eval(code, global_vars, locals())
except Exception as e:
await ctx.send('```py\n{}: {}```'.format(type(e).__name__, str(e)),)
return
if asyncio.iscoroutine(result):
result = await result
result = str(result)
if ctx.message.guild is not None:
token = ctx.bot.http.token
r = "[EXPUNGED]"
result = result.replace(token, r)
result = result.replace(token.lower(), r)
result = result.replace(token.upper(), r)
await ctx.send(box(result, lang="py"))
@commands.command(hidden=True)
@checks.is_owner()
async def mock(self, ctx, user: discord.Member, *, command):
"""Runs a command as if it was issued by a different user
The prefix must not be entered"""
# Since we have stateful objects now this might be pretty bad
# Sorry Danny
old_author = ctx.author
old_content = ctx.message.content
ctx.message.author = user
ctx.message.content = ctx.prefix + command
await self.bot.process_commands(ctx.message)
ctx.message.author = old_author
ctx.message.content = old_content