Last active
July 4, 2017 21:10
-
-
Save Jerdak/637dc783b32066498cdfad8465148f29 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# requires https://github.com/Rapptz/discord.py | |
# this snippet was scripted against discord.py v0.16.8 @ commit 7b806667cda6dc26b6a99d73473dcff5c2dd4044 | |
import discord | |
import asyncio | |
import re | |
from types import ModuleType | |
sandbox = ModuleType('sandboxed_modules') | |
from discord.ext.commands import Bot | |
my_bot = Bot(command_prefix="!") | |
@my_bot.event | |
@asyncio.coroutine | |
def on_read(): | |
print("Client logged in") | |
def __compile_that_shit(contents): | |
""" Compile source helper | |
Convert a discord.py message block to a viable bit of python source. | |
It's assumed the user will return a string. | |
Arguments: | |
contents (str) - Discord message contents. See 'expected content format' below. | |
Expected Content Format: | |
!discord_command | |
```python | |
def my_code(): | |
return "my code ran, aren't I special" | |
``` | |
NOTE: | |
discord.py doesn't like inline double quotes so for now | |
the source must contain escaped single quotes for string | |
literals. | |
TODO: | |
* Wrap user code so it always returns a string. | |
* Sanitize user code to disallow file system access, or use in VM only. | |
""" | |
# Ugly regex to pull out markdown code block. | |
m = re.search('`{3}python(?:(.*$)\n)?([\s\S]*)`{3}',contents) | |
code_block = m.group(2) | |
# Split code block along lines | |
code_blocks = code_block.split('\n') | |
# Recreate code block | |
code_block = "\n".join(code_blocks) | |
print("contents:",contents) | |
print("Code Block:",code_block) | |
code = compile(code_block,'','exec') | |
# Avoid function leakage, plop it in a custom namespace. (TODO: Tie this to user id?) | |
exec(code,sandbox.__dict__) | |
@my_bot.command(pass_context=True) | |
@asyncio.coroutine | |
def compile_that_shit(ctx): | |
""" Compile user code | |
Example: | |
!compile_that_shit | |
```python | |
def my_code(): | |
return "my code ran, aren't I special" | |
``` | |
""" | |
__compile_that_shit(ctx.message.content) | |
yield from my_bot.say("I compiled your shitty code, but I'm not happy about it. Use `!run_that_shit <function_name>` to trigger the function. Parens not supported") | |
@my_bot.command() | |
@asyncio.coroutine | |
def run_that_shit(*args): | |
""" Run compiled function | |
Example: | |
!run_that_shit my_code | |
TODO: | |
* Add argument support. e.g. !run_that_shit my_code('foo','bar') | |
""" | |
print(args) | |
if args[0] in sandbox.__dict__: | |
yield from my_bot.say(sandbox.__dict__[args[0]]()) | |
else: | |
yield from my_bot.say("<{0}> not found, compile that shit first".format(args[0])) | |
# CLIENT TOKEN is your Discord bot's token. | |
my_bot.run('<CLIENT_TOKEN>') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment