From ae07835da7717efcb3ccda30b897e7d13c8d4f04 Mon Sep 17 00:00:00 2001 From: Ocetars Date: Tue, 2 Dec 2025 20:56:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/dashboard/routes/__init__.py | 2 + astrbot/dashboard/routes/command.py | 84 ++++++++++++++++++++++++++++ astrbot/dashboard/server.py | 1 + 3 files changed, 87 insertions(+) create mode 100644 astrbot/dashboard/routes/command.py diff --git a/astrbot/dashboard/routes/__init__.py b/astrbot/dashboard/routes/__init__.py index b7997cf8e..03e9ea798 100644 --- a/astrbot/dashboard/routes/__init__.py +++ b/astrbot/dashboard/routes/__init__.py @@ -1,5 +1,6 @@ from .auth import AuthRoute from .chat import ChatRoute +from .command import CommandRoute from .config import ConfigRoute from .conversation import ConversationRoute from .file import FileRoute @@ -16,6 +17,7 @@ from .update import UpdateRoute __all__ = [ "AuthRoute", "ChatRoute", + "CommandRoute", "ConfigRoute", "ConversationRoute", "FileRoute", diff --git a/astrbot/dashboard/routes/command.py b/astrbot/dashboard/routes/command.py new file mode 100644 index 000000000..6d3477302 --- /dev/null +++ b/astrbot/dashboard/routes/command.py @@ -0,0 +1,84 @@ +from quart import request + +from astrbot.core.star.command_management import ( + list_command_conflicts, + list_commands, +) +from astrbot.core.star.command_management import ( + rename_command as rename_command_service, +) +from astrbot.core.star.command_management import ( + toggle_command as toggle_command_service, +) + +from .route import Response, Route, RouteContext + + +class CommandRoute(Route): + def __init__(self, context: RouteContext) -> None: + super().__init__(context) + self.routes = { + "/commands": ("GET", self.get_commands), + "/commands/conflicts": ("GET", self.get_conflicts), + "/commands/toggle": ("POST", self.toggle_command), + "/commands/rename": ("POST", self.rename_command), + } + self.register_routes() + + async def get_commands(self): + commands = await list_commands() + conflicts = await list_command_conflicts() + summary = { + "total": len(commands), + "disabled": len([cmd for cmd in commands if not cmd["enabled"]]), + "conflicts": len(conflicts), + } + return Response().ok({"items": commands, "summary": summary}).__dict__ + + async def get_conflicts(self): + conflicts = await list_command_conflicts() + return Response().ok(conflicts).__dict__ + + async def toggle_command(self): + data = await request.get_json() + handler_full_name = data.get("handler_full_name") + enabled = data.get("enabled") + + if handler_full_name is None or enabled is None: + return Response().error("handler_full_name 与 enabled 均为必填。").__dict__ + + if isinstance(enabled, str): + enabled = enabled.lower() in ("1", "true", "yes", "on") + + try: + await toggle_command_service(handler_full_name, bool(enabled)) + except ValueError as exc: + return Response().error(str(exc)).__dict__ + + payload = await _get_command_payload(handler_full_name) + return Response().ok(payload).__dict__ + + async def rename_command(self): + data = await request.get_json() + handler_full_name = data.get("handler_full_name") + new_name = data.get("new_name") + keep_original = bool(data.get("keep_original_alias", False)) + + if not handler_full_name or not new_name: + return Response().error("handler_full_name 与 new_name 均为必填。").__dict__ + + try: + await rename_command_service(handler_full_name, new_name, keep_original) + except ValueError as exc: + return Response().error(str(exc)).__dict__ + + payload = await _get_command_payload(handler_full_name) + return Response().ok(payload).__dict__ + + +async def _get_command_payload(handler_full_name: str): + commands = await list_commands() + for cmd in commands: + if cmd["handler_full_name"] == handler_full_name: + return cmd + return {} diff --git a/astrbot/dashboard/server.py b/astrbot/dashboard/server.py index 84976f2ba..643e96542 100644 --- a/astrbot/dashboard/server.py +++ b/astrbot/dashboard/server.py @@ -63,6 +63,7 @@ class AstrBotDashboard: core_lifecycle, core_lifecycle.plugin_manager, ) + self.command_route = CommandRoute(self.context) self.cr = ConfigRoute(self.context, core_lifecycle) self.lr = LogRoute(self.context, core_lifecycle.log_broker) self.sfr = StaticFileRoute(self.context)