- 删除 docs/plan 下 00–18 的计划、评审、验收、发布记录与升级证据,docs/spikes 与 spikes 验证代码
(保留 spikes/movieclaw-src 本地克隆),以及 4 份一次性审查 / 调研;全部可在 ceb66f8 查到
- MP 对照移到 docs/porting/moviepilot-v3-comparison.md;经验教训改为 docs/plan/lessons.md(补第 25 条)
- docs/plan/README.md:文档放哪、当前状态、待办
- 引用改写:代码注释指向在维护的文档,其余注明已删除与 git 位置;清掉原有 6 个失效链接
- README 开头改为当前状态与入口;CHANGELOG 补齐 0.3.8–0.3.14 与工程变更
Co-Authored-By: Claude Opus 5.5 <[email protected]>
15 KiB
媒体整理(/console/organize)
原地入库为 v0.3.14 的待部署改动;当前生产 v0.3.13 的整理方式仍为复制/移动,独立就地刮削继续可用。
整理页分为「整理队列」与「整理记录」。队列显示等待、执行和等待继续的后台入库任务;记录显示复制/移动/原地入库的处理结果。文件管理的改名、删除、还原账本继续保存,通用记录接口仍可查询。
实现:
- 列表 / 统计 / 详情:
apps/server/src/modules/acquisition-organize/routes/organization.ts(筛选recordFilters,通配likePattern);公开字段在services/organize.ts的loadRecordsPublic。 - 删除:
apps/server/src/modules/file-manager/record-delete.ts(复用文件管理删除deleteFiles)。 - 契约:
packages/contracts/src/organization.ts(OrganizationListQuery、OrganizationStats*、OrganizationDelete*),端点Api.organization.stats / remove。 - 前端:
apps/web/app/routes/console/organize.tsx、organize.$id.tsx,components/organize/(删除确认框、标题 / 季集小件),批量重新整理走共用整理弹窗的{ kind: "records" }来源。
统一整理弹窗(v0.3.13)
手动选目录、文件管理器、下载详情与历史重新整理打开同一个弹窗。单文件只处理该文件,目录递归展开视频,多选合并去重。媒体类型可自动、电影或剧集;作品可自动识别、搜索本地/TMDB,也可选定类型后输入 TMDB ID 定位。手动指定作品与季号作用于整个本次范围,混合批次中需单独纠正的作品另行选取;文件明细可核对和修正季集、排除文件,没有另一套批量勾选语义。
各入口匹配相同来源配置,唯一匹配自动带出方式和分类/目标,多个匹配在弹窗内选定;不使用来源配置时沿用全局默认并手动指定。下载详情优先按已有 qB 标签匹配覆盖当前路径的来源。历史原配置仍覆盖可用输入时优先采用;成功移动后的目标不再属于旧来源时显示当前匹配配置或手动选项。
本次可选择原地入库、复制或移动。复制/移动可调整目标媒体库或具体目录、命名、目标冲突及整理后刮削。刮削默认沿用全局配置,显式开关只影响本次;整理成功的文件再进入现有 NFO/图片任务,TMDB 和 Local 均适用。做种义务未满足时不提供移动,复制与原地登记不改变视频文件,服务端继续核对实际状态。
手动来源发现真正成功历史时显示数量及「跳过成功记录」,默认关闭,开启后仅本次跳过;失败/部分成功记录不算完整成功,最新失败也不会遮盖较早成功。目标已存在策略单独处理。从历史记录进入直接采用重新整理语义。修改识别或选项后旧预览失效,需重新生成。
确认预览后只提供「加入整理队列」。后台受理成功后弹窗自动关闭,可以继续操作,进度到队列查看,整理后的刮削任务也显示在队列,整理详情单独展示刮削结果;部分受理时已受理文件从本次范围移除,剩余文件可修改后再预览提交。队列复用现有后台调度,不要求浏览器停留到文件处理结束。记录、队列及弹窗明细均复用统一分页。
来源、分类与存量整理
设置 → 媒体库与目录中维护分类 YAML 和整理来源。新功能已于 2026-10-01 部署为 v0.3.9,迁移 0059_organize_source_snapshot 已执行,见 发布记录(已删除,见 git ceb66f8)。
- 一条来源配置选一个来源目录、一个媒体库目标目录、复制或移动方式。通过弹窗浏览已登记的目录选择,不需要填写宿主机任意路径。不同来源可以使用相同分类,规则只维护一次。
- 分类一级固定为
movie/tv。规则按顺序首次匹配;同一规则的字段同时满足,同字段逗号值为任一匹配,!排除。release_year支持年份或区间;原始 TMDB 详情的一级字段也可使用。 - 空条件是兜底,应放在最后。默认保留「欧美电影」「欧美剧集」承接所有未命中的习惯。TV 默认顺序为儿童剧集、动漫剧集、纪录片、综艺、华语剧集、亚洲剧集、欧美剧集。尚未取得 TMDB 详情不能冒充分类成功。
- 自动分类在目标目录下追加分类目录,再使用现有作品/季目录模板。固定分类直接以所选目标为分类目录,避免追加第二遍分类名称。预览显示完整目标路径。已有作品沿用路径绑定,保存新规则不会移动旧库。
- YAML 保存后用于后续计划,重启保留;语法或目录名不合法时拒绝保存,已有规则保留。
来源触发方式可以选手动、qB 标签或目录快照。qB 标签同时限定下载器实例和来源范围;只有完成的任务进入整理,去掉标签后停止接管,已有管理标签继续有效。
新增来源或更改来源路径时,先将当前视频文件记录为基线,这些文件不会因此自动入库。快照持久化在数据库,重启保留。后续新增或改变的文件,在连续两次扫描确认大小和修改时间稳定后再处理。已知 qB 任务由下载器接管流程负责,避免两种触发重复整理。下载器目录会查询当前全部 qB 任务,即使未打标签、尚无数据库任务行,也会等下载完成。下载器不可达或目录读取失败会记录错误并保留此前快照。
「整理存量」是可重复触发的一次性扫描:排除同一源文件事实已成功整理的文件及未完成下载,历史部分成功中的失败文件、同路径发生变化的文件仍可选,候选进入同一个整理弹窗,确认识别、操作和完整目标路径后执行。单次候选按识别上限分批;完成后再次触发可处理余下文件。这个操作不重建或清空基线。识别不确定时也可打开现有智能助手协助判断,再加入整理队列。
文件管理器选中文件或目录后点「整理」,会读取来源配置并按同根、目录边界和最长来源路径匹配所选全部项目。唯一匹配自动带入复制/移动方式、分类和目标策略;多个同等匹配让用户选择,也可不用配置手动指定。不同来源混合选择或没有匹配时使用共用整理弹窗的手动选项。媒体类型在预览时核对,配置目标可由本次明确的目标选择覆写。
实现复用既有识别、冻结计划、文件操作账本、整理记录与任务引擎;未增加软链接、硬链接或另一套 AI 执行流程。
手动下载、Local 元数据与一次性洗版(已部署 v0.3.10)
搜索、站点工作台和原站详情均可独立下载,不要求订阅。下载时默认正常入库,也可选择一次性洗版并勾选旧版本;只有一个旧版本时默认选中,多个由用户选择。媒体详情与下载窗口展示已有文件和规格。正常入库保留已有版本;不同版本路径由可编辑的命名模板决定,同名冲突仍需处理。
未识别资源确认后允许下载。整理时先匹配 TMDB,再由现有网络/Agent 元数据补全能力核对译名、原名和别名;能够找到正确条目时回到 TMDB,找不到且详情资料充分时使用 Local 身份。Local 共用现有分类、命名、复制/移动和 NFO/图片任务,并保留字段来源;信息不足或候选冲突保留待处理。Agent 搜寻依赖已配置的模型/搜索能力和现有每日补全预算;没有封面资料时不会虚构图片。Local 入库安排元数据文件写入,普通 TMDB 自动刮削保持原设置。
洗版在本次冻结计划中保存选中的旧文件。新文件核验登记成功后才清理所选旧版本,剧集只处理成功对应的季集与 Part;覆盖不完整的合并集保留。相同目标路径会先暂存旧文件,失败后恢复。旧版的私有字幕等随之清理,共享 NFO/图片、未选版本及下载缓存保留;按现有文件替换设置移入回收站或删除。
关联迁移 0060_manual_acquisition,已于 2026-10-01 随 v0.3.10 发布执行。业务依据与验收见 MP 对照 §5.6。
与 MP 的对照
MP 对照源:MoviePilot-Frontend/src/views/reorganize/TransferHistoryView.vue、components/dialog/TransferHistoryDeleteDialog.vue、app/api/endpoints/history.py、app/db/models/transferhistory.py。
| MP 功能 | 我们 | 说明 |
|---|---|---|
| 海报 | 新增 | 作品海报(media.posterPath),没有时显示首字占位 |
| 标题 / 年份 / 季集 | 已有 | 作品 (年) S01E02;未识别的显示「未识别 · 源文件名」 |
| 二级分类(华语电影等) | 已接入 | 分类规则在设置编辑 YAML;电影 / 剧集为母分类,综艺属于剧集 |
| 源路径 → 目标路径 | 新增 | 列表加「源 → 目标」列(只显示末两段,悬停看全路径);详情「整理前 / 整理后」已有 |
| 存储标签(本地 / SMB…) | 不做 | 只有本地存储,标签不提供信息 |
| 整理方式 复制 / 移动 | 已有 | 列表「方式」列;整理页聚焦复制/移动结果 |
| 软链接、Rclone 复制 / 移动 | 不做 | 整理服务不支持这几种方式 |
| 大小 | 新增 | 逐文件源大小之和(sizeBytes) |
| 状态 成功 / 失败 + 失败原因 | 已有,改 | 支持「部分成功」;执行中任务在队列查看;成功不加徽章;失败原因走 reasons.ts 一句话,原码进详情「技术信息」 |
| 时间 | 已有,改 | 相对时间,悬停看完整时间 |
| 来源 下载器 / 手动 / 自动 | 新增下载器 | 来源列加下载器名称;详情加「下载任务」一行,种子 hash 进「技术信息」 |
关键字搜索(标题、源、目标;* ? 通配) |
已有,补 | 补通配、逐文件的源 / 目标路径、种子 hash |
| 搜「成功」「失败」切状态 | 不做 | 有状态筛选和计数按钮 |
| 状态筛选 | 已有 | |
| 类型筛选 | 新增 | 电影 / 剧集 / 未识别(kind=movie|series|none) |
| 时间筛选 | 新增 | 今天 / 最近 7 天 / 最近 30 天(since)。MP 没有,任务单要求 |
| 统计(总数 / 成功 / 失败) | 新增 | 列表上方一行计数,只列非零项,点一下按该状态筛选(GET /organization-records/stats) |
| 分页、每页条数 | 已有(不同) | 共享分页组件,10/20/50/100 条和翻页;游标按需加载,无总数时显示「已加载」 |
| 列排序 | 不做 | 按时间倒序;分组模式下按作品聚合 |
| 分组模式(按标题) | 新增 | 「按作品分组」,组头可折叠 |
| 筛选写进地址栏 | 新增 | 状态 / 类型 / 来源 / 时间 / 关键字 / 分组都在 URL,刷新不丢 |
| 单条:重新整理 | 已有,补 | 详情已有;列表行菜单新增。走共用弹窗(配置、展开预览、加入队列) |
| 单条:智能助手整理 | 已有(不同) | 「让智能体排查」:失败 / 部分成功的记录在行菜单和详情里 |
| 单条:删除(只删记录 / 连源文件 / 连媒体库文件 / 全部) | 新增 | 确认框里两个勾选项,先核对再执行,写清删几个文件、多大、哪些删不了、会不会被自动整理再处理 |
| 查看详情 | 已有 | 详情加海报、大小、下载任务、删除按钮 |
| 批量选择 / 全选 | 新增 | 「批量」进入选择模式,表头全选 |
| 批量删除 | 新增 | 同单条删除确认框;删不了的逐条列出,其余照删 |
| 批量重新整理 | 新增 | 选中记录的可用文件一起进整理弹窗(成功移动取目标,其他取源);同属一个作品时预选作品 |
| 清空整理记录 | 不做 | 整理记录同时是文件变更的追溯记录;清理按保留期由计划页负责 |
删除
POST /organization-records/delete {ids[≤200], deleteSource, deleteTarget, dryRun},scope organize.execute。
- 文件一律移入回收站,走文件管理删除(
deleteFiles,mode=trash,retireAssets=true):已入库文件同时从媒体库移除(位置 removed、资产 retired、满足的收录版本转需关注 + 待处理)。回收站里能还原。 - 源文件 = 该记录逐文件结果的
source_path(只认执行进程本地视图);媒体库文件 = 成功文件的target_path(相对库根时按库根拼)。已经不在的文件跳过、不拦。 - 只有复制 / 移动 / 原地入库 / 硬链接记录有文件可删;改名、移入回收站、还原类记录只删记录本身。
- 一条记录的任一文件不能删(做种未满足或下载中
download_active、绑定目录needs_unbind、不在登记目录outside_roots、目录离线等),这条记录连同它的文件都不动;还在整理的记录(running)不删。其余照删。 - 文件移入回收站会写一条「移入回收站」整理记录(同文件管理删除),
trashRecordId返回它。 - 下载器里的任务不删(同文件管理删除原则)。
- 删文件只允许管理员(控制台会话 / DEV key);API Key 只能删记录,删文件 403,需先走
/files/delete的一次性审批。 autoRetry:下载已完成但没入库(download_task.status=completed、本工具管理、没从下载器删除)且删完没有别的整理记录的下载任务数。自动整理扫描(index.ts的补漏)会在几分钟后重新整理它们——与 MP 删失败记录后重新整理一致;已入库(imported)的不会。- 删除不写增量读取的墓碑(
/organization-records/changes不会出现被删的记录);文件变化通过「移入回收站」记录可见。审计files.organize_records_delete。
已知缺口
- 删媒体库文件只删整理记录里的文件,目录里的 NFO、图片与空目录保留(MP 在没有剩余视频时会连目录删掉)。
- 分组只对已加载的记录生效(同 MP 分组模式)。
- 统计的「进行中」= 排队 + 执行中;点它时列表只筛执行中。
原地入库(v0.3.14 待部署)
文件管理器选择已登记媒体库目录中的视频或目录,进入整理弹窗,默认选择「原地入库 · 保留位置与名称」。识别作品、手动指定电影/剧集、TMDB 和季集的方式与复制/移动相同,生成预览后加入现有整理队列。
- 源与目标路径相同;不复制、不移动、不重命名,不清理媒体目录中的临时文件。配对字幕/音轨同步登记,文件名和内容保持原样。
- 登记视频资产、所在库根、实际相对路径、版本信息与季集覆盖,已有同作品资产不重复创建;不新建会改变以后整理目标的目录绑定。
- 原地模式不使用来源配置的搬运目标、命名模板或替换策略,弹窗隐藏这些选项;不支持借此洗版或替换已有文件。
- 开启「整理后刮削」时,仅针对本次成功登记的视频在原目录补写 NFO/图片,不递归刮削整个同目录或该作品的其它版本。只登记/只读库根可原地入库,刮削关闭。
- 文件必须位于已登记、启用的媒体库根;下载缓存仍使用复制/移动或独立「刮削」。希望将现有目录直接作为媒体库时,先在设置登记该目录,然后原地入库。
- 预览与入队复用原计划校验;执行时确认文件未变化,不把已经归属其它作品的文件悄悄改绑。结果标为「原地入库」,可从整理记录重新整理。
此功能代码已实现,当前生产仍为 v0.3.13;本会话不能访问 Docker 或测试 PostgreSQL,部署及真实数据库回归尚待补验,见发布记录。