This commit is contained in:
douboer
2025-08-15 13:49:02 +08:00
parent 8873c70a60
commit 0bc6844209
76 changed files with 726 additions and 11197 deletions

View File

@@ -8,6 +8,8 @@ exportbooknotes.py
- 命令行菜单按最近打开时间降序展示书籍列表,供用户选择导出。
- 仅导出选中书籍的所有笔记按章节分组生成Markdown文件。
依赖config.py 统一管理路径和配置项。
主要数据流:
1. 数据同步到data目录
2. 解析Books.plist获取书籍元数据
@@ -19,10 +21,13 @@ exportbooknotes.py
依赖Python 3, InquirerPy, bs4, shutil, os, datetime, sqlite3
主要数据流:
典型用法:
python exportbooknotes.py
# 按提示选择书籍自动导出笔记到export_notes目录
"""
import config
"""
自动生成 booksnote 数据结构:
booksnote = {
@@ -63,7 +68,7 @@ def get_toc_tree(toc_path):
#pprint(toc_tree, indent=2, depth=5)
return toc_tree
def build_booksnote(annotation_db='data/AEAnnotation.sqlite', books_plist='data/Books.plist', bookid=None):
def build_booksnote(annotation_db=config.LOCAL_ANNOTATION_DB, books_plist=config.LOCAL_BOOKS_PLIST, bookid=None):
# 支持只处理特定 assetid 的笔记
annotations = get_annotations(annotation_db, bookid=bookid)
booksinfo = parse_books_plist(books_plist)
@@ -148,11 +153,11 @@ if __name__ == '__main__':
import os.path
# 自动覆盖 ./data 下的数据库和plist文件源为iBooks真实路径
src_files = [
(os.path.expanduser('~/Library/Containers/com.apple.iBooksX/Data/Documents/AEAnnotation/AEAnnotation_v10312011_1727_local.sqlite'), 'data/AEAnnotation.sqlite'),
(os.path.expanduser('~/Library/Containers/com.apple.iBooksX/Data/Documents/AEAnnotation/AEAnnotation_v10312011_1727_local.sqlite-shm'), 'data/AEAnnotation.sqlite-shm'),
(os.path.expanduser('~/Library/Containers/com.apple.iBooksX/Data/Documents/AEAnnotation/AEAnnotation_v10312011_1727_local.sqlite-wal'), 'data/AEAnnotation.sqlite-wal'),
(os.path.expanduser('~/Library/Containers/com.apple.iBooksX/Data/Documents/BKLibrary/BKLibrary-1-091020131601.sqlite'), 'data/BKLibrary.sqlite'),
(os.path.expanduser('~/Library/Containers/com.apple.BKAgentService/Data/Documents/iBooks/Books/Books.plist'), 'data/Books.plist')
(config.IBOOKS_ANNOTATION_DB, config.LOCAL_ANNOTATION_DB),
(config.IBOOKS_ANNOTATION_SHM, config.LOCAL_ANNOTATION_SHM),
(config.IBOOKS_ANNOTATION_WAL, config.LOCAL_ANNOTATION_WAL),
(config.IBOOKS_LIBRARY_DB, config.LOCAL_LIBRARY_DB),
(config.IBOOKS_BOOKS_PLIST, config.LOCAL_BOOKS_PLIST)
]
for src, dst in src_files:
if os.path.exists(src):
@@ -165,7 +170,7 @@ if __name__ == '__main__':
from InquirerPy import inquirer # type: ignore
# 先获取所有书籍元数据
booksinfo = parse_books_plist('data/Books.plist')
booksinfo = parse_books_plist(config.LOCAL_BOOKS_PLIST)
# 构建书名列表优先displayname, 其次itemname, 否则assetid按parse_books_plist中的date字段排序
assetid2name = {}
@@ -173,7 +178,7 @@ if __name__ == '__main__':
from booklist_parse import get_books_last_open
# 获取所有书籍的最后打开时间(字典,值为{'last_open': 时间戳}
last_open_times = get_books_last_open('data/BKLibrary.sqlite')
last_open_times = get_books_last_open(config.LOCAL_LIBRARY_DB)
for assetid, info in booksinfo.items():
name = info.get('displayname') or info.get('itemname') or assetid