feat(plugins): 插件支持热加载与启用/停用清单
- pugins/__init__.py 重写:load_plugins / discover / set_enabled / reload
- 热加载:把 study_tool.pugins.<名字> 的模块从 sys.modules 摘掉后重新 import;
重载前先 registry.unregister 旧 id,平台 id 改了也不会留残影
- 启用清单存设置项 plugins({"disabled": [...]}):未列出的默认启用,新插件自动生效;
停用即从注册表摘掉,/api/platforms 与账号平台下拉同步消失
- platforms/registry.py 新增 unregister(pid)
- 新接口:GET /api/plugins、POST /api/plugins/{name}/enable|disable、
POST /api/plugins/reload、POST /api/plugins/{name}/reload;失败返回 ok=false
- 同步 docs/pugin.md(新增「加载与启停」)、docs/architecture.md、docs/OPTIMIZATION.md、AGENTS.md
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
"""课程 / 发现 / 学习 / 停止 / 抓包 / 快照 / 历史日志接口。"""
|
||||
"""课程 / 发现 / 学习 / 停止 / 抓包 / 快照 / 历史日志 / 插件管理接口。"""
|
||||
import threading
|
||||
import time
|
||||
|
||||
from fastapi.responses import HTMLResponse, JSONResponse
|
||||
from study_tool.webapp import app
|
||||
|
||||
from study_tool import store
|
||||
from study_tool import pugins, store
|
||||
from study_tool.capture import *
|
||||
from study_tool.config import *
|
||||
from study_tool.engine import study_worker
|
||||
@@ -25,6 +25,44 @@ def api_platforms():
|
||||
for p in registry.all()]}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ 插件管理
|
||||
# 插件目录 pugins/<名字>/,实现见 study_tool.pugins。
|
||||
|
||||
@app.get("/api/plugins")
|
||||
def api_plugins():
|
||||
"""磁盘上的插件清单:是否启用、是否已加载、加载后的 label 与 capabilities。"""
|
||||
return {"ok": True, "plugins": pugins.discover()}
|
||||
|
||||
|
||||
@app.post("/api/plugins/{name}/enable")
|
||||
def api_plugin_enable(name: str):
|
||||
return _plugin_call(lambda: pugins.set_enabled(name, True))
|
||||
|
||||
|
||||
@app.post("/api/plugins/{name}/disable")
|
||||
def api_plugin_disable(name: str):
|
||||
return _plugin_call(lambda: pugins.set_enabled(name, False))
|
||||
|
||||
|
||||
@app.post("/api/plugins/reload")
|
||||
def api_plugins_reload():
|
||||
"""重载全部已启用插件:改完插件代码不用重启服务。"""
|
||||
return _plugin_call(pugins.reload)
|
||||
|
||||
|
||||
@app.post("/api/plugins/{name}/reload")
|
||||
def api_plugin_reload(name: str):
|
||||
return _plugin_call(lambda: pugins.reload(name))
|
||||
|
||||
|
||||
def _plugin_call(fn):
|
||||
"""插件操作失败不抛 500,返回 ok=false 给前端提示。"""
|
||||
try:
|
||||
return {"ok": True, "plugins": fn()}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": str(e), "plugins": pugins.discover()}
|
||||
|
||||
|
||||
# ------------------------------------------------------------------ 运行日志 / 快照
|
||||
|
||||
@app.get("/api/log/history")
|
||||
|
||||
Reference in New Issue
Block a user