Kykky 阅读统计 2.0:周榜、总榜上线,以及一次必须重新登录的破坏性更新

技术交流天穹何以高 发布于 18 小时前 24 次阅读 2064 字 预计阅读时间: 9 分钟


重要:本次是破坏性更新。

服务端账号与鉴权系统升级后,旧版本客户端保存在本地的 Token 将无法继续使用。
请先更新到新版客户端,并重新扫码登录。数据不会丢失,重新登录后功能即可恢复正常。

距离上次写 Kindle 阅读统计工具 已经过去了一段时间。这期间 Kykky 一直在小修小补,而这次是一次比较大的更新:服务端和 Web 端做了重构,客户端也同步升级了上传协议。

先说结论:

  • 新增 周榜 和 总榜
  • Web 登录改为持久会话,不再那么容易掉登录
  • 服务端每天凌晨会根据已上传日志重新计算统计数据
  • 客户端上传新增本周、总计时长,并增强了网络异常处理
  • 旧客户端 Token 会失效,需要更新客户端并重新登录
  • 数据库只做增量迁移,不删除原有用户、设备和阅读数据

这次更新了什么

1. 周榜和总榜

排行榜现在有四个维度:

  • 日榜
  • 周榜
  • 月榜
  • 总榜

周榜以周一为一周起点。总榜则统计该账号保存过的全部阅读时长。

服务端会从上传的 metrics_reader_* 和 history.gz 中重新解析日志,计算今日、本周、本月和总计,而不是完全依赖客户端上报的数字。这样即使旧客户端没有上传新字段,只要日志还在,服务端也能补算。

2. Web 端重构为静态前端 + API

以前 Web 页面是 PHP 直接渲染的,这次拆成了:

  • Web 根目录只放静态 HTML/CSS/JS
  • 所有接口统一放在 /api
  • 页面通过 JavaScript 请求 API

同时把 Bootstrap、Font Awesome、Chart.js、pako、html2canvas 这些前端依赖全部下载到了本地,不再依赖公共 CDN。国内网络环境下页面会更稳定一些。

旧入口仍然保留,例如 /share.php、/device.php、/fastsync.php 会自动跳转到新的静态页面,老链接不会直接失效。

3. 持久登录

以前 Web 端依赖 PHP Session,服务器清理或 Cookie 过期后很容易掉登录。这次新增了数据库会话表:

  • 登录状态保存在数据库
  • Cookie 使用 HttpOnly + SameSite=Lax
  • 默认一年有效,临近过期自动续期
  • 退出登录会立即吊销会话

Web 端旧 Session 不再有效,所以升级后需要重新用 GitHub 登录一次。

4. 每天自动重算统计

服务端新增了每日重算逻辑,并合并进 api/cron.php:

  • 每天凌晨 00:20 - 04:59 之间自动执行一次
  • 根据用户已上传的日志重新计算今日、本周、本月、总计
  • 使用完成标记避免一天重复执行
  • 也可以手动执行 php api/cron.php --recalc

这样旧客户端缺失的周/总数据,会在后续重算中慢慢补齐。

5. 客户端网络层增强

新版客户端 0.4.0 主要改了账号和网络部分:

  • 上传新增本周、总计字段
  • 离线快捷同步二维码也包含新字段
  • 增加 HTTP 状态码检查
  • 处理超时、空响应、二维码过期、设备未绑定等情况
  • 登录轮询失败时会显示原因,不再静默等待
  • Token/state 改为原子写入,并设置 0600 权限
  • 修复云同步对话框重复 gtk_box_pack 导致的 GTK 警告

此外,客户端配置新增了 share_scheme,share_domain 也可以直接写完整 URL,方便自定义服务端地址。

重要:为什么旧 Token 会失效

这次服务端对账号和鉴权配置做了升级。旧版客户端保存在 etc/token 里的设备 Token 无法继续通过校验,表现为同步失败或设备授权失效。

这是本次升级的预期行为,不是阅读数据损坏。

处理方式很简单:

  1. 更新到新版客户端
  2. 重新扫码登录一次
  3. 登录后同步功能即可恢复

阅读日志仍然保存在原来的 log 目录里,不需要删除,也不会因为重新登录而丢失。

升级指南

Kindle 用户

  1. 前往 kindle-reading-gtk Releases 下载 0.4.0 版本。
  2. 根据固件版本选择:
    • 固件低于 5.16.3:kindle-reading-gtk_kindlepw2(armel)
    • 固件高于 5.16.3:kindle-reading-gtk_kindlehf(armhf)
  3. Kindle 用户请同时下载对应的 libcurl,并按发布页说明与主程序放在一起。
  4. 替换插件 bin 目录中的旧程序。
  5. 打开 Kykky,进入「更多」→「云同步」:
    • 如果显示设备授权失效,点「强制注销」
    • 然后重新扫码登录
  6. 回到首页,确认今日/本周/本月/总计数据正常显示。

如果更新后仍然提示同步失败,可以先强制注销再重新扫码。不要删除 log 文件夹。

Web 用户

直接访问 reading.tqhyg.net,用 GitHub 重新登录一次即可。

之前的排行榜数据、设备和日志都还在。新的周榜、总榜会在每日重算或下次同步后逐步完整。

自建服务端用户

这次服务端改动较多,升级前请先备份数据库和 storage 日志目录。

数据库只需要执行增量迁移:

mysql -uroot -p kykky_db < api/sql/migration_v2_sessions.sql
mysql -uroot -p kykky_db < api/sql/migration_v3_week_total.sql

迁移只新增 sessions 表,以及 stats.week_seconds、stats.total_seconds 两列,不会删除原有数据。

迁移完成后回填一次历史统计:

php api/cron.php --recalc

配置和 nginx 也有变化:

  • 配置文件现在放在 Web 根目录的 config.php
  • 必须由 nginx 拒绝访问 /config.php 和 /config.sample.php
  • 只有 /api/*.php 交给 PHP-FPM
  • GitHub OAuth 回调改为 /api/github.php?action=callback
  • 如果服务器在 WAF/反向代理后,建议加 absolute_redirect off,避免跳转带上内部端口

详细步骤放在仓库的 docs/MIGRATION.md 和 docs/NGINX.md 里。

一点开发小记

这次服务端重构最大的感受是:统计逻辑不能只放在客户端。

旧版主要依赖客户端算好今日、本月再上传,服务端只存两个数字。一旦客户端版本不一致、上传中断,或者用户只上传了部分日志,排行榜数据就容易不一致。

新版改成服务端重新解析日志,客户端上报的数字只作为没有文件时的兜底。再加上每天凌晨的日志重算,旧客户端缺失的数据也会慢慢补齐。

另一个比较隐蔽的问题是 nginx 在 WAF 反向代理后生成绝对跳转:

Location: https://example.com:10443/share.html

浏览器会跳到内部端口。解决办法是在 nginx 的 http 或 server 块加上:

absolute_redirect off;
port_in_redirect off;
server_name_in_redirect off;

这样 nginx 会返回相对地址:

Location: /share.html

公网域名和端口就能保持不变。

结语

这次更新看起来是一次“排行榜加两个 tab”,但底层其实动了账号、上传协议、统计计算和 Web 架构。

短期会有一点升级成本:旧 Token 失效,需要更新客户端并重新登录。但长期来看,服务端统一计算、持久会话和每日重算会让数据更稳定,也方便后面继续加功能。

相关链接:

如果更新后遇到问题,或者对周榜/总榜有什么建议,欢迎到 GitHub 提 Issue。

阅读数据会继续记录,习惯也会继续。量化阅读不是目的,保持阅读才是。

除非注明,否则均为天远日记原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.tqhyg.net/post708.html