summaryrefslogtreecommitdiff
path: root/ATRI/plugins/code-runner.py
blob: 367a1444613bfa38873de500057fc1efb27012b5 (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
"""
Idea from: https://github.com/cczu-osa/aki
"""
import json
from nonebot.adapters.cqhttp import Bot, MessageEvent

from ATRI.rule import is_in_service
from ATRI.service import Service as sv
from ATRI.utils.request import post_bytes
from ATRI.exceptions import RequestTimeOut


RUN_API_URL_FORMAT = 'https://glot.io/run/{}?version=latest'
SUPPORTED_LANGUAGES = {
    'assembly': {'ext': 'asm'},
    'bash': {'ext': 'sh'},
    'c': {'ext': 'c'},
    'clojure': {'ext': 'clj'},
    'coffeescript': {'ext': 'coffe'},
    'cpp': {'ext': 'cpp'},
    'csharp': {'ext': 'cs'},
    'erlang': {'ext': 'erl'},
    'fsharp': {'ext': 'fs'},
    'go': {'ext': 'go'},
    'groovy': {'ext': 'groovy'},
    'haskell': {'ext': 'hs'},
    'java': {'ext': 'java', 'name': 'Main'},
    'javascript': {'ext': 'js'},
    'julia': {'ext': 'jl'},
    'kotlin': {'ext': 'kt'},
    'lua': {'ext': 'lua'},
    'perl': {'ext': 'pl'},
    'php': {'ext': 'php'},
    'python': {'ext': 'py'},
    'ruby': {'ext': 'rb'},
    'rust': {'ext': 'rs'},
    'scala': {'ext': 'scala'},
    'swift': {'ext': 'swift'},
    'typescript': {'ext': 'ts'},
}


__doc__ = """
在线运行代码
权限组:所有人
用法:
  /code (lang) (code)
示例:
  /code python
  print('Hello world!')
"""

code_runner = sv.on_command(
    cmd="code",
    docs=__doc__,
    rule=is_in_service('code')
)

@code_runner.handle()
async def _code_runner(bot: Bot, event: MessageEvent) -> None:
    msg = str(event.message).split("\n")
    
    if msg[0] == "list":
        msg0 = "咱现在支持的语言如下:\n"
        msg0 += ", ".join(map(str, SUPPORTED_LANGUAGES.keys()))
            
        await code_runner.finish(msg0)
    elif not msg[0]:
        await code_runner.finish("请键入/help以获取更多支持...")
    
    laug = msg[0].replace("\r", "")
    if laug not in SUPPORTED_LANGUAGES:
        await code_runner.finish("该语言暂不支持...")
    
    del msg[0]
    code = "\n".join(map(str, msg))
    try:
        req = await post_bytes(
            RUN_API_URL_FORMAT.format(laug),
            json={
                "files": [{
                        "name": (SUPPORTED_LANGUAGES[laug].get("name", "main") +
                        f".{SUPPORTED_LANGUAGES[laug]['ext']}"),
                        "content": code
                }],
                "stdin": "",
                "command": ""
            }
        )
    except RequestTimeOut:
        raise RequestTimeOut("Failed to request!")
    
    payload = json.loads(req)
    sent = False
    for k in ['stdout', 'stderr', 'error']:
        v = payload.get(k)
        lines = v.splitlines()
        lines, remained_lines = lines[:10], lines[10:]
        out = '\n'.join(lines)
        out, remained_out = out[:60 * 10], out[60 * 10:]

        if remained_lines or remained_out:
            out += f"\n(太多了太多了...)"

        if out:
            await bot.send(event, f"{k}:\n\n{out}")
            sent = True
    
    if not sent:
        await code_runner.finish("Running success! Nothing print.")