feat: 清单存 /s/ 路径,重开程序跳过画廊页解析
画廊页要翻 ?p=N 分页收集全部页(206 张 = 11 次请求)。之前每次运行都要
重新解析一遍,即使本地已经有完整清单。现改为:
- 清单升级到 v2,pageMap 存每页的 /s/ 路径与文件名
- 下载前先按 gid 找磁盘上的画廊目录,读到 v2 清单就直接下载,不请求画廊页
- 解析完立即写清单,崩溃/关程序也不丢
为什么存 /s/ 路径而不是 hath 直链:
hath 直链是「随机子域 + 随机端口 + 时间戳签名」,每次都变且会过期,
存下来也没法用(手动复制到浏览器打开,下次同样失效)。/s/ 路径是稳定的。
降级策略(都实测过):
- v1 旧清单(没有 pageMap)→ 重新解析,并把清单升级成 v2
- 清单 JSON 损坏 → 重新解析,跑完重写一份正常的
- 清单的 /s/ 路径过期(待下页几乎全失败)→ 自动重新解析一次再重试
- 找不到清单但目录存在(换了目录模板)→ 按新模板名/旧标题名找到目录继续
另外 pageMap 里存了 meta,否则从清单重建时目录模板(如 {artist}/...)
会退化到兜底值,算出来的目录名和之前对不上。
测试从 68 增至 74,其中 TestManifestSkipsReparse 实测第二次运行
画廊页请求数为 0 增量。
This commit is contained in:
@@ -247,24 +247,57 @@ https://oclzqqk.gyktyewfonyf.hath.network:39656/h/4e9af9f.../keystamp=1791448200
|
||||
|
||||
### 画廊目录清单(.ehdl.json)
|
||||
|
||||
每个画廊目录下会写一份 `.ehdl.json`:
|
||||
每个画廊目录下会写一份 `.ehdl.json`。首次下载时(解析完画廊页)写入,之后每次跑都会更新。
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"version": 2,
|
||||
"gid": "4239274",
|
||||
"token": "55e069b6b9",
|
||||
"title": "[Noxe] 0820 Qingxiao",
|
||||
"totalPages": 206,
|
||||
"donePages": [1, 2, 3, 5],
|
||||
"failedPages": [4],
|
||||
"pageMap": {
|
||||
"1": { "page": 1, "file": "001.png", "sPath": "/s/bb06b5db77/4239250-1", "finished": true },
|
||||
"2": { "page": 2, "file": "002.png", "sPath": "/s/cc11ee22ff/4239250-2", "finished": true }
|
||||
},
|
||||
"meta": { "artist": "Noxe", "group": "CriticalHAI", "tags": ["qingxiao"] },
|
||||
"updatedAt": 1791475732842
|
||||
}
|
||||
```
|
||||
|
||||
作用:断点续传的依据是「文件在且非空」,但那有个盲区 —— 如果 `state.json`
|
||||
丢了,程序就不知道这个画廊**原本应该有多少张**。清单补上了这个认知,
|
||||
扫目录就能算出「应该 206 张,现在只有 4 张」。
|
||||
**关键作用:跳过重新解析。**
|
||||
|
||||
画廊页要翻 `?p=N` 分页收集全部页(206 张 = 11 次请求)。有了 `pageMap` 里的
|
||||
`/s/` 路径,程序重启后可以直接下载,不必再解析画廊页。
|
||||
|
||||
```
|
||||
首次:解析画廊页(11次) → 写清单 → 下载
|
||||
重开:读清单(0次请求) → 直接下载
|
||||
```
|
||||
|
||||
**为什么 `pageMap` 存 `/s/` 路径而不是图片直链?**
|
||||
|
||||
hath 直链是 `随机子域 + 随机端口 + 时间戳签名`,每次请求都不一样且会过期 ——
|
||||
存下来也没法用(就算手动复制到浏览器打开,下次也会失效)。
|
||||
`/s/` 路径是稳定的,用它每次实时换取直链。
|
||||
|
||||
### 清单失效怎么办
|
||||
|
||||
如果清单里的 `/s/` 路径过期了(EH 换 key、或作者更新了画廊),下载会失败。
|
||||
程序会自动检测:**待下载页几乎全失败 → 重新解析一次画廊页 → 用新路径重试**。
|
||||
|
||||
日志里会看到:
|
||||
|
||||
```
|
||||
画廊 4239274 用本地清单(206 页),跳过重新解析
|
||||
画廊 4239274:本地清单的页面路径似乎已失效,重新解析画廊页
|
||||
画廊 4239274:重新解析后全部下载完成
|
||||
```
|
||||
|
||||
如果重新解析后还是失败(画廊真被删了/受限制了),才会标记「部分失败」。
|
||||
这时候按标题手动搜一次重新导入即可。
|
||||
|
||||
状态文件:
|
||||
- Windows:`%APPDATA%\EH Downloader\state.json`
|
||||
@@ -316,6 +349,8 @@ go test -race ./... # 竞态检测
|
||||
- **全局限流**(并发穿透验证 + 精确计时)
|
||||
- **整轮扫尾**(首轮 4 次重试全挂 → 扫尾救回 / 永久失败 → partial)
|
||||
- **画廊清单**(读写往返、目录扫描、state.json 丢失后的恢复)
|
||||
- **清单优先**:第二次下载完全跳过画廊页解析(实测画廊页请求数不增)
|
||||
- **清单降级**:v1 旧清单 / 损坏清单 / `/s/` 路径过期,三种情况都能正确回退
|
||||
|
||||
## 免责声明
|
||||
|
||||
|
||||
Reference in New Issue
Block a user