diff options
Diffstat (limited to 'eval_handler.py')
-rw-r--r-- | eval_handler.py | 49 |
1 files changed, 49 insertions, 0 deletions
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<id>[0-9]+)>'): '(guild.get_member({id}) or client.get_user({id}))', + re.compile(r'<#(?P<id>[0-9]+)>'): '(discord.utils.get(all_channels, id={id}))', + re.compile(r'<@&(?P<id>[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) |