mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-11-03 06:04:20 +08:00
- PluginSlot:导入插件模块并在 Shadow DOM 中挂载 custom element,host / context 先于插入设置;加载失败、元素未定义或运行时报错只让该插件的挂载点显示「插件组件加载失败」 - AbHost:api 限定在 /api/v1/plugins/<id>/ 与只读 GET 的宿主 API;i18n、主题、toast;events.on 订阅 SSE 新增的 bus 帧(后端把总线事件转发给前端) - 五个挂载点:设置分区、番剧详情标签、卡片操作、侧边栏页面 /plugins/:id、首页小组件 - 未启用的内置 / 已允许的插件也能取得配置 schema,首次启用前即可填写配置 - Schema 表单支持对象数组(hardlink 的 path_map) - hardlink 插件自带 settings.section 元素「链接已有文件」,调用补链路由并显示计数 - examples/plugins/manual-pick:详情页标签示例,含插件路由与事件订阅 - 设计文档第 0 节记录调整,第 10 节标记 P6 已完成
49 lines
1.6 KiB
Python
49 lines
1.6 KiB
Python
"""示例插件:手动选种(前端挂载点 ``bangumi.detail.tab`` 的验收演示)。
|
|
|
|
前端组件(``web/index.js``)经宿主的只读 API 列出规则的种子,选择结果经本插件
|
|
自己的路由 ``/api/v1/plugins/manual-pick/picks/<bangumi_id>`` 保存到插件的键值
|
|
存储,并发布 ``manual-pick.picked`` 事件;打开着的详情页通过 ``host.events.on``
|
|
收到事件后刷新。SDK 0.x 没有「让下载器下载指定种子」的接口,所以这里只记录
|
|
选择,不触发下载。
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import ClassVar
|
|
|
|
from fastapi import APIRouter
|
|
from pydantic import BaseModel
|
|
|
|
from ab_sdk import Event, Plugin, points, provider
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class Picked(Event):
|
|
kind: ClassVar[str] = "manual-pick.picked"
|
|
|
|
bangumi_id: int
|
|
torrent_id: int
|
|
|
|
|
|
class Pick(BaseModel):
|
|
torrent_id: int
|
|
|
|
|
|
class ManualPick(Plugin):
|
|
@provider(points.API_ROUTER, id="api")
|
|
def api(self) -> APIRouter:
|
|
router = APIRouter()
|
|
|
|
@router.get("/picks/{bangumi_id}")
|
|
async def get_pick(bangumi_id: int) -> dict[str, int | None]:
|
|
return {"torrent_id": await self.ctx.kv.get(f"pick:{bangumi_id}")}
|
|
|
|
@router.put("/picks/{bangumi_id}")
|
|
async def put_pick(bangumi_id: int, body: Pick) -> dict[str, int]:
|
|
await self.ctx.kv.set(f"pick:{bangumi_id}", body.torrent_id)
|
|
self.ctx.bus.publish(
|
|
Picked(bangumi_id=bangumi_id, torrent_id=body.torrent_id)
|
|
)
|
|
return {"torrent_id": body.torrent_id}
|
|
|
|
return router
|