fix(sites): HHClub parsing, resource list layout and request restraint
HHClub (憨憨) was checked read-only against a real account (one detail
request; list, user data and health came from the product's own fetch).
Parsing fixes:
- list titles carried the site's new-torrent marker "[新]" (58 of 100
rows; the detail page title has none); stripped with a replace filter
- refreshing a detail overwrote seeders / leechers / snatched / category
name / H&R with null because the HHClub div detail page lacks them;
detail values now fall back to the list snapshot (mergeDetailOverList),
and an unknown detail promotion keeps the list promotion
- level "贵宾" is VIP (umt.vipLevels)
- sanitized minimal fixture HHANCLUB_LIST_PAGE_2026 + tests; README marks
HHClub as verified 2026-09-29
Size, counts, category ids/names, +08:00 time and subtitle were correct.
Request restraint:
- site definitions may carry umt.defaults; merged with settings.sites
(longer intervals, fewer pages): new settings defaultSnapshotMaxPages 1,
defaultHealthCheckIntervalSec 6 h, defaultDetailCacheSec 24 h; default
burst 2. HHClub: snapshot 60 min page 1 only, health 6 h, search
concurrency 1, detail cache 24 h, 1 token / 3 s burst 2
- periodic / manual snapshots are capped to that page count; scheduled
health checks skip sites checked within the interval; detail refresh is
served from cache inside the window; live searches on one site queue
- every rate-limiter token is counted per site per hour
(site_request_count, migration 0046); GET /sites/{id}/request-stats;
site overview and resource list show requests in the last 24 hours
Resource list: two-layer rows. Main line: title + spec tags (episodes,
resolution, source, codec, HDR, group, 国语/中字, site tags) + promotion
with time left + H&R. Second line: subtitle (one line, ellipsis) and
fixed-width category / size / seed-leech-snatched / upload time
(relative, absolute on hover) columns, stale badge, inventory overlay;
folds into a card on phones.
Also aligns identity_candidate.normalized_title order in db types with
the migrations (schema drift test).
Takes effect after the stack is rebuilt (migration 0046).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
20b63db254
commit
901b01d1a1
43 files changed
+1222
-1315
No files matched your search
+12
-3
@@ -61,7 +61,7 @@
|
||||
| key | 名称 | 默认 | 行为 |
|
||||
|---|---|---|---|
|
||||
| `sites.user_data` | 站点数据刷新 | 每 6 小时,一个周期后首跑 | 启用站点里 `status=active` 的非 passkey 账号逐个入队 `refreshSiteAccount{mode:"userData"}`;会话失效的账密账号自动重登一次;只读对账模式跳过 |
|
||||
| `sites.health_check` | 站点健康检测 | 每小时,一个周期后首跑 | 启用站点(非 generic_rss)逐个同步检测;可在定时任务页关闭 |
|
||||
| `sites.health_check` | 站点健康检测 | 每小时扫描,一个周期后首跑 | 启用站点(非 generic_rss)逐个同步检测;距上次检测(手动或定时)不足该站健康检测间隔(缺省 6 小时)的跳过;可在定时任务页关闭 |
|
||||
|
||||
注:定时任务 key 只允许小写(注册表校验),所以规格里的 `sites.userData` / `sites.healthCheck` 落为下划线形式。
|
||||
|
||||
@@ -74,14 +74,23 @@
|
||||
|
||||
| 字段 | 缺省 | 说明 |
|
||||
|---|---|---|
|
||||
| `defaultRateLimit` | `{requestsPerMinute: 20, concurrency: 1}` | 站点 `rate_limit` 为空时使用;不会比定义里的 `umt.rateLimit` 更激进(取两者较慢的间隔、较小的并发) |
|
||||
| `defaultSnapshotIntervalSec` | 3600 | 站点开了定时快照但未设周期时使用 |
|
||||
| `defaultRateLimit` | `{requestsPerMinute: 20, concurrency: 2}` | 站点 `rate_limit` 为空时使用;不会比定义里的 `umt.rateLimit` 更激进(取两者较慢的间隔、较小的并发) |
|
||||
| `defaultSnapshotIntervalSec` | 3600 | 站点开了定时快照但未设周期时使用(与定义 `umt.defaults.snapshotIntervalSec` 取较长) |
|
||||
| `defaultSnapshotMaxPages` | 1 | 定时 / 手动快照最多抓几页(与定义取较小);补漏有自己的页数预算,实时补查固定 1 页 |
|
||||
| `defaultHealthCheckIntervalSec` | 21600 | 定时健康检测的最短间隔(与定义取较长) |
|
||||
| `defaultDetailCacheSec` | 86400 | 详情缓存:期内 `GET /sites/{id}/releases/{rid}?refresh=true` 与 `release.inspect` 不再请求站点(与定义取较长);0 = 不缓存 |
|
||||
| `userAgent` | 固定桌面 Chrome UA | 账号未设 UA 时用于登录与用户数据 |
|
||||
| `proxyUrl` | null | 站点 `proxy=true` 时,适配器、登录、用户数据请求都经此代理(`Deno.createHttpClient`) |
|
||||
| `userDataMaxSeedingPages` | 10 | 用户数据做种分页上限 |
|
||||
|
||||
运行时每 30 s 最多重读一次设置;设置变化会让站点适配器按新签名重建。
|
||||
|
||||
## 访问默认与请求统计
|
||||
|
||||
站点定义可带 `umt.defaults`(`snapshotIntervalSec / snapshotMaxPages / healthCheckIntervalSec / userDataIntervalSec / searchConcurrency / detailCacheSec`),是按站点实测给的保守下限;运行时 `siteAccessFor(def, settings.sites)` 合并:周期、缓存取较长,页数取较小;`searchConcurrency`(缺省 1)让同站不同关键词的实时补查排队执行。目前只有憨憨配置了(快照 60 分钟 1 页、健康检测 6 小时、用户数据 6 小时、搜索并发 1、详情缓存 24 小时、限流 3 秒 1 个令牌突发 2)。
|
||||
|
||||
每从站点限流器拿到一个令牌(列表、搜索、详情、下载、登录、用户数据、原站视图导航)记一次请求,写 `site_request_count`(迁移 `0046`,按小时聚合,多进程共用,保留 7 天)。`GET /sites/{id}/request-stats`(read)返回最近 24 小时总数、按小时明细、快照实际周期与合并后的访问默认;站点页概览「近 24 小时请求」与资源页列表头显示。计数只在升级后开始累计。
|
||||
|
||||
## Agent 能力(W10-pre2)
|
||||
|
||||
处理器在 `apps/server/src/modules/sources-identity/capabilities-sites.ts`,调用上面同一组 service。能力 ID 只允许小写 + 下划线(`CapabilityId` 正则),所以规格里的 `site.healthCheck` / `site.refreshLogin` / `site.userData` 落为下划线形式。
|
||||
|
||||
Reference in new issue
Block a user