aboutsummaryrefslogtreecommitdiff
path: root/modules/execute.py
blob: 61276471a7ee0132087f4a5054aeeaa0e40e4e22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import re
from collections import defaultdict
from datetime import datetime, timedelta
from typing import Pattern

from discord import Embed, Color, Message, Guild, TextChannel, Member
from discord.ext.commands import Bot

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)

languages = {
    'kt': KOTLIN,
    'kotlin': KOTLIN,
    'dart': DART,
    'dt': DART,
    'lua': LUA,
    'py': PYTHON_3,
    'python': PYTHON_3,
    'js': NODEJS,
    'javascript': NODEJS,
    'c': C_LANG,
    'c++': CPP,
    'cpp': CPP,
    'py2': PYTHON_2,
    'go': GO_LANG,
    'scala': SCALA,
    'sc': SCALA,
    'bash': BASH,
    'hs': HASKELL,
    'haskell': HASKELL,
    'brainfuck': BRAINFUCK,
    'bf': BRAINFUCK,
}


class ExecuteCog(object):
    def __init__(self, bot: Bot):
        self.bot: Bot = bot
        self.last_messaged = defaultdict(lambda: datetime.fromtimestamp(0))

    # noinspection PyMethodMayBeStatic
    async def on_message(self, message: Message):
        if message.guild is None:
            return
        content: str = message.content
        guild: Guild = message.guild
        author: Member = message.author
        channel: TextChannel = message.channel
        if guild.me not in message.mentions:
            return
        code = ""
        lang = ""
        for match in CODE_BLOCK_REGEX.finditer(content):
            code = match.group('code')
            lang = match.group('lang')
            break
        if lang is "" or code is "":
            return
        inp = ""
        for match in INPUT_BLOCK_REGEX.finditer(content):
            inp += match.group("text") + '\n'
        last = self.last_messaged[author.id]
        delta = datetime.now() - last
        if delta < timedelta(seconds=30):
            return await channel.send(
                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:
            self.last_messaged[author.id] = datetime.now()
        response = await execute(code, *languages[lang])
        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
        output = response.output
        cpu_time = response.cpu_time
        await channel.send(
            embed=Embed(
                title="Executed your code",
                description=f"```\n{output}```"
            ).set_footer(text=f"Executed in {cpu_time}s. Memory: {memory}"))


def setup(bot: Bot):
    bot.add_cog(ExecuteCog(bot))