aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorromangraef <romangraef@loves.dicksinhisan.us>2018-09-10 20:51:36 +0200
committerromangraef <romangraef@loves.dicksinhisan.us>2018-09-10 20:51:36 +0200
commitdbde5c34a71157707e82bc52b0c671d7dadc741a (patch)
tree799d9f86d22b455af5d0ce892d460482f61645ce
parentb105798c91b30e6fe8bff2a9087af6db4e6065a2 (diff)
downloadevalbot-dbde5c34a71157707e82bc52b0c671d7dadc741a.tar.gz
evalbot-dbde5c34a71157707e82bc52b0c671d7dadc741a.tar.bz2
evalbot-dbde5c34a71157707e82bc52b0c671d7dadc741a.zip
Rextester api
-rw-r--r--README.md8
-rw-r--r--compile_api.py70
-rw-r--r--config.py6
-rw-r--r--modules/execute.py79
4 files changed, 80 insertions, 83 deletions
diff --git a/README.md b/README.md
index 4a2034d..c268404 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,10 @@
EVALBOT
------
-Discord Code eval bot using the [Compilebot][compilebot] API.
+Discord Code eval bot using the [Rextester][rextester] API.
### SETUP
- Create a discord bot account at [the discord developers page][discord-devs]. **IMPORTANT** Create a bot user as well.
- - Go to the [Compilebot][compilebot] website and subscribe to a plan.
- clone the repository and create a [Virtual Environment][venv]
- Install all the requirements via `pip install -r requirements.txt`
- Create a `config.ini` in the following format:
@@ -13,12 +12,9 @@ Discord Code eval bot using the [Compilebot][compilebot] API.
[discord]
token = YOURDISCORDTOKEN. DISCORD! TOKEN! NOT ID OR SECRET
-[jdoodle]
-id = yourcompilebotid
-secret = yourcompilebotsecret
```
- Launch the bot via `python main.py`. If you want to run the bot permanently i recommend using `tmux` or `screen`.
-[compilebot]: https://www.jdoodle.com/compiler-api/
[discord-devs]: https://discordapp.com/developers/applications/me
[venv]: https://docs.python.org/3/library/venv.html
+[rextester]: http://rextester.com/main
diff --git a/compile_api.py b/compile_api.py
index 82ac440..019df74 100644
--- a/compile_api.py
+++ b/compile_api.py
@@ -1,49 +1,57 @@
-import asyncio
+import base64
+from io import BytesIO
+from typing import Optional, List, Union
import aiohttp
+from discord import File
-from config import jdoodle_id, jdoodle_secret
-
-EXECUTE_ENDPOINT = "https://api.jdoodle.com/v1/execute"
+EXECUTE_ENDPOINT = "http://rextester.com/rundotnet/api"
def get_parameters(**kwargs):
- return dict(
- clientId=jdoodle_id,
- clientSecret=jdoodle_secret,
- **kwargs,
- )
+ return kwargs
+
+class ExecuteResponse(object):
-def post(url, data=None, json=None, **kwargs):
- return asyncio.get_event_loop().run_in_executor(None, lambda *_: requests.post(url, data, json, **kwargs))
+ def __init__(self, warnings: Optional[str], errors: Optional[str], output: str, stats, files):
+ self.output: Optional[str] = output
+ self.warnings: Optional[str] = warnings
+ self.errors: Optional[str] = errors
+ self.stats: str = stats
+ self.files: Optional[List[str]] = files
+ @property
+ def discord_files(self) -> List[File]:
+ if not self.files:
+ return []
-class ExecuteResponse(object):
- output: str
- cpu_time: float
- memory: int
- status_code: int
+ def convert_file(b64, i):
+ bytesio = BytesIO()
+ bytesio.write(base64.b64decode(b64))
+ bytesio.seek(0)
+ return File(bytesio, filename=f'output{i}.png')
- def __init__(self, output: str, cpu_time: float, memory: int, status_code: int):
- self.output: str = output
- self.cpu_time: float = cpu_time
- self.memory: int = memory
- self.status_code: int = status_code
+ return [convert_file(b64, i) for i, b64 in enumerate(self.files)]
def parse_execute_response(response: dict) -> ExecuteResponse:
- memory = response['memory']
- output = response['output']
- cpu_time = response['cpuTime']
- status_code = response['statusCode']
- return ExecuteResponse(output, cpu_time, memory, status_code)
+ warnings = response['Warnings']
+ errors = response['Errors']
+ output = response['Result']
+ stats = response['Stats']
+ files = response['Files']
+ return ExecuteResponse(warnings, errors, output, stats, files)
-async def execute(code: str, language: str, version: str) -> ExecuteResponse:
+async def execute(code: str, language: Union[str, int]) -> ExecuteResponse:
async with aiohttp.ClientSession() as session:
- response = await session.post(EXECUTE_ENDPOINT, json=get_parameters(
- script=code,
- language=language,
- versionIndex=version))
+ print(code)
+ print(language)
+ response = await session.post(EXECUTE_ENDPOINT, data=get_parameters(
+ Program=code,
+ LanguageChoice=language,
+ Input="",
+ CompilerArgs="",
+ ))
return parse_execute_response(await response.json())
diff --git a/config.py b/config.py
index 6595e98..08b3193 100644
--- a/config.py
+++ b/config.py
@@ -6,9 +6,3 @@ config.read('config.ini')
discord = config['discord']
token = discord['token']
-
-
-jdoodle = config['jdoodle']
-
-jdoodle_secret = jdoodle['secret']
-jdoodle_id = jdoodle['id']
diff --git a/modules/execute.py b/modules/execute.py
index ce45e12..bfef437 100644
--- a/modules/execute.py
+++ b/modules/execute.py
@@ -3,7 +3,7 @@ from collections import defaultdict
from datetime import datetime, timedelta
from typing import Pattern
-from discord import Embed, Color, Message, Guild, TextChannel, Member
+from discord import Embed, Message, Guild, TextChannel, Member
from discord.ext.commands import Bot
from compile_api import execute
@@ -11,29 +11,29 @@ from compile_api import execute
CODE_BLOCK_REGEX: Pattern = re.compile("```(?P<lang>.*)\n(?P<code>[\\s\\S]*?)```")
INPUT_BLOCK_REGEX: Pattern = re.compile("input[: \t\n]*```(?P<lang>.*)?\n(?P<text>[\\s\\S]*?)```", re.IGNORECASE)
-PYTHON_3 = ('python3', 2)
-NODEJS = ('nodejs', 2)
-C_LANG = ('c', 3)
-CPP = ('cpp14', 2)
-PHP = ('php', 2)
-PYTHON_2 = ('python2', 1)
-RUBY = ('ruby', 2)
-GO_LANG = ('go', 2)
-SCALA = ('scala', 2)
-BASH = ('bash', 2)
-CSHARP = ('csharp', 2)
-HASKELL = ('haskell', 2)
-BRAINFUCK = ('brainfuck', 0)
-LUA = ('lua', 1)
-DART = ('dart', 2)
-KOTLIN = ('kotlin', 1)
-JAVA = ('java', 0)
+PYTHON_3 = 24
+NODEJS = 17
+C_LANG = 6
+CPP = 7
+PHP = 8
+PYTHON_2 = 5
+RUBY = 12
+GO_LANG = 20
+SCALA = 21
+BASH = 38
+CSHARP = 1
+HASKELL = 11
+BRAINFUCK = 44
+LUA = 14
+KOTLIN = 43
+JAVA = 4
+R_LANG = 31
languages = {
+ 'r': R_LANG,
+ 'rlang': R_LANG,
'kt': KOTLIN,
'kotlin': KOTLIN,
- 'dart': DART,
- 'dt': DART,
'lua': LUA,
'py': PYTHON_3,
'python': PYTHON_3,
@@ -88,29 +88,28 @@ class ExecuteCog(object):
embed=Embed(
description=f"You are not allowed to eval code again. Check again in "
f"{(timedelta(seconds=30)-delta).seconds}secs"))
- if not author.guild_permissions.manage_messages:
+ if not author.guild_permissions.manage_messages and not author.id == 310702108997320705:
self.last_messaged[author.id] = datetime.now()
- language, version = languages[lang]
- response = await execute(code, language, version)
- if response.status_code == 429:
- return await channel.send(
- embed=Embed(
- color=Color.blurple(),
- description="The daily ratelimit for our API is reached. A great alternative is [Ideone]("
- "https://ideone.com/) or [Repl.it](https://repl.it/)"))
- if response.status_code == 401:
- return await channel.send(
- embed=Embed(
- color=Color.red(),
- description="Our API credentials are invalid. Please contact the bot owner"))
- memory = response.memory
+ language = languages[lang]
+ print(language)
+ response = await execute(code, language)
output = response.output
- cpu_time = response.cpu_time
+ stats = response.stats
+ warnings = response.warnings
+ errors = response.errors
+ files = response.discord_files
+ em = Embed(
+ title="Executed your code",
+ description=f"```\n{output}```"
+ ).set_footer(text=stats)
+ if warnings:
+ em.add_field(name="Warnings", value=f'```\n{warnings}```')
+ if errors:
+ em.add_field(name="Errors", value=f'```\n{errors}```')
await channel.send(
- embed=Embed(
- title="Executed your code",
- description=f"```\n{output}```"
- ).set_footer(text=f"Executed in {cpu_time}s. Memory: {memory}"))
+ embed=em,
+ files=files if len(files) > 0 else None
+ )
def setup(bot: Bot):