217 lines
8.2 KiB
Python
217 lines
8.2 KiB
Python
from __future__ import annotations
|
||
|
||
import re
|
||
from typing import TYPE_CHECKING, Any
|
||
|
||
from astrbot.api.star import Context
|
||
from astrbot.api.web import error_response, json_response, request
|
||
|
||
from .event_push import EVENT_NAMES
|
||
|
||
if TYPE_CHECKING:
|
||
from .event_push import EventPushService
|
||
from .jx3api_data import JX3APIService
|
||
from .kungfu_alias import KungfuAliasService
|
||
from .server_binding import ServerBindingService
|
||
from .session_control import SessionControlService
|
||
|
||
|
||
class WebUIService:
|
||
"""注册插件管理页接口,并处理 WebUI 的数据读写。"""
|
||
|
||
def __init__(
|
||
self,
|
||
jx3api: JX3APIService,
|
||
event_push: EventPushService,
|
||
server_binding: ServerBindingService,
|
||
kungfu_alias: KungfuAliasService,
|
||
session_control: SessionControlService,
|
||
):
|
||
self.jx3api = jx3api
|
||
self.event_push = event_push
|
||
self.server_binding = server_binding
|
||
self.kungfu_alias = kungfu_alias
|
||
self.session_control = session_control
|
||
|
||
def register(self, context: Context, plugin_name: str):
|
||
routes = (
|
||
("dashboard", self.dashboard, ["GET"], "读取会话管理数据"),
|
||
("bindings/save", self.save_binding, ["POST"], "保存会话区服绑定"),
|
||
("bindings/delete", self.delete_binding, ["POST"], "删除会话区服绑定"),
|
||
("aliases/save", self.save_aliases, ["POST"], "保存区服别名"),
|
||
("aliases/delete", self.delete_aliases, ["POST"], "删除区服别名"),
|
||
("aliases/restore", self.restore_aliases, ["POST"], "恢复默认区服别名"),
|
||
("kungfu/save", self.save_kungfu, ["POST"], "保存心法别名"),
|
||
("kungfu/restore", self.restore_kungfu, ["POST"], "恢复默认心法别名"),
|
||
("servers/refresh", self.refresh_servers, ["POST"], "刷新区服目录"),
|
||
(
|
||
"session-control/mode",
|
||
self.save_session_control_mode,
|
||
["POST"],
|
||
"保存会话控制模式",
|
||
),
|
||
(
|
||
"session-control/save",
|
||
self.save_session_control_entry,
|
||
["POST"],
|
||
"保存会话控制名单",
|
||
),
|
||
(
|
||
"session-control/delete",
|
||
self.delete_session_control_entry,
|
||
["POST"],
|
||
"删除会话控制名单",
|
||
),
|
||
)
|
||
for path, handler, methods, description in routes:
|
||
context.register_web_api(
|
||
f"/{plugin_name}/{path}",
|
||
handler,
|
||
methods,
|
||
description,
|
||
)
|
||
|
||
@staticmethod
|
||
async def _json_payload() -> dict[str, Any]:
|
||
payload = await request.json(default={})
|
||
if not isinstance(payload, dict):
|
||
raise ValueError("请求正文必须是 JSON 对象")
|
||
return payload
|
||
|
||
@staticmethod
|
||
def _parse_aliases(raw_aliases: Any) -> list[str]:
|
||
if isinstance(raw_aliases, str):
|
||
return re.split(r"[,,;;\n]+", raw_aliases)
|
||
if isinstance(raw_aliases, list):
|
||
return [str(value) for value in raw_aliases]
|
||
raise ValueError("别名必须是字符串或数组")
|
||
|
||
async def dashboard(self):
|
||
bindings = await self.server_binding.list_bindings()
|
||
subscriptions = await self.event_push.list_subscription_statuses()
|
||
aliases = await self.server_binding.list_aliases()
|
||
kungfu = await self.kungfu_alias.list_kungfu()
|
||
session_control = await self.session_control.get_state()
|
||
return json_response(
|
||
{
|
||
"bindings": bindings,
|
||
"subscriptions": subscriptions,
|
||
"aliases": aliases,
|
||
"kungfu": kungfu,
|
||
"servers": self.server_binding.standard_servers(),
|
||
"events": {
|
||
str(action): name for action, name in EVENT_NAMES.items()
|
||
},
|
||
"session_control": session_control,
|
||
}
|
||
)
|
||
|
||
async def save_binding(self):
|
||
try:
|
||
payload = await self._json_payload()
|
||
server = self.server_binding.resolve_standard_server(
|
||
payload.get("server")
|
||
)
|
||
if not server:
|
||
raise ValueError("绑定区服必须选择标准区服")
|
||
await self.server_binding.set_binding(
|
||
str(payload.get("session_id") or ""),
|
||
server,
|
||
)
|
||
except ValueError as exc:
|
||
return error_response(str(exc), status_code=400)
|
||
return json_response({"saved": True})
|
||
|
||
async def delete_binding(self):
|
||
try:
|
||
payload = await self._json_payload()
|
||
session_id = str(payload.get("session_id") or "")
|
||
if not session_id.strip():
|
||
raise ValueError("会话 ID 不能为空")
|
||
await self.server_binding.delete_binding(session_id)
|
||
except ValueError as exc:
|
||
return error_response(str(exc), status_code=400)
|
||
return json_response({"deleted": True})
|
||
|
||
async def save_aliases(self):
|
||
try:
|
||
payload = await self._json_payload()
|
||
await self.server_binding.set_aliases(
|
||
str(payload.get("server") or ""),
|
||
self._parse_aliases(payload.get("aliases", [])),
|
||
)
|
||
except ValueError as exc:
|
||
return error_response(str(exc), status_code=400)
|
||
return json_response({"saved": True})
|
||
|
||
async def delete_aliases(self):
|
||
try:
|
||
payload = await self._json_payload()
|
||
server = str(payload.get("server") or "")
|
||
if not server.strip():
|
||
raise ValueError("标准区服名不能为空")
|
||
await self.server_binding.delete_aliases(server)
|
||
except ValueError as exc:
|
||
return error_response(str(exc), status_code=400)
|
||
return json_response({"deleted": True})
|
||
|
||
async def restore_aliases(self):
|
||
try:
|
||
restored = await self.server_binding.restore_default_aliases()
|
||
except (RuntimeError, ValueError) as exc:
|
||
return error_response(str(exc), status_code=500)
|
||
return json_response({"restored": restored})
|
||
|
||
async def save_kungfu(self):
|
||
try:
|
||
payload = await self._json_payload()
|
||
await self.kungfu_alias.save_aliases(
|
||
payload.get("pzid"),
|
||
self._parse_aliases(payload.get("aliases", [])),
|
||
)
|
||
except ValueError as exc:
|
||
return error_response(str(exc), status_code=400)
|
||
return json_response({"saved": True})
|
||
|
||
async def restore_kungfu(self):
|
||
try:
|
||
restored = await self.kungfu_alias.restore_defaults()
|
||
except (RuntimeError, ValueError) as exc:
|
||
return error_response(str(exc), status_code=500)
|
||
return json_response({"restored": restored})
|
||
|
||
async def refresh_servers(self):
|
||
servers = await self.jx3api.server_list()
|
||
if not servers:
|
||
return error_response("区服目录刷新失败", status_code=502)
|
||
await self.server_binding.update_server_catalog(servers)
|
||
return json_response({"servers": self.server_binding.standard_servers()})
|
||
|
||
async def save_session_control_mode(self):
|
||
try:
|
||
payload = await self._json_payload()
|
||
await self.session_control.set_mode(payload.get("mode"))
|
||
except ValueError as exc:
|
||
return error_response(str(exc), status_code=400)
|
||
return json_response({"saved": True})
|
||
|
||
async def save_session_control_entry(self):
|
||
try:
|
||
payload = await self._json_payload()
|
||
await self.session_control.save_entry(
|
||
payload.get("session_id"),
|
||
payload.get("list_type"),
|
||
payload.get("remark"),
|
||
)
|
||
except ValueError as exc:
|
||
return error_response(str(exc), status_code=400)
|
||
return json_response({"saved": True})
|
||
|
||
async def delete_session_control_entry(self):
|
||
try:
|
||
payload = await self._json_payload()
|
||
await self.session_control.delete_entry(payload.get("session_id"))
|
||
except ValueError as exc:
|
||
return error_response(str(exc), status_code=400)
|
||
return json_response({"deleted": True})
|