在Notion整理Kobo電子書櫃與筆記
10 Mar 2022購入 Kobo 電子書閱讀器超過兩年了,也累積了一定的閱讀量。
但我時常會覺得自己劃過的重點,好像劃了就過了,後來也都不曾翻出來讀。
前陣子在社群上看到討論如何把劃線筆記匯出,突然又想起了這件事情,剛好我最近熱衷於用 Notion 整理身邊的各種資料,不然我串個 Notion 的 API 把書單跟筆記通通傳上去好了?
步驟
起初我想找 Kobo 有沒有網頁版的閱讀器,這樣就有機會透過爬蟲處理,結果當然是吃了閉門羹。
而我又十分懶惰,不想一筆一筆建檔,本來就要這麼放棄了,直到在 Facebook 看到網友的分享才注意到閱讀器裡面的資料庫可以直接讀取。
原討論串:樂天 Kobo 電子書社群
所以要做的事情就很簡單了:
- 從閱讀器裡的 DB 檔案讀取我要的資訊
- 串接 Notion API 把資料打上去
Kobo 的資料庫
讀取資料庫多少涉及一點逆向工程,雖然我個人認為無傷大雅(沒有改機,或破解任何東西),但仍不確定是否有違反使用合約,請自行斟酌。
閱讀器的資料庫位於下列位址,可以直接插 USB 從電腦把檔案複製出來。
/.kobo/KoboReader.sqlite
由副檔名可以得知他是 SQLite,隨便找個簡單的 SQLite Browser 就可以瀏覽裡面的內容了。花了一點時間東拼西湊一下,最後測試可以列出所有我買的書的基礎語法長這樣:
SELECT * FROM content
WHERE ContentType = 6 AND
AnnotationsSyncToken IS NOT NULL AND
DownloadUrl = 'true'
而取得所有劃線筆記的語法則是這樣:
SELECT * FROM Bookmark B
LEFT JOIN content C ON B.VolumeID=C.ContentID
WHERE B.Type='highlight'
PS: 這是我自己推敲出來的結果,不保證其他型號也適用
Notion
原始規劃
一開始的想法很單純,開一個 database,用來放書,打開書的頁面之後把劃線筆記用 List 的方式一行一行存在下方的內容區塊。
後來捨棄的原因是,我想要一個頁面可以瀏覽所有的劃線筆記,像是單字卡那樣的感覺。但這樣就會遇到需要跨 table 關聯的問題
關聯的意思就是,我的筆記勢必會有一個欄位用來記錄這是來自哪一本書,而這個書名會來自另一個 database 的資料
感覺有點麻煩不知道 Notion 行不行?
結果抱著好奇的心態一查,Notion 竟然支援關聯 DB。
最終定案
最後規劃成兩個 db,一個存書單,一個存筆記清單,然後再把兩個用 relation 關聯起來就大功告成了。
寫成程式
Notion API 的用法網路上應該不少教學,官方的API 文件也還算清楚,我就不花太多篇幅贅述了
1. 事前準備
- 在My integrations頁面開一支新程式,並記下你的 API token
- 建立一個可以供 API 讀寫的 Page,記下你的 Page ID 並將 Page 分享給你的 Integrations
2. 程式邏輯
以下說明的程式碼僅說明概念。實際的程式我還在改善中
- 檢查 Page 上的 DB 是否存在,不存在就用 Notion API 開一個
if (!booksDBID) { API.createDB(); }
- 用 API 把線上的資料讀出來,並做成 ID-ISBN 的 Mapping(我用 ISBN 當識別)
let bookMap = API.getAll().map((item) => { return { id: item.id, isbn: getISBN(item), }; });
- 跟 SQLite 裡面的資料比對,不存在就新增,存在就更新
db.each(SQL_STMT, (err, row) => { let exist = bookMap.find((item) => row.ISBN == item.isbn); if (exist) { API.update(row); } else { API.insert(row); } });
成果
上傳好之後,再手動設定適合的 View,因為這個部分似乎無法靠 API 完成。
最後的成果如下圖:
備註
1. 書封的來源
DB 裡有個欄位是ImageId
,取得之後可以透過下列網址下載封面圖片:
https://ecimages.kobobooks.com/Image.ashx?imageID={ImageId}
2022/11/3 補充更新
或許是官方調整過,上述的網址似乎不開放使用了,現在呼叫只會拿到一張預設圖片。經搜尋過網路上其他討論以及研究 Kobo 網頁版的商城,目前改用下列網址取得圖片:
https://kbimages1-a.akamaihd.net/{ImageId}/1000/1333/80/False/image.jpg
網址參數的意義參考自此篇討論串:[Kobo] Performance issues with cover images #1347
由於 Notion 並不支援透過 API 直接上傳檔案作為頁面的 Banner 使用,所以除非願意自己架圖床,不然只能先這樣透過外站的資源處理了
2. 閱讀時數
閱讀時數的欄位名稱是TimeSpentReading
,單位是秒,可以自己寫個 formula 去換算成比較好理解的敘述