Phase 3: PluginWebMixin SDK + web plugin control panels

- New: sdk/plugin_web.py (PluginWebMixin: web pages, API routes, SSE)
- New: services/web_panel/routes/plugin_web.py (3 endpoints)
- New: plugins/example_plugin/dashboard.html (counter + SSE demo)
- Updated: example_plugin uses PluginWebMixin
- Tests: 28/28 passing
This commit is contained in:
2026-06-10 20:54:11 +08:00
parent c680fea8e0
commit e52f7f3566
7 changed files with 155 additions and 12 deletions
+2 -1
View File
@@ -5,7 +5,7 @@ import os
import logging
from pathlib import Path
from aiohttp import web
from .routes import auth, status, plugins, commands, logs, projects, proxy
from .routes import auth, status, plugins, commands, logs, projects, proxy, plugin_web
logger = logging.getLogger(__name__)
@@ -64,6 +64,7 @@ class WebPanelManager:
logs.setup_routes(app, self.base_path)
projects.setup_project_routes(app, self.sm)
proxy.setup_proxy_routes(app, self.sm)
plugin_web.setup_plugin_web_routes(app, self.sm)
# 注册日志广播
ls = self.sm.get_service("log")
+38
View File
@@ -0,0 +1,38 @@
from aiohttp import web
import json, logging
logger = logging.getLogger(__name__)
def setup_plugin_web_routes(app, service_manager):
async def plugin_page(request):
name = request.match_info.get("name","")
ps = service_manager.get_service("plugin")
plugin = ps.plugins.get(name)
if not plugin or not hasattr(plugin, "get_web_pages"):
return web.Response(text=f"Plugin {name} not found", status=404)
pages = plugin.get_web_pages()
if name in pages:
return web.Response(text=pages[name]["html"], content_type="text/html")
return web.json_response({"error": "no web page"})
async def plugin_sse(request):
name = request.match_info.get("name","")
ps = service_manager.get_service("plugin")
plugin = ps.plugins.get(name)
if plugin and hasattr(plugin, "handle_sse"):
return await plugin.handle_sse(request)
return web.json_response({"error": "SSE not supported"}, status=404)
async def plugin_event(request):
name = request.match_info.get("name","")
data = await request.json()
ps = service_manager.get_service("plugin")
plugin = ps.plugins.get(name)
if plugin and hasattr(plugin, "push_sse_event"):
await plugin.push_sse_event(data.get("type","event"), data)
return web.json_response({"ok": True})
return web.json_response({"ok": False}, status=404)
app.router.add_get("/plugin/{name}", plugin_page)
app.router.add_get("/plugin/{name}/sse", plugin_sse)
app.router.add_post("/plugin/{name}/event", plugin_event)
logger.info("Plugin web routes registered")