- 删除 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]>
16 KiB
16 KiB
许可证核对与来源登记(MoviePilot / MovieClaw)
本文依据 REQ §14.2 和任务书 §1"参考源码"一栏,属于工程合规边界的说明,不是法律意见。在对外分发或商业化之前,必须针对具体要发行的产品另行做法律审查(REQ §14.2 末段)。
1. 核对结论
| 项 | MoviePilot | MovieClaw |
|---|---|---|
| 仓库 | https://github.com/jxxghp/MoviePilot(分支 v3) |
https://github.com/movieclaw/movieclaw(main) |
| 本次核对的提交 | e6820a83ab05e8a00eb0e14adf0f357faa965c7e(2026-08-30,version.py = v3.0.0)。本地路径 /opt/moviepilot-plus/upstream/MoviePilot,是单提交浅克隆 |
fc9eb7248dd9c4f7cd8f3fbd704a357b0b766b90(REQ 附录 [S16])。本机没有源码(find /opt -maxdepth 3 -iname "*claw*" 没有结果),是通过 GitHub API 和 raw 取到该提交的 LICENSE、pyproject.toml 以及站点配置原文(见 moviepilot-downloader-and-sites.md §0) |
| REQ 附录快照 | 33da9ce65d5020a8e087584a3321c1ff353c1921:本地仓库里没有这个对象,无法逐行比对。以本表提交为准,引用行号时必须写明提交 |
与附录一致 |
| 仓库许可 | 根目录 LICENSE 是 GNU GPL v3 全文(674 行,md5 1ebbd3e34237af26da5dc08a4e440464) |
该提交的 LICENSE 是 修改版 Apache-2.0,附加非商业条件;LICENSE 第 44-45 行写明"v0.27.0 及之前发布的版本以 MIT 许可证发布……本许可证适用于 v0.27.0 之后发布的版本" |
| 包元数据 | pyproject.toml 没有 license 字段 |
pyproject.toml 第 7 行 version = "0.27.0",第 11 行 license = { text = "MovieClaw License (Apache-2.0 with non-commercial conditions)" } |
| MovieClaw 附加条件要点 | — | 两者冲突时附加条件优先;免费使用仅限非商业(个人/家庭自用、亲友间非营利共享、学习研究教学);公司内部使用也算商业使用,需要书面授权;再分发要附许可全文,衍生版本继续适用本许可。本项目给用户个人和家庭的媒体设施使用,是否落在"非商业"范围内要由用户确认;在确认之前,对 MovieClaw 一律只参考字段结构(data-ref) |
| 附加声明 | README.md 第 17 行写"仅用于学习交流使用,请勿在任何国内平台宣传该项目",第 79-80 行免责申明写"不得用于商业用途……不建议对用户认证机制进行规避或修改并公开发布"。这些是 README 里的声明,不是 LICENSE 的附加条款。GPLv3 §7 不允许附加"进一步限制",但按 REQ §14.2 的要求,本项目仍然尊重这些声明,不把它们解读成可以忽略的内容 |
附加条件写在 LICENSE 正文里,有约束力:商业使用需要书面授权,衍生版本继续适用同样的条款 |
| 版本字段陷阱 | — | main 的 pyproject 版本号仍是 0.27.0,但 LICENSE 已经是附条件版本。不能根据版本号推定 main 是 MIT(REQ §14.2 原话)。要按 MIT 使用,只能引用已经核实过的 v0.27.0 及更早的 tag,而且要逐个文件核对那个 tag 附带的许可 |
1.1 MP 中的非源码或闭源部分(不得作为参考源)
| 组件 | 位置 | 状态 | 处理 |
|---|---|---|---|
SitesHelper(站点认证、流控、站点索引定义) |
app/application/site/sites.cpython-314-x86_64-linux-gnu.so,已被 .gitignore:4 忽略;仓库只有 sites.pyi 类型存根 |
闭源二进制,由 docker/Dockerfile:261-262 从 jxxghp/MoviePilot-Resources 下载 |
不反编译,不参考。 站点选择器改以 MovieClaw 配置和我们自己抓取的页面为准 |
| 站点样例配置 | tests/test_rust_accel.py 里有少量站点 indexer 样例(公开测试数据) |
GPL-3.0 | 只用来理解字段语义,不作为选择器的来源 |
| 站点定义数据 | app/application/site/user.sites.v3.bin,已被 .gitignore:12 忽略,内容加密 |
同上 | 不解密,不使用 |
Rust 加速 moviepilot_rust 0.3.3 |
以 wheel 形式安装在 .venv,源码仓库是 jxxghp/MoviePilot-Rust |
wheel 附带的 LICENSE 是 GPLv3 | 只对照 Python 参考路径(见 moviepilot-metadata-recognition.md §0.1) |
内嵌的 tmdbv3api |
app/modules/themoviedb/tmdbv3api/*,文件头没有许可说明,仓库里也没有单独的 LICENSE/NOTICE |
来源推测是 AnthonyBloomer/tmdbv3api(MIT),但未核实 | 不使用;本项目直接调 TMDB REST v3 |
| 第三方运行依赖 | anitopy~=2.1.1、cn2an~=0.5.24、pinyin2hanzi~=0.1.1、regex、zhconv 等(pyproject.toml) |
各有各的许可 | 本项目如需等价的 npm 库,另行选型并单独登记,不因为 MP 用过就默认可用 |
2. 本项目的迁移边界
任务书 00-first-version-plan(已删除,见 git ceb66f8) §1 规定:"MoviePilot:GPLv3,只做行为对照与 TS 重写,不复制文件"。REQ §14.1 允许"以具体实现为参考迁移业务逻辑"。两条放在一起执行时,按下表办。
| 允许 | 不允许 |
|---|---|
阅读上游源码,理解调用链、条件分支、状态机和数据结构,用我们自己的语言写成行为对照记录(也就是 docs/porting/*.md) |
把 .py、.yaml 文件或者大段代码原样放进仓库,包括放进注释或测试 fixture |
用本机上游解释器运行上游代码,只为得到行为输出,作为 parity 期望值(脚本放在仓库外,或放在 packages/testkit/scripts/ 并标注"可选、需要本机 MP") |
让 CI 依赖上游代码;把上游模块作为运行时依赖;通过子进程调用 MP |
| 按对照记录独立编写 TS 实现,命名、结构和类型遵循本项目约定 | 逐行机械翻译(包括让 AI 逐行改写)后当作原创。REQ §14.2:跨语言翻译或 AI 改写不会自动让移植成为没有来源的独立原创 |
引用事实性常量:协议字段名(qB WebUI API、M-Team API、TMDB API)、站点公开的 HTML 结构、行业通用词表(WEB-DL、REMUX、DDP5.1) |
照搬上游整理过的数据表:RELEASE_GROUPS 站点到组名的正则表(app/domain/meta/releasegroup.py:26)、StreamingPlatforms 平台码表(app/domain/meta/streamingplatform.py,约 270 条)、_name_nostring_re 干扰词表。这类表要自行编制,并在 ledger 里写明来源(例如公开的 scene/P2P 命名规范、站点官方规则页) |
| 上游测试里的标题字符串(事实数据)可以作为输入语料 | 整份拷贝 tests/cases/meta.py 这类测试文件;期望值必须由我们自己按 REQ 判定,不是照抄上游的 target |
| MovieClaw:阅读 YAML 的字段结构,参考其字段设计 | 在没有书面授权时拷贝 MovieClaw main 的配置或代码(附条件许可);把 main 的内容当作 MIT 使用 |
MovieClaw tag v0.27.0(c79bb1b0,MIT) 的资产可以原样复制或转换(kind=copied-mit),前提是保留 MIT 全文与 Copyright (c) 2026 MovieClaw(packages/adapters/src/sites/definitions/NOTICE-MovieClaw.md),每个产物写明来源提交与路径(站点定义 JSON 的 provenance 字段),且只经 git show v0.27.0:<path> 读取(用户 2026-09-27 确认,依据 movieclaw-assessment.md §1) |
复制 v0.27.0 之后(251f1988 起附条件许可)的任何内容;复制 MC 仓库内自带独立许可的第三方子组件(skill-creator Apache-2.0、liquid-glass)而不遵守其各自许可 |
对每个 PR 的要求:只要实现参考了上游,PR 描述里就必须写"参考:docs/porting/<文件>#<节>",并在 §3 ledger 里补一行,登记状态为 behavior-ref。只有真的复制了代码或数据时,才登记为 copied;按目前的边界,不应出现 copied。例外是 copied-mit:复制 MIT 许可的资产(目前仅 MovieClaw v0.27.0),必须 notice_required=是 并附 NOTICE。
2.1 分发时的注意事项(首期不分发,先写在这里)
- 本项目用于内部部署(REQ §1.1.1)。内部使用不是忽略上游条款的理由(REQ §14.2)。
- 如果以后出现
copied条目:MP 来源的部分会让整个分发物受 GPLv3 约束(需要同许可、提供源码、保留声明);MovieClaw main 来源的部分需要书面授权。发现这种情况要先移除,再讨论。 - Docker 镜像不得包含 MP 或 MovieClaw 的任何文件,也不得在构建时下载
MoviePilot-Resources。
3. Component ledger
3.1 字段模板
| 字段 | 说明 |
|---|---|
id |
CL-<序号> |
our_module |
本项目的文件或函数,例如 packages/domain/src/title/parse.ts#parseReleaseTitle |
kind |
behavior-ref(只参考行为)/ data-ref(参考了数据结构,内容自行编制)/ copied(复制,原则上禁止)/ copied-mit(复制 MIT 资产,须保留 NOTICE,见 §2)/ dependency(npm 依赖) |
upstream |
仓库 URL |
commit_or_version |
精确提交或 tag,不能写 main |
upstream_paths |
文件:函数:行号 |
license |
上游在该提交下的许可 |
porting_doc |
docs/porting/*.md#节 |
modifications |
和上游行为的差异摘要,要引用对照文档里的"调整项" |
notice_required |
是 / 否(copied 或 MIT/Apache 依赖要保留版权声明) |
distribution |
internal-only / image / source |
reviewer、date |
登记人和日期 |
3.2 初始登记(W0-C)
| id | our_module(建议) | kind | upstream | commit | upstream_paths | license | porting_doc | modifications | notice | distribution |
|---|---|---|---|---|---|---|---|---|---|---|
| CL-001 | packages/domain/src/title/parse.ts |
behavior-ref | MoviePilot | e6820a8 | app/domain/metainfo.py:495,533;app/domain/meta/metavideo.py:163-874;app/domain/meta/metabase.py:244-431,719 |
GPL-3.0 | metadata-recognition §2-§3 | 新增 airDate、issue、cut、packHint、未知发布组兜底;调整了 merge 条件 | 否 | internal-only |
| CL-002 | packages/domain/src/title/custom-words.ts、episode-format.ts |
behavior-ref | MoviePilot | e6820a8 | app/domain/meta/words.py:54-221;app/application/formatting.py:84-230 |
GPL-3.0 | metadata-recognition §4 | 禁用 eval,规则版本化,偏移范围收窄 | 否 | internal-only |
| CL-003 | packages/domain/src/title/release-groups.ts |
data-ref | MoviePilot | e6820a8 | app/domain/meta/releasegroup.py:26,117,127 |
GPL-3.0 | metadata-recognition §5 | 只参考"站点到组名"的结构和界定符语义,组名表自行编制 | 否 | internal-only |
| CL-004 | packages/domain/src/identity/tmdb-match.ts、packages/adapters/src/tmdb/* |
behavior-ref | MoviePilot | e6820a8 | app/modules/themoviedb/__init__.py:190-930;app/modules/themoviedb/tmdbapi.py:130-770,961-1045;cache.py:143-265 |
GPL-3.0 | metadata-recognition §7-§8 | 候选打分,人工锁定,缓存放 PG | 否 | internal-only |
| CL-005 | packages/adapters/src/nfo/writer.ts、packages/tasks/src/refresh-metadata.ts |
behavior-ref | MoviePilot | e6820a8 | app/chain/scraping.py:148-395;app/modules/themoviedb/scraper.py:35-420 |
GPL-3.0 | metadata-recognition §10 | 刮削改为独立任务;uniqueid 里写本地 UUID | 否 | internal-only |
| CL-006 | packages/domain/src/organize/*、packages/adapters/src/fs/*、packages/tasks/src/verify-and-import.ts |
behavior-ref | MoviePilot | e6820a8 | 见 moviepilot-transfer.md §2 各表 |
GPL-3.0 | transfer §2-§4 | 见 transfer §3 的必须偏离表 | 否 | internal-only |
| CL-007 | packages/adapters/src/qbittorrent/* |
behavior-ref | MoviePilot | e6820a8 | app/modules/qbittorrent/__init__.py、qbittorrent.py(行号见 downloader-and-sites 文档) |
GPL-3.0 | downloader-and-sites §qB | 标签接管,删数据前做引用检查 | 否 | internal-only |
| CL-008 | packages/adapters/src/sites/nexusphp/* |
behavior-ref | MoviePilot | e6820a8 | app/modules/indexer/spider/*、app/modules/indexer/parser/nexus_php.py、nexus_audiences.py |
GPL-3.0 | downloader-and-sites §站点 | 站点定义自行编制;不使用闭源 SitesHelper | 否 | internal-only |
| CL-009(retired → CL-012) | packages/adapters/src/sites/nexusphp/configs/audiences.ts |
data-ref | MovieClaw | fc9eb72 | src/movieclaw_tracker/sites/configs/audiences.yaml |
MovieClaw License(Apache-2.0 加非商业条件) | downloader-and-sites §MovieClaw | 只参考字段结构;选择器值以我们自己抓取的观众页面为准重新编写 | 否(未复制) | internal-only |
| CL-010(retired → CL-013) | packages/adapters/src/sites/mteam/* |
behavior-ref + data-ref | MovieClaw + MoviePilot | fc9eb72 / e6820a8 | MC:sites/configs/mteam.yaml、sites/custom/mteam.py;MP:app/modules/indexer/parser/mtorrent.py |
MC 附条件 / GPL-3.0 | downloader-and-sites §M-Team | API 字段以 M-Team 公开 API 为准,按 API Key 模式实现 | 否 | internal-only |
| CL-011 | packages/testkit/fixtures/title-parity.json |
data-ref | MoviePilot | e6820a8 | 输入语料参考 tests/cases/meta.py;期望值自行判定 |
GPL-3.0(原测试文件) | metadata-recognition §9 | 只取标题字符串,必要时脱敏 | 否 | internal-only |
| CL-012 | packages/adapters/src/sites/definitions/*.json(23 站)、definitions/manifest.generated.ts、spider/mc-selector.ts、scripts/mp-sync/movieclaw-import.mjs |
copied-mit | MovieClaw | v0.27.0(c79bb1b0) |
src/movieclaw_tracker/sites/configs/*.yaml;selectors.py NexusPHPSelectors 默认值;frameworks/nexusphp.py _css_text |
MIT | downloader-and-sites §W1-3c | YAML 转为 MP indexer schema + umt;观众/馒头/HHClub/CHD 由 scripts/mp-sync/movieclaw-overrides/*.json 覆盖;除 4 主力站外 enabled:false |
是(definitions/NOTICE-MovieClaw.md) |
internal-only |
| CL-013 | packages/adapters/src/sites/mteam/* |
behavior-ref + copied-mit | MovieClaw + MoviePilot | v0.27.0(c79bb1b0)/ e6820a8 |
MC:sites/configs/mteam.yaml(→ definitions/mteam.json)、sites/custom/mteam.py(字段对照);MP:app/modules/indexer/spider/mtorrent.py、parser/mtorrent.py |
MIT / GPL-3.0 | downloader-and-sites §M-Team | 定义由 MC 转换 + W1-3b 值覆盖;API 行为按 MP | 是(MC 部分) | internal-only |
新增 npm 依赖(例如 anitopy 的等价实现、
re2、fast-xml-parser)按kind=dependency登记,填锁定版本和 SPDX。
3.3 ledger 的维护规则
- ledger 以本文件 §3.2 为唯一登记处,按 id 追加,不删除旧行;撤销时把行标记为
retired。 - 上游提交升级时,新增一行,写新的提交号,不覆盖旧行。对照文档里的行号也要按新提交重新核对。
copied行出现时,CI 必须失败。建议在scripts/里加一个检查:ledger 中kind=copied的行数必须为 0。copied-mit不在此列,但必须有 NOTICE 文件且notice=是。- 审核人检查三件事:PR 里有没有"参考:"链接;ledger 有没有对应行;diff 中有没有大段和上游高度相似的代码(可以用
jscpd这类工具,把上游目录作为外部语料做一次抽样检查)。
4. 待办与未决
| 项 | 状态 |
|---|---|
REQ 附录快照 33da9ce 和本地 e6820a8 的差异 |
未比对,本地没有该对象。需要时 git fetch --depth=1 origin 33da9ce... 再比对(需要网络) |
MovieClaw 是否有可用的 ≤v0.27.0 MIT tag,以及 tag 内的文件许可 |
未核对。只有在决定复用 MovieClaw 历史代码时才需要做 |
tmdbv3api 内嵌副本的来源和许可 |
未核实;本项目不使用它 |
| 对外分发 | 首期不做;如果要做,先完成法律审查 |