From 167d09793bcbbc29282507f6ff911dde174faa1d Mon Sep 17 00:00:00 2001 From: romangraef Date: Sat, 5 May 2018 12:49:05 +0200 Subject: added eval --- eval_handler.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 13 +++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 eval_handler.py diff --git a/eval_handler.py b/eval_handler.py new file mode 100644 index 0000000..89e8e09 --- /dev/null +++ b/eval_handler.py @@ -0,0 +1,49 @@ +import re +from typing import List, Dict, Pattern +import discord + +REPLACEMENTS: Dict[Pattern, str] = { + re.compile(r'<@!?(?P[0-9]+)>'): '(guild.get_member({id}) or client.get_user({id}))', + re.compile(r'<#(?P[0-9]+)>'): '(discord.utils.get(all_channels, id={id}))', + re.compile(r'<@&(?P[0-9]+)>'): '(discord.utils.get(all_roles, id={id}))', + # Maybe later emoji support +} + + +async def handle_eval(message: discord.Message, client: discord.Client): + content: str = message.content + command_start: int = content.find(' ') + channel: discord.TextChannel = message.channel + author: discord.Member = message.author + + all_channels: List[discord.Guild] = [] + all_roles: List[discord.Role] = [] + for guild in client.guilds: + guild: discord.Guild = guild # for type hints + all_channels += guild.channels + all_roles += guild.roles + + variables = { + 'message': message, + 'author': author, + 'channel': channel, + 'all_channels': all_channels, + 'all_roles': all_roles, + 'client': client, + 'discord': discord, + } + lines: List[str] = content[command_start:].strip().split('\n') + lines[-1] = 'return ' + lines[-1] + block: str = '\n'.join(' ' + line for line in lines) + code = f"async def code({', '.join(variables.keys())}):\n" \ + f"{block}" + + for regex, replacement in REPLACEMENTS.items(): + code = re.sub(regex, lambda match: replacement.format(**match.groupdict()), code) + + _globals, _locals = {}, {} + exec(code, _globals, _locals) + result = {**_globals, **_locals} + result = await result["code"](**variables) + + return await channel.send("Evaluation success: ```tr\n%r\n```" % result) diff --git a/main.py b/main.py index 942c774..6385fa5 100644 --- a/main.py +++ b/main.py @@ -6,6 +6,8 @@ from discord import Object from discord.ext import commands import discord +from eval_handler import handle_eval + bot = commands.Bot( command_prefix='~', self_bot=True, @@ -20,7 +22,7 @@ banned_guilds = [ def check_guild(func): @wraps(func) async def wrapper(ctx: commands.Context, *args, **kwargs): - if ctx.guild.id in banned_guilds: + if ctx.guild is not None and ctx.guild.id in banned_guilds: return return await func(ctx, *args, **kwargs) @@ -64,6 +66,13 @@ def get_with_attr(arr, **attributes): return list(_get_with_attr()) +@bot.command(name="eval", pass_context=True) +async def eval_command(ctx: commands.Context): + await handle_eval(message=ctx.message, + client=bot, + ) + + @bot.command(name="channel", pass_context=True) @check_guild async def channel_cmd(ctx: commands.Context, channel: discord.TextChannel = None): @@ -123,7 +132,7 @@ async def user_cmd(ctx: commands.Context, identifier): em.set_thumbnail(url=discord_profile.avatar_url) em.add_field(name='Joined Discord', value=discord_profile.created_at, inline=True) guild: discord.Guild = ctx.guild - if guild.get_member(identifier) is not None: + if guild is not None and guild.get_member(identifier) is not None: member: discord.Member = guild.get_member(identifier) em.colour = member.color em.add_field(name="Permissions", value=dump_perms(member.guild_permissions), inline=True) -- cgit