forked from mttu-developers/konabot
175 lines
5.2 KiB
Python
175 lines
5.2 KiB
Python
from typing import cast
|
||
import asyncio
|
||
from loguru import logger
|
||
from nonebot import on_command
|
||
import nonebot
|
||
from nonebot.adapters import Event, Bot
|
||
from nonebot_plugin_alconna import UniMessage, UniMsg
|
||
from nonebot.adapters.onebot.v11.event import MessageEvent as OB11MessageEvent
|
||
from nonebot.adapters.onebot.v11.bot import Bot as OB11Bot
|
||
from nonebot.adapters.onebot.v11.message import Message as OB11Message
|
||
|
||
from konabot.common.apis.ali_content_safety import AlibabaGreen
|
||
from konabot.common.longtask import DepLongTaskTarget
|
||
from konabot.common.render_error_message import render_error_message
|
||
from konabot.plugins.handle_text.base import (
|
||
PipelineRunner,
|
||
TextHandlerEnvironment,
|
||
register_text_handlers,
|
||
)
|
||
from konabot.plugins.handle_text.handlers.ai_handlers import THQwen
|
||
from konabot.plugins.handle_text.handlers.encoding_handlers import (
|
||
THAlign,
|
||
THAlphaConv,
|
||
THB64Hex,
|
||
THBase64,
|
||
THBaseConv,
|
||
THCaesar,
|
||
THMorse,
|
||
THReverse,
|
||
)
|
||
from konabot.plugins.handle_text.handlers.random_handlers import THShuffle, THSorted
|
||
from konabot.plugins.handle_text.handlers.unix_handlers import (
|
||
THCat,
|
||
THEcho,
|
||
THFalse,
|
||
THReplace,
|
||
THRm,
|
||
THTest,
|
||
THTrue,
|
||
)
|
||
from konabot.plugins.handle_text.handlers.whitespace_handlers import (
|
||
THLines,
|
||
THLTrim,
|
||
THRTrim,
|
||
THSqueeze,
|
||
THTrim,
|
||
)
|
||
|
||
|
||
TEXTFX_MAX_RUNTIME_SECONDS = 60
|
||
_textfx_running_users: set[str] = set()
|
||
|
||
|
||
def _get_textfx_user_key(evt: Event) -> str:
|
||
user_id = getattr(evt, "user_id", None)
|
||
self_id = getattr(evt, "self_id", None)
|
||
group_id = getattr(evt, "group_id", None)
|
||
if user_id is not None:
|
||
if group_id is not None:
|
||
return f"{self_id}:{group_id}:{user_id}"
|
||
return f"{self_id}:private:{user_id}"
|
||
session_id = getattr(evt, "get_session_id", None)
|
||
if callable(session_id):
|
||
try:
|
||
return f"session:{evt.get_session_id()}"
|
||
except Exception:
|
||
pass
|
||
return f"event:{evt.__class__.__name__}:{id(evt)}"
|
||
|
||
|
||
cmd = on_command(cmd="textfx", aliases={"处理文字", "处理文本"})
|
||
|
||
|
||
@cmd.handle()
|
||
async def _(msg: UniMsg, evt: Event, bot: Bot, target: DepLongTaskTarget):
|
||
user_key = _get_textfx_user_key(evt)
|
||
if user_key in _textfx_running_users:
|
||
await target.send_message("你当前已有一个 textfx 脚本正在运行,请等待它结束后再试。")
|
||
return
|
||
|
||
istream = ""
|
||
if isinstance(evt, OB11MessageEvent):
|
||
if evt.reply is not None:
|
||
istream = evt.reply.message.extract_plain_text()
|
||
else:
|
||
for seg in evt.get_message():
|
||
if seg.type == "reply":
|
||
msgid = seg.get("id")
|
||
if msgid is not None:
|
||
msg2data = await cast(OB11Bot, bot).get_msg(message_id=msgid)
|
||
istream = OB11Message(
|
||
msg2data.get("message")
|
||
).extract_plain_text()
|
||
|
||
script = msg.extract_plain_text().removeprefix("textfx").removeprefix("处理文字")
|
||
runner = PipelineRunner.get_runner()
|
||
res = runner.parse_pipeline(script)
|
||
|
||
if isinstance(res, str):
|
||
await target.send_message(res)
|
||
return
|
||
|
||
env = TextHandlerEnvironment(is_trusted=False, event=evt)
|
||
|
||
_textfx_running_users.add(user_key)
|
||
try:
|
||
results = await asyncio.wait_for(
|
||
runner.run_pipeline(res, istream or None, env),
|
||
timeout=TEXTFX_MAX_RUNTIME_SECONDS,
|
||
)
|
||
except asyncio.TimeoutError:
|
||
rendered = await render_error_message(
|
||
f"处理指令时出现问题:脚本执行超时(超过 {TEXTFX_MAX_RUNTIME_SECONDS} 秒)"
|
||
)
|
||
await target.send_message(rendered)
|
||
return
|
||
finally:
|
||
_textfx_running_users.discard(user_key)
|
||
|
||
for r in results:
|
||
if r.code != 0:
|
||
message = f"处理指令时出现问题:{r.ostream}"
|
||
rendered = await render_error_message(message)
|
||
await target.send_message(rendered)
|
||
return
|
||
|
||
ostreams = [r.ostream for r in results if r.ostream is not None]
|
||
attachments = [r.attachment for r in results if r.attachment is not None]
|
||
|
||
if ostreams:
|
||
txt = "\n".join(ostreams)
|
||
err = await AlibabaGreen.detect(txt)
|
||
if not err:
|
||
await target.send_message(
|
||
"处理指令时出现问题:内容被拦截!请你检查你的内容是否合理!"
|
||
)
|
||
return
|
||
await target.send_message(txt, at=False)
|
||
|
||
for att in attachments:
|
||
await target.send_message(UniMessage.image(raw=att), at=False)
|
||
|
||
|
||
driver = nonebot.get_driver()
|
||
|
||
|
||
@driver.on_startup
|
||
async def _():
|
||
register_text_handlers(
|
||
THCat(),
|
||
THEcho(),
|
||
THRm(),
|
||
THTrue(),
|
||
THFalse(),
|
||
THTest(),
|
||
THShuffle(),
|
||
THReplace(),
|
||
THBase64(),
|
||
THCaesar(),
|
||
THReverse(),
|
||
THBaseConv(),
|
||
THAlphaConv(),
|
||
THB64Hex(),
|
||
THAlign(),
|
||
THSorted(),
|
||
THMorse(),
|
||
THQwen(),
|
||
THTrim(),
|
||
THLTrim(),
|
||
THRTrim(),
|
||
THSqueeze(),
|
||
THLines(),
|
||
)
|
||
logger.info(f"注册了 TextHandler:{PipelineRunner.get_runner().handlers}")
|