docs: align Bun, routing, browser validation and MoviePilot site provenance
This commit is contained in:
1 parent
e72983ecee
commit
55841402a6
23 files changed
+269
-162
No files matched your search
@@ -1,4 +1,4 @@
|
||||
# ADR-002:持久任务引擎采用 OpenWorkflow 0.10.1(锁版本),封装在 `TaskEngine` 端口之后
|
||||
# ADR-002:持久任务引擎采用 OpenWorkflow(锁版本),封装在 `TaskEngine` 端口之后
|
||||
|
||||
- 状态:已采纳(2026-09-27,W0-B spike 后)
|
||||
- 关联:REQ §11、`00-first-version-plan`(已删除,见 git `ceb66f8`) §1 与 §3.1-8、验证记录 spike `w0b-openworkflow`(已删除,见 git `ceb66f8`)、代码 `spikes/openworkflow/`(已删除,见 git `ceb66f8`)
|
||||
@@ -9,6 +9,8 @@ v0.1 采用 **`[email protected]`(精确锁版本)+ `postgres@^3.4.9`**,表放
|
||||
|
||||
暂不实现自研租约任务表。下文附录给出备选设计,只在触发复议条件时启用(REQ §11.1:"只保留清晰的执行接口,不提前实现第二套引擎")。
|
||||
|
||||
2026-11-05 更新:当前精确锁定 `[email protected]` 与 `[email protected]`,原有端口和业务状态归属不变。新版本使用并发索引迁移,可能等待其它测试 schema 的长事务快照;server 的 `pg` 组改为文件串行,独立 schema 的隔离约定保留。下表记录最初 0.10.1 的验证结论,当前回归以 `bun run ci` 的任务引擎与 server 测试为准。
|
||||
|
||||
## 验证结论摘要
|
||||
|
||||
| 项 | 结果 | 对接入的约束 |
|
||||
|
||||
@@ -84,7 +84,7 @@ faux.setResponses([
|
||||
| 重试 | `retry: { enabled, maxRetries, baseDelayMs }`、`streamOptions.timeoutMs` |
|
||||
| 子代理开关 | **SDK 不提供**。由我们实现一个 `agent.delegate` 能力:开新 lane 或新会话,继承父任务的授权上限、预算和取消状态;默认关闭 |
|
||||
|
||||
## 已知限制
|
||||
## 初次接入时的限制(历史)
|
||||
|
||||
- 0.x 版本,存储格式 4 仍是 WIP,可能原地改变。锁精确版本,升级后跑 agent 与 server 的 Pi 相关测试(`deno task test:all`)。
|
||||
- 没有子代理,没有 PG 会话存储,`watchSession` 未实现。
|
||||
@@ -94,6 +94,8 @@ faux.setResponses([
|
||||
|
||||
## 2026-10-08 迁到 pi-durable
|
||||
|
||||
2026-11-05 更新:当前 `pi-durable`、`pi-ai`、`chord` 均精确锁定 1.3.0。适配层按新版 `ToolExecutionResult` 返回 `output` 内容块,正常结果与错误结果使用同一字段;对外 `AgentRuntimePort` 与会话目录约定保留。以下记录 1.1.0 迁入时的设计。
|
||||
|
||||
pi-agent-core 1.0 删掉了 harness(AgentHarness、会话存储、压缩、skills、系统提示等),只剩 `Agent` 与循环;harness 搬到 `@earendil-works/pi-durable`(实验性,版本之间 API 会变)。我们改为:
|
||||
|
||||
- 依赖锁精确版本:`@earendil-works/[email protected]`、`@earendil-works/[email protected]`、`@earendil-works/[email protected]`(pi-durable 的 Context / 文档状态),**移除** pi-agent-core。Pi 的类型仍只出现在 `packages/agent/src/pi/*`(另有 `prompt/skills.ts` 的格式约定),对外只有 `AgentRuntimePort`,端口与 `AgentRunEvent` 合同不变(`tool_call_end` 只新增可选 `durationMs`)。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# ADR-007: Bun 1.4.3 与 Linux 解析沙箱
|
||||
# ADR-007: Bun 1.4.4 与 Linux 解析沙箱
|
||||
|
||||
状态:采纳。取代 ADR-004 的运行时、依赖安装与编译方式;更新 ADR-005 的权限隔离实现。
|
||||
|
||||
后端、前端开发工具及 Vitest 使用 Bun 1.4.3。根 package.json 管理 workspace 与统一依赖,bun.lock 锁定解析结果。.bun-version、packageManager 与 Docker 构建镜像固定同一版本。现有业务依赖版本保持不变。
|
||||
后端、前端开发工具及 Vitest 使用 Bun 1.4.4。根 package.json 管理 workspace 与统一依赖,bun.lock 锁定解析结果。.bun-version、packageManager 与 Docker 构建镜像固定同一版本。运行时迁移时保持原业务依赖版本;后续升级在 manifest 与锁文件中显式维护,Pi 1.3 与 OpenWorkflow 0.11 的适配见 ADR-003、ADR-002。
|
||||
|
||||
Deno 全局调用改为 Node API 或 @umt/runtime 中的 Bun HTTP、WebSocket、子进程与流适配。HTTP 出口使用 proxy:false 强制直连,显式代理使用 respectNoProxy:false;环境代理由现有出口选择函数处理。
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
|
||||
| 路 | 范围 | 文件 | 预估 |
|
||||
| --- | --- | --- | --- |
|
||||
| A 导航 / 路由 / 重定向 | 新 `NAV_GROUPS`、新路由表、旧链接重定向、`findNavItem` 与面包屑、全站 `consolePath` 调用点替换 | `components/console/nav.ts`、`nav.test.ts`、`app/routes.ts`、`routes/console/layout.tsx`、新 `routes/console/redirects.ts`、`home.tsx` 等内部链接 | 0.5–1 天 |
|
||||
| A 导航 / 路由 / 重定向 | 新 `NAV_GROUPS`、新路由表、旧链接重定向、`findNavItem` 与面包屑、全站 `consolePath` 调用点替换 | `components/console/nav.ts`、`nav.test.ts`、`app/router.tsx`、`routes/console/layout.tsx`、新 `routes/console/redirects.ts`、`home.tsx` 等内部链接 | 0.5–1 天 |
|
||||
| B 设置页 + contracts | `settings.tsx` 改为 `settings/:section` 布局;按 3.4 重组现有表单卡片;新增站点登记表单、元数据分区、账户分区;`SETTINGS_SECTIONS` 与字段归属测试 | `routes/console/settings*.tsx`、`routes/console/settings/*.tsx`、`packages/contracts/src/settings.ts`(+ test)、`api/settings.ts`、`api/sites.ts` | 1.5–2 天 |
|
||||
| C 页面合并 / 拆分 | 任务页拆成 `downloads`(含 plans)与 `tasks`;订阅页拆出 `rules`;站点详情加"快照与 Feed / 账号"Tab,来源页收窄为健康总表;身份页"未识别"标记待处理;下载队列页头缓存水位条 | `routes/console/tasks*.tsx` → 新 `downloads*.tsx`、`subscriptions.tsx` → 新 `rules.tsx`、`sites.$siteId.tsx`、`sources.tsx`、`identity.tsx`、`components/workbench/*` | 2 天 |
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
| `/console/sources?tab=snapshots&siteId=x` | `/console/sites/x?tab=snapshots` | `sources.tsx` clientLoader;无 siteId 留在来源健康 |
|
||||
| `/console/settings?tab=*` | `/console/settings#<分区>[/<节>]` | IA-2:`settings.tsx` clientLoader;W8-A 起 `settingsPath()` 直接生成 hash |
|
||||
|
||||
`nav.test.ts` 断言每个导航项、每个重定向目标都在 `routes.ts` 里;冒烟(`scripts/smoke.mjs` 的 `REDIRECT_ROUTES`)逐条打开旧地址,确认落到新地址且 200。
|
||||
`nav.test.ts` 断言每个导航项、每个重定向目标都在 `router.tsx` 里;冒烟(`scripts/smoke.mjs` 的 `REDIRECT_ROUTES`)逐条打开旧地址,确认落到新地址且 200。
|
||||
|
||||
### 6.3 页面合并 / 拆分
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> 迁入自 /opt/uhd_web `docs/features/`(2026-09-27),2026-10-08 与 uhd_web 同步。文中流媒体、播放器、落地页、套餐等段落是 uhd_web 的原始上下文,本项目没有这些页面,只作材质与 token 用法参考;以本目录 README 的约定为准。
|
||||
|
||||
配合[设计 token](design-tokens.md)与[界面材质](interface-materials.md)。开发态的陈列页 `/dev/ui`(只在开发构建注册,[routes.ts](../../apps/web/app/routes.ts))把三块壳下的 token、材质和控件排在一页,换皮或改 token 先看它。
|
||||
配合[设计 token](design-tokens.md)与[界面材质](interface-materials.md)使用。控制台的实际控件以 `apps/web/app/components/ui/` 为准。
|
||||
|
||||
## 按钮只有一套
|
||||
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
### 进行中
|
||||
|
||||
- 系统梳理后的待办:[system-review.md](system-review.md),T0~T6 按优先级。
|
||||
- 补字幕:[subtitles.md](subtitles.md),第 1、2 步已完成;待办:以后接进整理 / 订阅工作流。
|
||||
- 补字幕:[subtitles.md](subtitles.md),手动上传、SubHD/字幕库及 M-Team 在线搜索下载已完成;待办:接进整理 / 订阅工作流。
|
||||
- 沙箱第二批:站点网页、RSS、网页抓取的 HTML / XML 解析迁入常驻子进程池(ADR-005)。
|
||||
|
||||
### 业务(需要真实环境或决定)
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
- 语言:先看文件名标签(chs / cht / 简体 / 繁體 / eng / 双语 …),再看内容(CJK、假名、谚文、繁体常用字比例);中英双语按简中处理(与整理规则一致)。
|
||||
- 季集:用文件名解析(复用资源名解析器);电影只有一个目标。对不上的留空让人选;同一集多个字幕按语言区分,同语言重复的提示。
|
||||
|
||||
## 在线(SubHD、字幕库)
|
||||
## 在线(SubHD、字幕库、M-Team)
|
||||
|
||||
- M-Team:已启用的 PT 站沿用站点账号、API 地址、代理、UA 和共享限流参与搜索,无须再登记字幕站。搜索结果使用稳定字幕 ID,不预先获取下载签名;点击下载时现场换签,后续沙箱解析、配对、写入与撤销沿用同一流程。历史来源为 `mteam`,迁移 `0096` 扩展来源约束;未接入自动补字幕。
|
||||
|
||||
- 搜索词:作品中文名、原名、年份,剧集带季号;结果按标题与季集匹配度排序,对不上的不列。
|
||||
- 验证码:① 代码识别(SubHD SVG 路径长度表、字幕库 BMP 采样模板,在沙箱里);② 没过就由智能体视觉在浏览器里接管;③ 智能体也没过就转人工。
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
## 1. 核对结论
|
||||
|
||||
2026-11-06 站点适配增量使用 MoviePilot v3.2.4(`3b156a545f14fea0285cd3ed3ea4aa49d97faa57`),根 LICENSE 仍为 GPLv3。按公开代码行为维护 TS 实现,没有复制 Python 文件、解密站点数据或引入闭源模块;新增 Milkie 为手写 API 定义,来源随定义登记。逐文件基线见 [mp-sync](mp-sync-ledger.md),以下表格保留最初来源核查的历史上下文。
|
||||
|
||||
| 项 | MoviePilot | MovieClaw |
|
||||
| --- | --- | --- |
|
||||
| 仓库 | `https://github.com/jxxghp/MoviePilot`(分支 `v3`) | `https://github.com/movieclaw/movieclaw`(`main`) |
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
> 格式:REQ §14.1.2 迁移交付规范。只做行为对照与 TS 重写,**不复制上游文件**(许可边界见 `license-and-provenance.md`)。
|
||||
> 本文件是研发对照记录,不表示对应 TS 模块已实现或已逐函数核验。
|
||||
|
||||
2026-11-06 站点框架已增量核对到 MoviePilot v3.2.4(`3b156a5`),当前实现、来源文件与保留差异见 [跟随移植账本](mp-sync-ledger.md#3-当前对照总表)。下文保留首次移植的 `e6820a8` 函数和行号记录,不作为当前全部适配状态。下载端口已改用共用 `SourcesRuntime` 的站点出口、有效凭据与 PG 限流;M-Team 字幕 API 接入现有在线补字幕流程。
|
||||
|
||||
## 0. 来源与版本
|
||||
|
||||
| 项 | 值 |
|
||||
|
||||
@@ -10,83 +10,101 @@
|
||||
|
||||
## 2. 用法
|
||||
|
||||
MP 本地仓库默认 `/opt/moviepilot-plus/upstream/MoviePilot`(浅克隆,当前 `e6820a8`)。以下命令 Node 24 或 `deno run -A` 均可(不依赖根 package.json / deno.json 任务)。
|
||||
MP 本地仓库默认 `/opt/moviepilot-plus/upstream/MoviePilot`(早期浅克隆,`e6820a8`)。用仓库锁定的 Bun 运行脚本;核查其他 checkout 时显式传 `--mp <路径>`,每个条目的已同步提交由下表单独记录。
|
||||
|
||||
```bash
|
||||
# 1) 取上游新提交(浅克隆)
|
||||
git -C /opt/moviepilot-plus/upstream/MoviePilot fetch --depth=1 origin <新提交或 v3>
|
||||
# 2) 查差异:已变更 / 已删除 / 监视目录新增,附逐文件 git diff 命令;有变化退出码 1
|
||||
node scripts/mp-sync/check.mjs --to <新提交> # 或 --mp <路径> --json
|
||||
bun scripts/mp-sync/check.mjs --to <新提交> # 或 --mp <路径> --json
|
||||
# 3) 按 diff 增量移植 TS 文件,把文件头 @mp-source 的提交号改为新提交(新文件加标签)
|
||||
# 4) 重建 ledger 与下表
|
||||
node scripts/mp-sync/build-ledger.mjs --commit <新提交>
|
||||
bun scripts/mp-sync/build-ledger.mjs --commit <新提交>
|
||||
# 5) 跑适配器测试
|
||||
cd packages/adapters && deno run -A npm:vitest run src/sites
|
||||
cd packages/adapters && bun x --bun vitest run src/sites
|
||||
```
|
||||
|
||||
MovieClaw 站点定义(与 MP 无关,但同属站点框架跟随工具):
|
||||
|
||||
```bash
|
||||
node scripts/mp-sync/movieclaw-import.mjs # 从 v0.27.0 重新转换 23 个站点定义(覆盖层:scripts/mp-sync/movieclaw-overrides/)
|
||||
node scripts/mp-sync/movieclaw-import.mjs --check # 只比较,有差异退出码 1
|
||||
bun scripts/mp-sync/movieclaw-import.mjs # 从 v0.27.0 重新转换 23 个站点定义(覆盖层:scripts/mp-sync/movieclaw-overrides/)
|
||||
bun scripts/mp-sync/movieclaw-import.mjs --check # 只比较,有差异退出码 1
|
||||
```
|
||||
|
||||
## 3. 当前对照总表
|
||||
|
||||
2026-11-06 核对 GitHub 最新稳定发布 [v3.2.4](https://github.com/jxxghp/MoviePilot/releases/tag/v3.2.4),固定提交 `3b156a545f14fea0285cd3ed3ea4aa49d97faa57`。本轮同步站点索引、用户解析与共享频控涉及的 42 个来源文件;其余 12 个媒体服务器、RSS、下载编排、文件管理、TMDB 与通用语料条目保留原基线,不据此宣称全应用已追平。
|
||||
|
||||
| 范围 | 本次同步 |
|
||||
| --- | --- |
|
||||
| 资源搜索 | 新增 Milkie;M-Team、HDDolby、Yema 分类透传与 API 地址覆盖;TNode 会话隔离;通用 XML/RSS、空 Feed 与无服务端分页的关键词窗口 |
|
||||
| 用户数据 | NexusPHP UUID、专用做种入口与流量回填;Audiences 顶栏用户识别;Discuz 分享率、Unit3D 用户名 ID 与积分入口;M-Team 等级名、空做种页停止;HDDolby API 前缀及受限 schema 回退 |
|
||||
| 公共请求 | 复用既有 `site:<数据库 ID>` 的 PG 桶;种子下载使用同一出口、账号 UA 和有效凭据;远端频控保留原因与冷却,错误页面标题脱敏 |
|
||||
| M-Team 字幕 | API 搜索、按种子列字幕和下载接入现有补字幕流程;来源枚举与迁移 `0096`,解析、写入、撤销沿用现有服务 |
|
||||
|
||||
保留项目边界:站点定义继续来自已核实的 MovieClaw MIT 快照与手写定义,不使用 MP 加密资源;MoviePilot 的采集器迁到 [MoviePilot-Site-Collector](https://github.com/jxxghp/MoviePilot-Site-Collector),该工具的迁移不代表站点配置变为可直接导入。Milkie 默认未启用。API Key、Cookie 和下载签名不进入搜索结果或历史;M-Team 字幕搜索只返回稳定 ID,下载时现场换签。无 Cookie 的签名下载不复用浏览器 profile,CDN 跳转也不转发账号凭据。
|
||||
|
||||
Audiences 的 compact 指标使用局部 XPath,比上游仍可能回到整文档的绝对 XPath 更严格,避免列表卡片污染当前用户数据。分页上限、ID 字符串化、缺失数值归一及确定性绝对日期解析延续既有合同。Python 类型整理、httpx 连接池恢复和 dateparser 语言加载属于上游实现细节,不另造对应 TS 机制。
|
||||
|
||||
已用 21 个自编 HTML/JSON 案例动态运行固定上游解析器做差分,按合同归一后 21/21 一致;自动化站点与字幕回归使用模拟请求及隔离数据库。真实 PT 账号、站点挑战和端到端下载仍需各自现场验收,未计入这些自动化结论。
|
||||
|
||||
<!-- mp-sync:table:begin -->
|
||||
共 51 个上游文件(`adapters/` = `packages/adapters/src/`)。
|
||||
共 54 个上游文件(`adapters/` = `packages/adapters/src/`)。
|
||||
|
||||
| 上游文件 | 本项目文件 | 移植提交 | sha256(前 12 位) | 来源 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `app/adapters/network/cloudflare.py` | `adapters/sites/user-parsers/common.ts` | `e6820a8` | `a23a2c44da05` | tag |
|
||||
| `app/adapters/network/cloudflare.py` | `adapters/sites/user-parsers/common.ts` | `3b156a5` | `c50274ad9e69` | tag |
|
||||
| `app/application/mediaserver.py` | `adapters/emby/client.ts` | `e6820a8` | `f034f0be8ba6` | manual |
|
||||
| `app/application/rss.py` | `adapters/rss/fetch.ts`<br>`adapters/rss/parse.ts`<br>`adapters/rss/rss-link.ts` | `e6820a8` | `8ea70f712512` | manual |
|
||||
| `app/application/site/sites.pyi` | `adapters/sites/definitions/schema.ts`<br>`adapters/sites/registry.ts`<br>`adapters/sites/spider/schema.ts` | `e6820a8` | `8fea9a239354` | manual |
|
||||
| `app/application/site/sites.pyi` | `adapters/sites/definitions/schema.ts`<br>`adapters/sites/registry.ts`<br>`adapters/sites/spider/schema.ts` | `3b156a5` | `b3f0ded80227` | manual |
|
||||
| `app/application/site/throttle.py` | `apps/server/src/modules/acquisition-organize/ports.ts`<br>`adapters/sites/rate-limit.ts` | `3b156a5` | `6ed524a1c2b4` | manual |
|
||||
| `app/application/torrent/download.py` | `adapters/sites/http.ts` | `3b156a5` | `11affe81a5af` | manual |
|
||||
| `app/chain/download/submission.py` | `adapters/sites/mteam/adapter.ts`<br>`adapters/sites/spider/adapter.ts`<br>`adapters/sites/spiders/common.ts` | `e6820a8` | `f7cb870e47d6` | manual+tag |
|
||||
| `app/domain/site.py` | `adapters/sites/user-parsers/common.ts` | `e6820a8` | `650c795a4def` | tag |
|
||||
| `app/foundation/dom.py` | `adapters/sites/user-parsers/dom.ts` | `e6820a8` | `6d6accf2cef1` | tag |
|
||||
| `app/foundation/size.py` | `adapters/sites/spider/spider.ts` | `e6820a8` | `7b0b8f50588c` | manual |
|
||||
| `app/foundation/temporal.py` | `adapters/sites/spiders/common.ts`<br>`adapters/sites/user-parsers/common.ts` | `e6820a8` | `74941f460e40` | tag |
|
||||
| `app/foundation/text.py` | `adapters/sites/user-parsers/common.ts` | `e6820a8` | `a88c75dc8431` | tag |
|
||||
| `app/domain/site.py` | `adapters/sites/user-parsers/common.ts` | `3b156a5` | `5e6b8ebcce64` | tag |
|
||||
| `app/foundation/dom.py` | `adapters/sites/user-parsers/dom.ts` | `3b156a5` | `38b63b12ee03` | tag |
|
||||
| `app/foundation/size.py` | `adapters/sites/spider/spider.ts` | `3b156a5` | `ee3289e2cbdd` | manual |
|
||||
| `app/foundation/temporal.py` | `adapters/sites/spiders/common.ts`<br>`adapters/sites/user-parsers/common.ts` | `3b156a5` | `237d9f55de13` | tag |
|
||||
| `app/foundation/text.py` | `adapters/sites/user-parsers/common.ts` | `3b156a5` | `8d8c5ed7aa81` | tag |
|
||||
| `app/modules/__init__.py` | `adapters/qbittorrent/paths.ts` | `e6820a8` | `2edada0ea591` | manual |
|
||||
| `app/modules/_base/downloader.py` | `adapters/qbittorrent/torrent.ts` | `e6820a8` | `84bd8946c8b2` | manual |
|
||||
| `app/modules/emby/emby.py` | `adapters/emby/client.ts` | `e6820a8` | `e6468ea34ef2` | manual |
|
||||
| `app/modules/filemanager/storages/local.py` | `adapters/fs/copy.ts`<br>`adapters/fs/move.ts` | `e6820a8` | `806a1970ca8e` | manual |
|
||||
| `app/modules/filemanager/transhandler.py` | `adapters/fs/move.ts` | `e6820a8` | `13e2bba491ac` | manual |
|
||||
| `app/modules/indexer/__init__.py` | `adapters/sites/registry.ts`<br>`adapters/sites/spider/adapter.ts`<br>`adapters/sites/spiders/adapter.ts`<br>`adapters/sites/spiders/index.ts`<br>`adapters/sites/spiders/map.ts`<br>`adapters/sites/spiders/types.ts`<br>`adapters/sites/user-parsers/registry.ts` | `e6820a8` | `e9c5d15fdaa5` | manual+tag |
|
||||
| `app/modules/indexer/parser/__init__.py` | `adapters/sites/user-parsers/base.ts`<br>`adapters/sites/user-parsers/types.ts` | `e6820a8` | `0e6c4215b713` | tag |
|
||||
| `app/modules/indexer/parser/bitpt.py` | `adapters/sites/user-parsers/bitpt.ts` | `e6820a8` | `871d25e570f1` | tag |
|
||||
| `app/modules/indexer/parser/discuz.py` | `adapters/sites/user-parsers/discuz.ts` | `e6820a8` | `12277ba955ce` | tag |
|
||||
| `app/modules/indexer/parser/file_list.py` | `adapters/sites/user-parsers/file-list.ts` | `e6820a8` | `f92e65ed7327` | tag |
|
||||
| `app/modules/indexer/parser/gazelle.py` | `adapters/sites/user-parsers/gazelle.ts` | `e6820a8` | `c10e5246724b` | tag |
|
||||
| `app/modules/indexer/parser/hddolby.py` | `adapters/sites/user-parsers/hddolby.ts` | `e6820a8` | `a4336d92d603` | tag |
|
||||
| `app/modules/indexer/parser/ipt.py` | `adapters/sites/user-parsers/ipt.ts` | `e6820a8` | `2b9d04d76606` | tag |
|
||||
| `app/modules/indexer/parser/mtorrent.py` | `adapters/sites/user-parsers/mtorrent.ts` | `e6820a8` | `c5d5a3c6f9f5` | tag |
|
||||
| `app/modules/indexer/parser/nexus_audiences.py` | `adapters/sites/user-parsers/nexus-audiences.ts` | `e6820a8` | `1a2d104db769` | tag |
|
||||
| `app/modules/indexer/parser/nexus_hhanclub.py` | `adapters/sites/user-parsers/nexus-hhanclub.ts` | `e6820a8` | `8850619069d4` | tag |
|
||||
| `app/modules/indexer/parser/nexus_php.py` | `adapters/sites/user-parsers/nexus-php.ts` | `e6820a8` | `39303ae96d9c` | tag |
|
||||
| `app/modules/indexer/parser/nexus_project.py` | `adapters/sites/user-parsers/nexus-project.ts` | `e6820a8` | `2b5508cfb2f8` | tag |
|
||||
| `app/modules/indexer/parser/nexus_rabbit.py` | `adapters/sites/user-parsers/nexus-rabbit.ts` | `e6820a8` | `09149b89a7c7` | tag |
|
||||
| `app/modules/indexer/parser/rousi.py` | `adapters/sites/user-parsers/rousi.ts` | `e6820a8` | `1b1ea93de084` | tag |
|
||||
| `app/modules/indexer/parser/small_horse.py` | `adapters/sites/user-parsers/small-horse.ts` | `e6820a8` | `b73b5de97737` | tag |
|
||||
| `app/modules/indexer/parser/sunnypt.py` | `adapters/sites/user-parsers/sunnypt.ts` | `e6820a8` | `937f8453fa2b` | tag |
|
||||
| `app/modules/indexer/parser/tnode.py` | `adapters/sites/user-parsers/tnode.ts` | `e6820a8` | `c9cb809fc4bf` | tag |
|
||||
| `app/modules/indexer/parser/torrent_leech.py` | `adapters/sites/user-parsers/torrent-leech.ts` | `e6820a8` | `72d1473a3bba` | tag |
|
||||
| `app/modules/indexer/parser/unit3d.py` | `adapters/sites/user-parsers/unit3d.ts` | `e6820a8` | `9a4d579deca5` | tag |
|
||||
| `app/modules/indexer/parser/yema.py` | `adapters/sites/user-parsers/yema.ts` | `e6820a8` | `0f98fd580bad` | tag |
|
||||
| `app/modules/indexer/parser/zhixing.py` | `adapters/sites/user-parsers/zhixing.ts` | `e6820a8` | `90c8954e7387` | tag |
|
||||
| `app/modules/indexer/spider/__init__.py` | `adapters/sites/spider/map.ts`<br>`adapters/sites/spider/schema.ts`<br>`adapters/sites/spider/spider.ts`<br>`adapters/sites/spider/template.ts` | `e6820a8` | `2513d962fa43` | manual |
|
||||
| `app/modules/indexer/spider/haidan.py` | `adapters/sites/spiders/haidan.ts` | `e6820a8` | `75eb802f19f0` | tag |
|
||||
| `app/modules/indexer/spider/hddolby.py` | `adapters/sites/spiders/hddolby.ts` | `e6820a8` | `46a50bd8d49f` | tag |
|
||||
| `app/modules/indexer/spider/mtorrent.py` | `adapters/sites/mteam/adapter.ts`<br>`adapters/sites/mteam/client.ts`<br>`adapters/sites/mteam/spider.ts`<br>`adapters/sites/spiders/mtorrent.ts` | `e6820a8` | `a8ab2b822cb2` | manual+tag |
|
||||
| `app/modules/indexer/spider/rousi.py` | `adapters/sites/spiders/rousi.ts` | `e6820a8` | `aa13c386a560` | tag |
|
||||
| `app/modules/indexer/spider/sunnypt.py` | `adapters/sites/spiders/sunnypt.ts` | `e6820a8` | `735b0d721e65` | tag |
|
||||
| `app/modules/indexer/spider/tnode.py` | `adapters/sites/spiders/tnode.ts` | `e6820a8` | `a3634a268dba` | tag |
|
||||
| `app/modules/indexer/spider/torrentleech.py` | `adapters/sites/spiders/torrentleech.ts` | `e6820a8` | `c965f2bcaea4` | tag |
|
||||
| `app/modules/indexer/spider/yema.py` | `adapters/sites/spiders/yema.ts` | `e6820a8` | `560b62c1ff10` | tag |
|
||||
| `app/modules/indexer/__init__.py` | `adapters/sites/registry.ts`<br>`adapters/sites/spider/adapter.ts`<br>`adapters/sites/spiders/adapter.ts`<br>`adapters/sites/spiders/index.ts`<br>`adapters/sites/spiders/map.ts`<br>`adapters/sites/spiders/types.ts`<br>`adapters/sites/user-parsers/registry.ts` | `3b156a5` | `4366034bdc25` | manual+tag |
|
||||
| `app/modules/indexer/parser/__init__.py` | `adapters/sites/user-parsers/base.ts`<br>`adapters/sites/user-parsers/types.ts` | `3b156a5` | `c6d7e45058cf` | tag |
|
||||
| `app/modules/indexer/parser/bitpt.py` | `adapters/sites/user-parsers/bitpt.ts` | `3b156a5` | `daccec01e01d` | tag |
|
||||
| `app/modules/indexer/parser/discuz.py` | `adapters/sites/user-parsers/discuz.ts` | `3b156a5` | `f056cb1f3691` | tag |
|
||||
| `app/modules/indexer/parser/file_list.py` | `adapters/sites/user-parsers/file-list.ts` | `3b156a5` | `1e101fe651f5` | tag |
|
||||
| `app/modules/indexer/parser/gazelle.py` | `adapters/sites/user-parsers/gazelle.ts` | `3b156a5` | `37d6b2017708` | tag |
|
||||
| `app/modules/indexer/parser/hddolby.py` | `adapters/sites/user-parsers/hddolby.ts` | `3b156a5` | `1a9f885333c3` | tag |
|
||||
| `app/modules/indexer/parser/ipt.py` | `adapters/sites/user-parsers/ipt.ts` | `3b156a5` | `fffccd341ace` | tag |
|
||||
| `app/modules/indexer/parser/mtorrent.py` | `adapters/sites/user-parsers/mtorrent.ts` | `3b156a5` | `1f35d41add01` | tag |
|
||||
| `app/modules/indexer/parser/nexus_audiences.py` | `adapters/sites/user-parsers/nexus-audiences.ts` | `3b156a5` | `7b53f3c76c5e` | tag |
|
||||
| `app/modules/indexer/parser/nexus_hhanclub.py` | `adapters/sites/user-parsers/nexus-hhanclub.ts` | `3b156a5` | `320c0979c192` | tag |
|
||||
| `app/modules/indexer/parser/nexus_php.py` | `adapters/sites/user-parsers/nexus-php.ts` | `3b156a5` | `8581be9deb8f` | tag |
|
||||
| `app/modules/indexer/parser/nexus_project.py` | `adapters/sites/user-parsers/nexus-project.ts` | `3b156a5` | `5bf6662060df` | tag |
|
||||
| `app/modules/indexer/parser/nexus_rabbit.py` | `adapters/sites/user-parsers/nexus-rabbit.ts` | `3b156a5` | `3d5434742282` | tag |
|
||||
| `app/modules/indexer/parser/rousi.py` | `adapters/sites/user-parsers/rousi.ts` | `3b156a5` | `f1ee95dfef78` | tag |
|
||||
| `app/modules/indexer/parser/small_horse.py` | `adapters/sites/user-parsers/small-horse.ts` | `3b156a5` | `adb5efa1f74e` | tag |
|
||||
| `app/modules/indexer/parser/sunnypt.py` | `adapters/sites/user-parsers/sunnypt.ts` | `3b156a5` | `c5449afb4930` | tag |
|
||||
| `app/modules/indexer/parser/tnode.py` | `adapters/sites/user-parsers/tnode.ts` | `3b156a5` | `699061470045` | tag |
|
||||
| `app/modules/indexer/parser/torrent_leech.py` | `adapters/sites/user-parsers/torrent-leech.ts` | `3b156a5` | `cf0debbfacd9` | tag |
|
||||
| `app/modules/indexer/parser/unit3d.py` | `adapters/sites/user-parsers/unit3d.ts` | `3b156a5` | `cfa271284dcb` | tag |
|
||||
| `app/modules/indexer/parser/yema.py` | `adapters/sites/user-parsers/yema.ts` | `3b156a5` | `da2a09e2d855` | tag |
|
||||
| `app/modules/indexer/parser/zhixing.py` | `adapters/sites/user-parsers/zhixing.ts` | `3b156a5` | `00de9540751f` | tag |
|
||||
| `app/modules/indexer/spider/__init__.py` | `adapters/sites/spider/map.ts`<br>`adapters/sites/spider/schema.ts`<br>`adapters/sites/spider/spider.ts`<br>`adapters/sites/spider/template.ts` | `3b156a5` | `2456e822939b` | manual+tag |
|
||||
| `app/modules/indexer/spider/haidan.py` | `adapters/sites/spiders/haidan.ts` | `3b156a5` | `315f775c3413` | tag |
|
||||
| `app/modules/indexer/spider/hddolby.py` | `adapters/sites/spiders/hddolby.ts` | `3b156a5` | `f0f6e9467f4a` | tag |
|
||||
| `app/modules/indexer/spider/milkie.py` | `adapters/sites/spiders/milkie.ts` | `3b156a5` | `8e967235574f` | tag |
|
||||
| `app/modules/indexer/spider/mtorrent.py` | `adapters/sites/mteam/adapter.ts`<br>`adapters/sites/mteam/client.ts`<br>`adapters/sites/mteam/definition.ts`<br>`adapters/sites/mteam/spider.ts`<br>`adapters/sites/mteam/subtitles.ts`<br>`adapters/sites/spiders/mtorrent.ts` | `3b156a5` | `6a07b5d161e9` | manual+tag |
|
||||
| `app/modules/indexer/spider/rousi.py` | `adapters/sites/spiders/rousi.ts` | `3b156a5` | `20f046e4be62` | tag |
|
||||
| `app/modules/indexer/spider/sunnypt.py` | `adapters/sites/spiders/sunnypt.ts` | `3b156a5` | `3b8c98086932` | tag |
|
||||
| `app/modules/indexer/spider/tnode.py` | `adapters/sites/spiders/tnode.ts` | `3b156a5` | `fe0641b3c6bc` | tag |
|
||||
| `app/modules/indexer/spider/torrentleech.py` | `adapters/sites/spiders/torrentleech.ts` | `3b156a5` | `b6c794453473` | tag |
|
||||
| `app/modules/indexer/spider/yema.py` | `adapters/sites/spiders/yema.ts` | `3b156a5` | `4ed0234b9201` | tag |
|
||||
| `app/modules/qbittorrent/qbittorrent.py` | `adapters/qbittorrent/client.ts`<br>`adapters/qbittorrent/state.ts` | `e6820a8` | `ab02e97e986f` | manual |
|
||||
| `app/modules/themoviedb/tmdbapi.py` | `adapters/tmdb/client.ts`<br>`adapters/tmdb/match.ts` | `e6820a8` | `787553a6f57d` | manual |
|
||||
| `app/schemas/site.py` | `adapters/sites/user-parsers/types.ts` | `e6820a8` | `e7952ed40b7b` | tag |
|
||||
| `app/schemas/site.py` | `adapters/sites/user-parsers/types.ts` | `3b156a5` | `78739bcb7d79` | tag |
|
||||
| `tests/cases/meta.py` | `packages/domain/test/differential/meta-mp.json`<br>`packages/domain/test/differential/meta-samples.json` | `e6820a8` | `3af375cf2c43` | manual |
|
||||
| `tests/test_rust_accel.py` | `packages/adapters/test/differential/indexer.json`<br>`scripts/mp-sync/gen-differential.py` | `e6820a8` | `0259f245d278` | manual |
|
||||
<!-- mp-sync:table:end -->
|
||||
|
||||
@@ -27,7 +27,7 @@ docker compose --env-file .env.deploy ps camofox # healthy
|
||||
```
|
||||
|
||||
上游不发布镜像。compose 缺省用的是**浏览器桌面镜像** `umt-browser-desktop:1.18.0`(`docker/browser-desktop`,§8),
|
||||
当前默认版本为 1.18.0,构建补丁、锁文件和 Playwright 1.60 协议兼容例外见 [镜像说明](../../docker/camofox/README.md)。以下旧日期的验收表保留历史版本。
|
||||
当前默认源码版本为 1.18.0,构建补丁、锁文件和 Playwright peer 上限见 [镜像说明](../../docker/camofox/README.md)。以下旧日期的验收表保留历史版本。
|
||||
|
||||
它从纯截图镜像 `camofox-browser:1.18.0` 复制 camofox,所以**先构建基础镜像**:`docker/camofox/Dockerfile` 从 git tag `v1.18.0`
|
||||
构建(修了上游 Dockerfile 的两个问题,见文件头)。首次构建要从 GitHub 拉源码与约 630 MB 的 Camoufox 浏览器包:
|
||||
@@ -691,7 +691,7 @@ camofox 按 **API 调用**判断活动,有三道空闲回收(`docker-compose.yml
|
||||
|
||||
## 16 2026-10-01 的 1.18 升级复测
|
||||
|
||||
当前默认桌面镜像为 `umt-browser-desktop:1.18.0`,基础镜像 `camofox-browser:1.18.0` 锁定上游 `f94c81babf4bfd44cdd4bd46e1f2e1fb1d91c753`。Node 24.21.0、Camoufox 152.0.4-beta.30、camoufox-js 0.12.0;Playwright 保持官方协议可兼容的 1.60.0,原因和独立锁见 [构建说明](../../docker/camofox/README.md)。
|
||||
当前默认桌面镜像为 `umt-browser-desktop:1.18.0`,基础镜像 `camofox-browser:1.18.0` 锁定上游 `f94c81babf4bfd44cdd4bd46e1f2e1fb1d91c753`。当前依赖锁使用 Node 24.21.0、Camoufox 152.0.4-beta.30、camoufox-js 0.13.0 和 Playwright 1.62.1,原因和独立锁见 [构建说明](../../docker/camofox/README.md)。2026-11-05 在独立桌面容器和全新 profile 卷验证了当前组合,重启前 12 项、正常重启后 13 项通过,包括身份保持、Cookie 落盘、快照、PNG、可信点击和 profile 隔离;测试容器与卷已清理。下述 2026-10-01 的现场验证使用升级前的依赖组合,其中真实站点相关结论不自动扩展到当前组合。
|
||||
|
||||
用生产 profile 与桌面配置的独立副本验证了鉴权、原身份保持、Cookie 正常重启落盘、上下文/页面、evaluate、快照、PNG、选择器与可信坐标点击、profile 隔离。现有真实 BrowserService/Agent 能力核验脚本 `scripts/browser-verify/verify.ts` 的 setup/a/b/idle/c/d 共 25 项严格通过,包含登录、脱敏、提取、下载文件哈希及资源关联、正常重启与空闲回收自动重连、旧引用拒绝、SIGKILL 未落盘登录丢失识别。适配器能力表现已登记 1.18.0 的原十项能力,未知版本不继承核验结果。
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ docker build -t uhd-media-tool:latest . # 或 docker com
|
||||
APP_VERSION=v0.3.11 docker compose --env-file .env.deploy build app # 示例:发布时填写对应版本,写进 web 的 version.json
|
||||
```
|
||||
|
||||
- 多阶段:`oven/bun:1.4.3`(装依赖 → web 构建 → server 编译)→ `debian:trixie-slim` 运行镜像。
|
||||
- 多阶段:`oven/bun:1.4.4`(装依赖 → web 构建 → server 编译)→ `debian:trixie-slim` 运行镜像。
|
||||
- 运行镜像额外装 `gosu`(降权)及 PG 客户端动态库,从固定的 `postgres:18.6-trixie` 官方镜像复制 pg_dump/pg_restore/psql 与 libpq 18,
|
||||
外加 `/usr/local/bin/ffprobe`:从 `mwader/static-ffmpeg:9.0.2` 拷单个静态二进制(约 135 MB;Debian `ffmpeg` 包要 200+ 个依赖约 450 MB)。
|
||||
换来源用 `--build-arg FFPROBE_IMAGE=<含 /ffprobe 的镜像>`。
|
||||
|
||||
+8
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
## 前置
|
||||
|
||||
- Bun 1.4.3(锁定)、Docker;Linux 解析沙箱构建需要 C 编译器和 Node-API 头文件(Debian: `build-essential libnode-dev`)。不需要单独安装 Node.js / pnpm。
|
||||
- Bun 1.4.4(锁定)、Docker;Linux 解析沙箱构建需要 C 编译器和 Node-API 头文件(Debian: `build-essential libnode-dev`)。不需要单独安装 Node.js / pnpm。
|
||||
- 端口:web 5180、API 4390、PG 55433。4380 留给本机部署版(Caddy),本机 3000/5175/5176/55432 已被其他项目占用,不要改用。
|
||||
|
||||
## 首次启动
|
||||
@@ -16,6 +16,10 @@ bun run dev # 同时起 server(4390)与 web(5180)
|
||||
|
||||
单独起:`bun run dev:server`(`bun --watch`,默认 `--role all`,API + worker 同进程)、`bun run dev:web`。
|
||||
|
||||
前端使用 Vite 8 + TanStack Router,路由表在 `apps/web/app/router.tsx`,构建入口为 `apps/web/index.html` 与 `app/entry.client.tsx`。`VITE_API_TARGET` 可覆盖开发代理目标,默认 `http://localhost:4390`;生产产物仍输出到 `apps/web/build/client`,由后端按 SPA 路由回退到 `index.html`。
|
||||
|
||||
server 测试按 `unit`、`pg`、`serial` 分组运行。`unit` 文件并行,其余两组各自文件串行;OpenWorkflow 0.11 的并发索引迁移会等待其它 schema 的长事务快照,因此不同 schema 的数据库测试也不能并行跑。测试连接开发库,不使用部署库。
|
||||
|
||||
## 验证
|
||||
|
||||
```sh
|
||||
@@ -105,6 +109,8 @@ curl -H "Authorization: Bearer umt-dev-admin-key" "localhost:4390/api/v1/events?
|
||||
|
||||
身份重识别的幂等判断同时覆盖季集、日期、发布组和识别词命中;作品候选相同不代表解析事实相同,不能跳过事实变更后的季集重算。
|
||||
|
||||
整理身份事项按决策 ID 使用稳定恢复幂等键,在原记录的重新规划锁内复用有效后继。人工与智能体同时确认同一作品只入队一次;并发选择不同作品时返回冲突,不能让同一来源生成两份执行计划。
|
||||
|
||||
季集计算和识别词归 sources-identity,整理请求、文件操作与入库状态归 acquisition-organize。整理把真实失败文件和同批正常文件样本交给映射事项,模拟与写入共用同一判断;映射重算后以 `media.episode_mapping_changed` 通知整理模块,只有季集已经确定的未完成记录重新规划。恢复预检与规划复用 `planFileEpisodes`,保留原资源的发布时间等解析上下文。Agent 的调查运行、预算和授权沿用现有机制,不另外创建恢复框架;身份补齐、重新排队和实际入库完成分别按业务事实核实。
|
||||
|
||||
维护时先验证真实的成功、失败和恢复路径,尤其是授权、文件替换、取消与外部副作用;删除空壳或无使用者的机制时同步删除其专属测试与文档。不要为了目录对称增加转发层,也不要把不同阶段的状态合并成一个枚举。
|
||||
@@ -203,7 +209,7 @@ docker compose up -d --build # 服务:app(4380)+ postgres(数据卷 umt-p
|
||||
curl localhost:4380/api/v1/health
|
||||
```
|
||||
|
||||
- 镜像:`oven/bun:1.4.3` 构建 web 与 `bun build --compile` 出二进制,并构建 `sandbox-policy.node`,运行时 `debian:trixie-slim` + gosu + postgresql-client + 静态 ffprobe,root 启动修 `/data` 属主后降权到 PUID(缺省 10001)。
|
||||
- 镜像:`oven/bun:1.4.4` 构建 web 与 `bun build --compile` 出二进制,并构建 `sandbox-policy.node`,运行时 `debian:trixie-slim` + gosu + postgresql-client + 静态 ffprobe,root 启动修 `/data` 属主后降权到 PUID(缺省 10001)。
|
||||
- 入口 `docker/entrypoint.sh`:迁移 → 自检 → 同时起 api、worker、worker:agent 三个进程;任一退出则停掉其余并以非 0 退出,由 `restart: unless-stopped` 拉起。
|
||||
- 主进程使用非 root 用户和只读的 `/app` 产物;外部字节解析另起子进程,由原生 seccomp 策略限制文件、网络与进程访问。镜像带静态 ffprobe;运行期写入落在 `DATA_DIR`(容器内 `/data`)。完整部署说明见 [deploy.md](deploy.md)。
|
||||
- 构建版本号:`APP_VERSION=v0.1.0 docker compose build`(写入 web 的 `version.json`)。
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
规格:`docs/design/site-center.md`。实现:`apps/server/src/modules/sources-identity/service/account.ts`(凭证、刷新登录、用户数据、健康检测、删除、定时任务)、`routes/sources.ts`、`runtime.ts`(凭证注入、站点默认、代理);账密登录 `packages/adapters/src/sites/login/nexusphp.ts`;迁移 `0031_site_center`。
|
||||
|
||||
2026-11-06 按 MoviePilot v3.2.4 同步公开站点框架,具体范围与偏离见 [移植账本](../porting/mp-sync-ledger.md)。Milkie 作为手写 API 定义登记,需要 API Key,缺省未启用;未进行真实账号验收的站点不会因此自动启用。
|
||||
|
||||
搜索、列表、详情、种子下载与 M-Team 字幕共用站点出口、账号 UA 和 `site:<数据库 ID>` 的 PG 限流桶。远端明确频控保留原因并顺延同一桶;不会把限流记作凭据失效。M-Team 的 `config.apiBaseUrl` 优先于定义默认 API 基址;用户数据解析也读取该配置及定义的 `api_url`,`config.userdataPath` 可指定用户信息页。账号校验保留只使用声明 schema 的行为,公用用户数据刷新入口只在 Gazelle、NexusPHP、Unit3D 间回退。
|
||||
|
||||
## 站点类型与获取方式(IA-2,迁移 `0055_site_kind`)
|
||||
|
||||
- `site.kind`:`pt`(PT 站,从站点定义库选)/ `public_bt`(公开 BT 站,不登录)/ `rss_feed`(自定义 RSS 源,只有 RSS)/ `torznab`(Jackett、Prowlarr 等的 Torznab 接口,**只定义结构**:`TorznabSiteConfig{apiUrl, apiKeySecretRef, indexerId, categories}`,不能添加、不参与调度)。定义在 `packages/contracts/src/sources.ts` 的 `SITE_KINDS`。
|
||||
|
||||
@@ -108,7 +108,7 @@ PATCH /api/v1/settings {"storage":{"retentionDays":{"observation":60}}}
|
||||
| `scheduled_job_run` | 不按天数:每个任务只留最近 50 次(`trimRuns`,原有) | — |
|
||||
| `cache_stat` | 不按天数:写入统计时顺带删 30 天前的行(原有) | — |
|
||||
|
||||
引擎语义核对(openworkflow 0.10.1):run 幂等键只在 24 小时内去重(`DEFAULT_RUN_IDEMPOTENCY_PERIOD_MS`),
|
||||
引擎语义核对(openworkflow 0.11.0):run 幂等键只在 24 小时内去重(`DEFAULT_RUN_IDEMPOTENCY_PERIOD_MS`),
|
||||
认领 / 恢复只看 pending / running / sleeping,父 run 在 step 里等子 run 时读子 run 状态。
|
||||
所以删 14 天前的终态 run 不影响去重与恢复;父 run 未结束的子 run 保留。业务侧去重看 `task` 表(`kind + idempotency_key`)
|
||||
与 `enqueueSweep` 的时间槽,不依赖引擎旧 run。
|
||||
|
||||
Reference in new issue
Block a user