summaryrefslogtreecommitdiff
path: root/ATRI/plugins/code_runner
diff options
context:
space:
mode:
Diffstat (limited to 'ATRI/plugins/code_runner')
-rw-r--r--ATRI/plugins/code_runner/__init__.py35
-rw-r--r--ATRI/plugins/code_runner/data_source.py111
2 files changed, 146 insertions, 0 deletions
diff --git a/ATRI/plugins/code_runner/__init__.py b/ATRI/plugins/code_runner/__init__.py
new file mode 100644
index 0000000..dfe6162
--- /dev/null
+++ b/ATRI/plugins/code_runner/__init__.py
@@ -0,0 +1,35 @@
+from random import choice
+
+from nonebot.adapters.cqhttp import Bot, MessageEvent
+from nonebot.adapters.cqhttp.message import Message, MessageSegment
+
+from ATRI.utils.limit import FreqLimiter
+from .data_source import CodeRunner
+
+
+_flmt = FreqLimiter(5)
+_flmt_notice = choice(["慢...慢一..点❤", "冷静1下", "歇会歇会~~"])
+
+
+code_runner = CodeRunner().on_command("/code", "在线运行一段代码,帮助:/code help")
+
+@code_runner.handle()
+async def _code_runner(bot: Bot, event: MessageEvent):
+ user_id = event.get_user_id()
+ if not _flmt.check(user_id):
+ await code_runner.finish(_flmt_notice)
+
+ msg = str(event.get_message())
+ args = msg.split("\n")
+
+ if not args:
+ content = f"> {MessageSegment.at(user_id)}\n" + "请键入 /code help 以获取帮助~!"
+ elif args[0] == "help":
+ content = f"> {MessageSegment.at(user_id)}\n" + CodeRunner().help()
+ elif args[0] == "list":
+ content = f"> {MessageSegment.at(user_id)}\n" + CodeRunner().list_supp_lang()
+ else:
+ content = MessageSegment.at(user_id) + await CodeRunner().runner(msg)
+
+ _flmt.start_cd(user_id)
+ await code_runner.finish(Message(content))
diff --git a/ATRI/plugins/code_runner/data_source.py b/ATRI/plugins/code_runner/data_source.py
new file mode 100644
index 0000000..bbe0d2e
--- /dev/null
+++ b/ATRI/plugins/code_runner/data_source.py
@@ -0,0 +1,111 @@
+from ATRI.rule import is_in_service
+from ATRI.service import Service
+from ATRI.utils import request
+from ATRI.exceptions import RequestError
+
+
+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__ = """
+在线跑代码
+"""
+
+
+class CodeRunner(Service):
+
+ def __init__(self):
+ Service.__init__(self, "在线跑代码", __doc__, rule=is_in_service("在线跑代码"))
+
+ @staticmethod
+ def help() -> str:
+ return (
+ "/code {语言}\n"
+ "{代码}\n"
+ "For example:\n"
+ "/code python\n"
+ "print('hello world')"
+ )
+
+ @staticmethod
+ def list_supp_lang() -> str:
+ msg0 = "咱现在支持的语言如下:\n"
+ msg0 += ", ".join(map(str, SUPPORTED_LANGUAGES.keys()))
+ return msg0
+
+ @staticmethod
+ async def runner(msg: str):
+ args = msg.split("\n")
+ if not args:
+ return "请检查键入内容..."
+
+ lang = args[0].replace("\r", "")
+ if lang not in SUPPORTED_LANGUAGES:
+ return "该语言暂不支持..."
+
+ del args[0]
+ code = "\n".join(map(str, args))
+ url = RUN_API_URL_FORMAT.format(lang)
+ js = {
+ "files": [
+ {
+ "name": (
+ SUPPORTED_LANGUAGES[lang].get("name", "main")
+ + f".{SUPPORTED_LANGUAGES[lang]['ext']}"
+ ),
+ "content": code,
+ }
+ ],
+ "stdin": "",
+ "command": ""
+ }
+
+ try:
+ res = await request.post(url, json=js)
+ except RequestError:
+ raise RequestError("Request failed!")
+
+ payload = await res.json()
+ 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:
+ return f"\n{k}:\n{out}"
+
+ if not sent:
+ return "\n运行完成,没任何输出呢..." \ No newline at end of file