Files
douyin-pc/docs/2026-09-07-14-49-persistent-history-work-cache.md
T

6.4 KiB
Raw Blame History

作品与历史事件持久缓存方案(0.1.8)

目标

将原来只存在于进程内存中的作品列表和历史事件预览改为 SQLite 持久缓存,并保持以下行为:

  • 首次同步获取平台当前可返回的全部数据,后续只增量读取新数据。
  • 程序重启后仍可查看已有作品和事件,不依赖重新全量请求。
  • 实时事件和历史事件共用本地事件缓存;实时来源优先,不会被后续历史同步降级。
  • 历史操作仍须“预览勾选 + 二次确认”,实时任务优先于历史任务。
  • 每个大号独立配置作品刷新间隔,默认 60 分钟,0 表示关闭。
  • 自动刷新只在对应账号组运行时发生;手动“强制增量刷新”始终可用。
  • 普通界面不显示数字时间戳和原始 JSON;完整业务字段仅保留在 SQLite 中用于定位。

数据库变更

cached_works

(source, aweme_id) 唯一保存每个大号的作品:

  • create_time:平台发布时间,内部保留数值。
  • description:作品描述。
  • statistics:点赞、评论、收藏、分享等完整统计 JSON。
  • cover:封面地址。
  • business:完整平台业务对象;认证字段写入前递归替换为 [凭据已隐藏]
  • updated:本地最后合并时间。

重复作品使用 upsert 更新描述、统计、封面和业务对象,不产生重复行。

cached_notices

(source, nid) 唯一保存每个大号的历史和实时事件:

  • 提取并索引事件时间、类型、作品 ID、来源 UID/昵称、评论和作品描述。
  • business 保存经过认证字段保护的完整通知对象。
  • originhistorylive
  • 同一通知先历史同步、后实时收到时,来源提升为 live;以后再次历史同步不会降回 history

新增索引支持按账号/时间以及账号/作品/类型/时间读取。

规则与刷新状态

大号规则新增 works_refresh_interval,单位秒:

  • 默认 3600
  • 有效范围 0..604800(最多 7 天)。
  • 旧规则自动补默认值,不改写已有作品范围、任务或账号归属。

settings 表使用 works_refreshed_at:<account-id> 保存上次成功请求时间。旧数据库启动时通过 CREATE TABLE IF NOT EXISTS 和规则默认值直接迁移,无需用户手工操作。

同步流程

作品

  1. 打开“作品监控”。
  2. 本地没有缓存时,分页读取全部历史作品并写入 SQLite。
  3. 本地已有缓存时,普通打开只读本地数据,不发送平台请求。
  4. 手动强制刷新或运行期间到达刷新间隔时,从最新页开始读取;遇到已缓存作品 ID 后停止继续翻页。
  5. 将返回作品 upsert 到缓存,再显示完整本地列表。

分页仍校验账号 UID、64 位 ID 字符串、返回结构和游标推进;游标不推进会立即拒绝,避免死循环。

历史事件

  1. 每次打开“历史事件操作”都执行增量同步。
  2. 本地无事件时分页读取全部历史事件;已有事件时遇到缓存通知 ID 后停止翻页。
  3. 同步固定使用只读参数 is_mark_read=0,不会标记已读。
  4. 保存后按当前大号的作品监控规则过滤:指定作品模式只显示命中作品;关注事件不受作品筛选。
  5. UI 可再按中文事件类型过滤;仅当前显示并勾选的行进入二次确认。

实时监听调用原有 Store.ingest() 时先写入 cached_notices,因此没有匹配规则、没有可用小号或暂未创建任务的实时事件也仍可留作查看。

调度行为

账号组主循环读取该大号的刷新间隔:

  • 首次运行且从未同步作品时立即建立缓存。
  • 到达间隔后复用当前已登录会话进行增量刷新。
  • 刷新失败只记录原因,不中断通知监听;下一间隔再试。
  • 停止账号组会退出主循环,因此不会继续自动请求。

历史任务继续使用优先级 0,实时任务使用优先级 100。同 UID 实时事件可取消尚未执行的历史任务;已执行、执行中和待核对任务不重发、不静默改写。

界面变化

  • 原“获取近期作品”和“获取全部历史作品”合并为一个“作品监控”。
  • 作品表显示正常日期、描述、ID、点赞、评论、收藏、分享、封面地址和本地更新时间。
  • 作品弹窗提供每大号刷新分钟数和“强制增量刷新”。
  • 历史表显示正常日期、中文类型、来源用户、作品、评论、通知 ID 和数据来源。
  • 历史表可按事件类型筛选;全选、清空和最终提交只作用于当前显示行。
  • 任务结果把常见平台字段转换为中文摘要;原始结构只在数据库中保留。

认证信息保护

作品和事件完整业务对象写库前复用 account_log.visible() 递归处理。Cookie、Authorization、Session、Token、密码、verifyFpa_bogus、X-Bogus、X-TT-Params 和签名字段不会以可直接使用的值保存或显示。

验证

本地回归测试:

.venv/bin/python -m pytest -q
74 passed

新增测试覆盖:

  • 作品缓存重复 upsert。
  • SQLite 关闭重开后的作品、通知和刷新规则持久化。
  • 历史来源提升为实时来源且不会降级。
  • 指定作品过滤和关注事件例外。
  • 缓存业务对象的认证字段隐藏。
  • 新作品监控命令、刷新间隔保存和无 JSON 的用户界面。

Windows 发布验证结果:

  • Windows pytest74 passed
  • fingerprint-chromium/Patchright 浏览器矩阵:全部通过,real_write_actions=0
  • 打包 GUI 冒烟:Qt、核心模块、SQLite、Patchright、浏览器均通过,accounts=0real_write_actions=0
  • 构建清单:版本 0.1.8,23 个 Python 源文件哈希全部一致。
  • 已登录真实账号只读验证:个人资料、历史事件、作品请求均为 HTTP 200、业务码 0,UID 归属正确,64 位 ID 保持字符串;未执行关注或私信。
  • 安装包:222,660,069 字节,SHA256 9b91d9fcfb91a423e9730288b58c11d0dd9732c6c88cc663f059ff2f2a1141d8

空白 Windows 环境安装

最终安装包继续包含 Python、Qt、Patchright 和锁定版本的 fingerprint-chromium。用户只需运行:

DouyinAccounts-0.1.8-Windows-x64-Setup.exe

无需安装额外运行时。覆盖安装会保留 %LOCALAPPDATA%\DouyinAccounts 下的账号、数据库、登录目录、缓存、任务和日志。