能力 ID 的域名允许单个下划线分词(episode_mapping)。 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
5.8 KiB
5.8 KiB
集数解析与映射(2026-10-03 定)
解析器只回答「发布者声称这是第几季第几集」;本模块回答「媒体库应当把它当成哪一集」。参考 MP 的偏移表达式、ANI-RSS 的订阅预览,在其上加元数据校验、确定性换算、规则与待处理,Agent 兜底放最后。
ANI-RSS(GPL-2.0,只借思路不抄代码)摸排结论:一条订阅 = 一条 feed + 一个字幕组 + 一个 bgm 条目;集号靠一条正则;偏移只有整数,自动推断 = -(feed 最小集号 - 1),不核对元数据;TMDB 只用于集标题(可选 Episode Group);体验来自「订阅预览」(按偏移算好的集号 + 已下载 + 缺集)与缺集 / 摸鱼提醒。
现状与缺口
- 本地 UUID 主身份、外部身份表、集单元的
kind / content_type / segment / source_issue已有。 release-parser/offset.ts的偏移表达式求值器没有任何调用方。ensureUnits拿解析结果直接找或建集单元:TMDB 第 2 季 12 集,解析出 S02E13 会建临时 S02E13,不报错。- 整理(
organize-plan.ts)、季包选文件(downloads.ts)、接管(takeover.ts)会对文件名重新解析,映射必须在这些地方同样生效。
判定流程
输入:解析结果 + 作品 + 季表(每季总集数、是否最新季、作品是否完结、已知每集播出日期)+ 资源发布时间 + 发布组 + 该作品的映射规则。只处理剧集类作品的正片(content_type = main、季号 ≥ 1);电影、特别篇、花絮原样通过。
- 有适用规则(作品 + 季 + 发布组,越具体越优先)→ 按规则换算 → 校验。校验失败:规则停用、开待处理,本条资源按「待确认」处理。
- 无规则,原号校验:
- 季存在且集号 ≤ 该季总集数 → 通过。
- 季总集数未知、或该季是最新季且作品未完结、且集号超出不多 → 放行(元数据滞后),记
unverified。 - 否则 → 不通过,进第 3 步。
- 确定性换算(结果都要再校验,且只取唯一解):
- 季内绝对集号:
S02 13、第 1 季 12 集 →13 - 12 = S02E01。 - 跨季绝对集号:季号是推定的(
seasonInferred),集号超出第 1 季 → 按各季总集数累加换算。 - 与「元数据滞后」冲突时(最新在播季)用发布时间判:发布时间与换算后那集的播出日期相差 ≤ 7 天才认换算,否则按滞后放行。
- 综艺:有
airDate时按播出日期对集。
- 季内绝对集号:
- 仍不行 → 资源已绑定作品但集数待确认:不建集单元,订阅评估跳过(原因
episode_unresolved),开待处理episode_mapping(按作品 + 季 + 发布组去重),附建议规则。
结果写入 source_release.episode_resolution(原始季集、规范季集、方式 raw / rule / absolute_in_season / absolute_cross_season / air_date / unverified / unresolved、规则 id、证据),parsed 里的季集改为规范值,下游不用改口径。
映射规则
- 作用域:作品(必填)+ 来源季(可空)+ 发布组(可空)。不做全局 / 站点级(站点标题差异由别名表解决)。
- 类型:
expression(复用offset.ts,如EP-12、EP*2-1,可带目标季)、table(26 → S02E01、27-28 → S02E02)、special(映射为特别篇 / 花絮 / 忽略)。 - 证据等级复用
manual / rule_confirmed / multi_evidence / needs_review,不用百分比。 - 失效:规则算出的结果校验不通过 → 停用并开待处理,不做置信度衰减。
- 规则建立或修改后,按作品重算已绑定资源的集数解析(不重做身份识别)。
- 建议规则:同作品 + 季 + 发布组下的待确认资源,用发布时间对播出日期配对,试
EP±n/EP*2/EP*2-1,全部样本成立才给建议。
分批
| 批次 | 内容 | 验收要点 |
|---|---|---|
| 1 领域纯函数 | packages/domain/src/episode-resolution/:类型、校验、确定性换算、规则应用、建议规则推导、总入口 |
domain 单测覆盖上面每个分支(含滞后放行、发布时间判定、多解拒绝、表格规则、双集) |
| 2 存储与识别接入 | 迁移(episode_mapping_rule 表、source_release.episode_resolution);季表加载;识别(resolve.ts 及其他 ensureUnits 调用方)接入;parsedOf 叠加;订阅评估跳过待确认;待处理 episode_mapping;规则失效;按作品重算 |
server pg 测试:ANi 连续编号进库即为 S02E01 并能被订阅覆盖;规则失效开待处理;滞后放行不卡追更 |
| 3 文件侧接入 | 整理计划、季包选文件、接管、文件管理识别统一套用同一作品的映射 | 下载按 S02E01 计划、文件名 - 13 整理后命名为 S02E01;季包按缺集选对文件 |
| 4 接口与界面 | contracts 端点:规则增删改、模拟预览(给定作品 / 季 / 发布组 / 草稿规则,列近期资源的原始 → 规范与校验结果);待处理 episode_mapping 的确认 / 修改 / 忽略;作品页与订阅详情「集数映射」面板 |
契约测试、web 单测、冒烟;文案过 check:copy |
| 5 Agent 兜底 | 能力 episode_mapping.inspect(只读上下文包)、episode_mapping.simulate(试草稿规则)与 episode_mapping.apply_rule(经授权写规则,服务端强制先模拟全部样本通过、不误伤已对上的资源);Skill「集数映射」与能力地图;episode_mapping 待处理接后台自动调查,没有授权时留「智能体建议」一键确认 |
agent 测试;模拟不通过的建议不能写入 |
以后再做:TMDB Episode Group、Bangumi sort / ep 对照、综艺会员加更等变体细分。
状态
- 批次 1
- 批次 2
- 批次 3
- 批次 4
- 批次 5