重要:本次是破坏性更新。
服务端账号与鉴权系统升级后,旧版本客户端保存在本地的 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 无法继续通过校验,表现为同步失败或设备授权失效。
这是本次升级的预期行为,不是阅读数据损坏。
处理方式很简单:
- 更新到新版客户端
- 重新扫码登录一次
- 登录后同步功能即可恢复
阅读日志仍然保存在原来的 log 目录里,不需要删除,也不会因为重新登录而丢失。
升级指南
Kindle 用户
- 前往 kindle-reading-gtk Releases 下载
0.4.0版本。 - 根据固件版本选择:
- 固件低于 5.16.3:
kindle-reading-gtk_kindlepw2(armel) - 固件高于 5.16.3:
kindle-reading-gtk_kindlehf(armhf)
- 固件低于 5.16.3:
- Kindle 用户请同时下载对应的
libcurl,并按发布页说明与主程序放在一起。 - 替换插件
bin目录中的旧程序。 - 打开 Kykky,进入「更多」→「云同步」:
- 如果显示设备授权失效,点「强制注销」
- 然后重新扫码登录
- 回到首页,确认今日/本周/本月/总计数据正常显示。
如果更新后仍然提示同步失败,可以先强制注销再重新扫码。不要删除 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 失效,需要更新客户端并重新登录。但长期来看,服务端统一计算、持久会话和每日重算会让数据更稳定,也方便后面继续加功能。
相关链接:
- 项目主页:TQHYG/kykky
- 客户端:TQHYG/kindle-reading-gtk
- 服务端:TQHYG/kindle-reading-php
- 阅读统计站:reading.tqhyg.net
- 上一篇介绍文章:Kindle 阅读统计工具:量化你的阅读生活,每一分钟都算数
如果更新后遇到问题,或者对周榜/总榜有什么建议,欢迎到 GitHub 提 Issue。
阅读数据会继续记录,习惯也会继续。量化阅读不是目的,保持阅读才是。
除非注明,否则均为天远日记原创文章,转载必须以链接形式标明本文链接
Comments NOTHING