广播里存着一段豆瓣自己都不留的历史
NeoDB 的维护者看了 PR,问了一句「可以生成 NDJSON 吗」。换过去之后多带走的不只是豆列——3411 条广播拼出一条状态时间线,而豆瓣自己已经不显示它了。
上一篇写的是 NeoDB 那一路真导了一次。那次导的是 CSV。维护者看完 PR 回了一句:
厉害。可以生成NDJSON吗?旧的CSV格式只是为了兼容NiceDB和Doufen,限制太多了。
这句话里有一个我原先不知道的事实:那套 CSV 不是 NeoDB 的格式, 是它为了兼容另外两个工具留下的一层壳。而我把导出建在了那层壳上。
换格式换来的东西比预想的多
原先「还没做的」里第一条写着豆列导不进去——NeoDB 的收藏单只存在于它自己的 NDJSON 归档格式里。所以我以为换过去就是把这一条划掉。
实际上 NDJSON 多装下四样,拿真实的 2950 条标记量过:
- 豆列 —— 6 份、134 条,其中 73 条是能落地的作品条目。
- 不挂作品的日记 —— 5 篇长文里的 3 篇。CSV 的笔记必须挂一个条目,这 3 篇原先是直接丢掉的。
- 每条记录各自的可见性 —— 那一份私密豆列现在能以私密的身份进去。
- 状态历史 —— 3179 条。
最后一条是这次真正的发现,而且它不是从 NeoDB 那边来的,是从档案里翻出来的。
豆瓣只存现在,广播存着当时
豆瓣的标记只有当前状态:你现在是「看过」,打了四星。你什么时候从「想看」 变成「在看」的、当时打了几星,它不留。
但广播是发出去那一刻就冻住的。「想看 XXX」是一条, 「在看 XXX ★★★★★」是另一条,「看过 XXX ★★★★」是第三条, 每一条都带着自己的日期和自己的星。
3411 条广播里,3179 条能对上档案里的某个作品。它们覆盖 2373 件作品,
其中 678 件的状态变过不止一次。而 NDJSON 里正好有一种记录
叫 ShelfLog,装的就是这个。
所以这一步不是「把已有的数据换个格式送出去」,是把一段已经在档案里、 但从没有出口的东西送了出去。这也是这个项目一直在说的那句话的一次兑现: 原始页面抓下来了,能不能用得上,是后来才知道的事。
默认是关着的(--shelf-history)。它是全新的一条路,
还没有真导过一次——理由跟下面最后一节一样。
形状是读源码读出来的,五个坑都是静默的
跟上次一样:读导入器的源码,不读它的文档。这一路读出来五个地方, 写错了都照样是合法 JSON、照样解析通过、照样不报错:
-
ShelfLog的形状跟其他记录都不一样。 别的记录读content.withRegardTo/content.status/content.published,只有它读顶层的item/status/timestamp。 -
ShelfMember上没有标签这一项。 CSV 是把标签挤在标记那一行里的。照那个想法写,712 个标签会一声不吭地全丢。 -
progress是三态的。 键不在 = 不动,null= 清掉用户手工填的阅读进度,有值 = 恢复。 豆瓣不记「读到第几页」,所以这个键必须整个不写—— 写null是去删别人的数据。 -
舞台剧的广播
target_type叫loc,不叫drama。 12 种取值里根本没有drama。 照着自己这边的字段名去猜键名,那几条会全部漏掉。 -
豆列里分类 3114、写成
/subject/的其实是游戏。 NeoDB 只认www.douban.com/game/<id>/。改写是量出来的: 31 条 id 在档案里的条目,30 条是游戏,档案里存的 URL 全是/game/。
前三条现在有一个静态契约测试盯着:把导入器源码里 「每种记录在哪一层读哪些键」抄成一张表,对着产出断言。 真正会出事的环境是一个跑着的 NeoDB,本地任何测试都进不去, 所以检查只能是静态的——这跟扩展那边 offscreen 的那个检查是同一类问题。
也换来两处倒退,一并说了
-
没有 ISBN 兜底。 NDJSON 这条路上,条目只靠 URL 匹配
(导入器传给匹配函数的标题和 info 都是空字符串)。CSV 那边
info列里的isbn:还能找回一本豆瓣页面已经没了的书。 IMDb 有 URL 形式,ISBN 没有。 -
上传页面上没有可见性选项。 它检测到 NDJSON 就把那三个单选框
藏起来,于是一律按公开导入。所以这个选择被挪进了文件里——
--visibility=1或2。 文件能表达表单表达不了的东西,这跟私密豆列是同一条理由。
旧的 CSV 那一份没删,改成要显式要(--target=neodb_csv)。
它现在只在上面这两件事上比 NDJSON 强,而那两件事都是真的。
还没做的,还是那一句
NDJSON 这一路还没有真导过一次。上一篇的结论在这里同样成立: 「我理解对了他们的代码」和「他们真的收下了」是两件事。 在有人真导一次之前,这一路的说法只能是「符合从导入器源码里读出来的格式」, 不是「能用」。