Skip to content

feat(jm): 一章一份 PDF 打包 zip 与 v3.18.3 发布准备 - #108

Closed
69gg wants to merge 1 commit into
mainfrom
feat/jm-chapter-pdf-zip
Closed

69gg wants to merge 1 commit into
mainfrom
feat/jm-chapter-pdf-zip

Conversation

@69gg

@69gg 69gg commented Oct 1, 2026

Copy link
Copy Markdown
Owner

变更说明

禁漫(JM)下载的交付物从「整本一个加密 PDF」改为「每章一份 AES-256 加密 PDF(同一个随机 8 位密码),打包成一个无密码 zip」:多章节本子不再需要一本几十上百 MB 的单文件才能翻开,zip 解压后按文件名就是阅读顺序。

交付结构:

JM1114751 测试本子.zip          ← 无密码,作为独立文件消息发送
├── JM1114751 001 序章.pdf      ← AES-256,密码统一
├── JM1114751 002.pdf
└── JM1114751 003 第三话.pdf

影响范围

用户可见行为

  • 合并转发仍是「本子信息 / 解密密码」两节点,随后单独发一条文件消息——发的是 zip;密码节点措辞改为「zip 内所有 PDF 的解密密码(8 位):…」,避免用户以为 zip 本身要密码。密码仍不进历史摘要。
  • zip 条目为 JM<车号> <三位章节序号>[ <章节标题>].pdf,序号取服务端章节 order 并补零(空章节不占号,服务端没给标题的章节只留序号、不再重复本子标题)。
  • 单章超限只跳过该章、其余章节照常打包,信息节点写明「N 章未打包」;所有章节都没能出 PDF 时仍只发「本子信息 / 状态」两个节点。

破坏性配置变更

  • [jm].max_file_size → [jm].chapter_max_file_size(默认仍 100MB,0 不限、<0 回退 100)。语义从「整本 PDF 上限」变为「单章 PDF 上限」,超限只丢该章;旧键失效并回退默认值,需要用户改配置。zip 总体积 = 章节数 × 单章上限,不再受配置约束(QQ/NapCat 侧上传上限由部署承担)。
  • 同步更新:config.toml.example、docs/configuration.md、docs/pipelines.md、docs/usage.md、docs/development.md、README.md、ARCHITECTURE.md、jm_book 的 README 与 config.json 描述。

内部接口

  • src/Undefined/jm/downloader.py:JmDownload 拆成 JmChapterArchive(zip_path + 每章 ChapterPdfInfo + skipped_chapters,状态 ok/partial/empty)与 JmPlainDownload(uid 路径的单份未加密 PDF);download_book_pdf → download_book,_download_sync 拆成 _download_archive_sync / _download_plain_sync。
  • 逐章组装取代整本组装:每章 download → _write_pdf → 收集,该章页面随即释放(峰值内存 ≈ 一章页面 + 已完成章节 PDF),zip 写完后删掉散落副本,任务目录只留最终交付物;删除「整本源图字节累计超限就中止整本」的预判。
  • src/Undefined/jm/sender.py:_send_result(zip_path=...),build_info_text / build_history_message 收窄为 JmChapterArchive,无密码时状态节点文案由「PDF 未发送」改为「文件未发送」。
  • 投递语义一字未改:文件不进合并转发(转发节点里的文件在 QQ 客户端下载会失败)、转发被明确拒绝才降级为「信息 / 密码」两条普通消息、delivery_uncertain / file_transfer_error 不降级重发但 zip(此前从未发出)照常单独发送、文件自身投递未确认直接上抛。
  • jm_book 的 output_mode=uid 维持单份未加密整本 PDF(供 file_analysis_agent 解析),仅共用新的单章上限校验。
  • v3.18.3 发布准备:CHANGELOG 条目 + 版本号同步(pyproject.toml、src/Undefined/__init__.py、两个 App 的 package/lock/Cargo/tauri.conf 与 uv.lock,lock 只改根包版本、无依赖漂移)。

关联 Issue

无

自检

  • uv run ruff check . 与 uv run ruff format --check . 通过(815 files)
  • uv run mypy . 通过(815 source files,Success)
  • uv run pytest tests/ --cov 通过(覆盖率不低于 pyproject.toml 中的 fail_under)
  • 改动 apps/undefined-console/ 或 src/Undefined/webui/static/js/:已跑 cd apps/undefined-console && npm run check
  • 改动 apps/undefined-chat/:已跑 cd apps/undefined-chat && npm run check
  • 涉及配置项:已同步 config.toml.example 与 docs/configuration.md
  • 涉及 WebUI / Tauri 界面:已附截图

说明:未跑全量 pytest --cov(只跑了受影响模块的测试集);两个 App 只有版本号改动,其 Biome / tsc / cargo fmt / check / test 由 pre-commit 全量钩子覆盖。

备注

  • 部署注意:升级后请把 config.toml 里的 [jm].max_file_size 改成 [jm].chapter_max_file_size,否则会静默回退默认 100MB。可用 uv run python scripts/sync_config_template.py 同步模板(旧键不会被自动删除,也不会被读取)。
  • 回滚方式:直接 revert 本 PR 即可,无数据迁移、无 schema 变更;已发出的 zip 与新 PDF 不受影响。
  • 真实链路已验证:真图 → 每章真 PDF → zip,zip 无需密码即可列出/解压,每个章节 PDF 需密码且同一密码可打开。

禁漫下载的交付物从「整本一个加密 PDF」改为「每章一份加密 PDF,统一密码打包成
一个无密码 zip」:多章节本子不再需要一本几十上百 MB 的单文件才能翻开,zip 解压后
按文件名就是阅读顺序。

- `downloader.py`:`JmDownload` 拆成 `JmChapterArchive`(zip + 每章 PDF 元信息 +
  `skipped_chapters`,状态 `ok`/`partial`/`empty`)与 `JmPlainDownload`(uid 路径的
  单份未加密 PDF),`download_book_pdf` → `download_book`;逐章 `download →
  _write_pdf → 收集`,每章页面在该章写完即释放,zip 写完后删掉散落副本,任务目录
  只留最终交付物。
- zip 条目为 `JM<车号> <三位章节序号>[ <章节标题>].pdf`(序号取服务端章节 `order`,
  空章节不占号),zip 用标准库 `zipfile` + `ZIP_DEFLATED` 写成、不加密;每个章节
  PDF 各自用同一个随机 8 位密码做 AES-256 加密。
- 体积语义改为单章上限:`[jm].max_file_size` 改名为 `[jm].chapter_max_file_size`
  (默认仍 100MB),超限只跳过那一章、其余章节照常打包,信息节点写明「N 章未打包」;
  旧键失效并回退默认值。zip 总体积不再受配置约束。
- `sender.py`:文件消息改发 zip,密码节点写明「zip 内所有 PDF 的解密密码」;投递语义
  不变(文件不进合并转发、转发被明确拒绝才降级两条普通消息、`delivery_uncertain` /
  `file_transfer_error` 不重发但 zip 照常发送、密码不进历史摘要)。
- `jm_book` 工具的 `output_mode=uid` 维持单份未加密 PDF;配置模板、README、
  ARCHITECTURE、docs(configuration / pipelines / usage / development)与工具
  README/config.json 描述同步更新。
- 版本 3.18.2 → 3.18.3。
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository: 69gg/Undefined/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 4c20cbe7-5c9c-4176-875c-ab0df27915ac

📥 Commits

Reviewing files that changed from the base of the PR and between 3a96355 and 19c7949.

⛔ Files ignored due to path filters (5)
  • apps/undefined-chat/package-lock.json is excluded by !**/package-lock.json
  • apps/undefined-chat/src-tauri/Cargo.lock is excluded by !**/*.lock
  • apps/undefined-console/package-lock.json is excluded by !**/package-lock.json
  • apps/undefined-console/src-tauri/Cargo.lock is excluded by !**/*.lock
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (26)
  • ARCHITECTURE.md
  • CHANGELOG.md
  • README.md
  • apps/undefined-chat/package.json
  • apps/undefined-chat/src-tauri/Cargo.toml
  • apps/undefined-chat/src-tauri/tauri.conf.json
  • apps/undefined-console/package.json
  • apps/undefined-console/src-tauri/Cargo.toml
  • apps/undefined-console/src-tauri/tauri.conf.json
  • config.toml.example
  • docs/configuration.md
  • docs/development.md
  • docs/pipelines.md
  • docs/usage.md
  • pyproject.toml
  • src/Undefined/__init__.py
  • src/Undefined/config/config_class.py
  • src/Undefined/config/load_sections/integrations.py
  • src/Undefined/jm/downloader.py
  • src/Undefined/jm/sender.py
  • src/Undefined/skills/shared.py
  • src/Undefined/skills/tools/jm_book/README.md
  • src/Undefined/skills/tools/jm_book/config.json
  • tests/test_jm_config.py
  • tests/test_jm_downloader.py
  • tests/test_jm_sender.py
 ____________________________________
< Zero-day? Zero chance on my watch. >
 ------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@69gg 69gg closed this Oct 1, 2026
@69gg
69gg deleted the feat/jm-chapter-pdf-zip branch October 1, 2026 05:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant