aboutsummaryrefslogtreecommitdiff
path: root/modules/execute.py
blob: 1d9102e833d90652de3dc31fc5c072cc72249d8e (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
115
116
117
118
119
120
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
from filter import verify

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)

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,
    'java': JAVA,
}


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()
        language, version = languages[lang]
        if not verify(message, language):
            return
        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
        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))