'update'
This commit is contained in:
149
readme.md
149
readme.md
@@ -1,6 +1,6 @@
|
||||
# iBooks 笔记专家 详细设计文档
|
||||
|
||||
> 版本: 1.1 (2025-09 重构整理)
|
||||
> 版本: 1.2 (2025-10 CFI排序与优化)
|
||||
> 维护者: 项目开发组
|
||||
> 说明: 本文档统一重新编排章节,增加架构与 UML 部分,便于后续扩展与维护。
|
||||
|
||||
@@ -8,11 +8,19 @@
|
||||
|------|------|------|
|
||||
| 1.0 | 2025-08 | 初版文档 |
|
||||
| 1.1 | 2025-09 | 重组目录;新增模块拆分、UML、AI 简评与可视化章节整理 |
|
||||
| 1.2 | 2025-10 | **重大更新**: EPUB CFI排序系统,界面优化,性能提升 |
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本工具用于从 macOS iBooks(Apple Books)应用的数据文件中提取用户的书籍笔记,并以 Markdown 格式导出。支持从 iBooks 的数据库和 plist 文件自动同步数据,支持交互式选择书籍导出,导出内容结构清晰,便于后续整理和阅读。
|
||||
支持按最近打开时间排序书籍,菜单显示书名与时间戳,导出流程高效。
|
||||
本工具用于从 macOS iBooks(Apple Books)应用的数据文件中提取用户的书籍笔记,并以 Markdown 格式导出。**v1.2版本重大改进**:实现完整的EPUB CFI(Canonical Fragment Identifier)排序系统,确保笔记按真实阅读位置排序,支持交互式选择书籍导出,导出内容结构清晰,便于后续整理和阅读。
|
||||
|
||||
### 🆕 v1.2 新特性
|
||||
|
||||
- **🎯 EPUB CFI 排序**: 完整实现IDPF规范,笔记按文档真实位置排序
|
||||
- **📊 阅读统计修复**: 7天/30天/年度阅读时长统计准确性提升
|
||||
- **🎨 界面优化**: 清理控制台警告,改进按钮交互效果
|
||||
- **⚡ 性能提升**: 优化数据处理流程,减少冗余计算
|
||||
- **🧪 测试覆盖**: 全面的CFI解析、排序、导出验证测试
|
||||
|
||||
---
|
||||
|
||||
@@ -22,11 +30,27 @@
|
||||
|
||||
- 自动同步 iBooks 数据库和书籍信息文件到本地 `./data` 目录。
|
||||
- 解析 iBooks 笔记数据库,构建结构化的 `booksnote` 数据。
|
||||
- **🆕 EPUB CFI 排序**: 按 EPUB 规范解析 CFI 位置信息,确保笔记按真实阅读顺序排列。
|
||||
- 解析书籍元数据(如书名、路径等)。
|
||||
- 支持交互式模糊搜索选择要导出的书籍。
|
||||
- 按章节导出所选书籍的所有笔记,格式为 Markdown。
|
||||
- 书名中如含有“-xxxx”后缀,仅保留“-”前的主书名。
|
||||
- 书籍选择菜单按最近打开时间(last_open)降序排序,显示格式为“书名 [时间戳]”。
|
||||
- 书名中如含有"-xxxx"后缀,仅保留"-"前的主书名。
|
||||
- 书籍选择菜单按最近打开时间(last_open)降序排序,显示格式为"书名 [时间戳]"。
|
||||
- **🆕 阅读统计**: 精确的7天/30天/年度阅读时长统计和可视化图表。
|
||||
|
||||
### 2.1.1 CFI 排序技术
|
||||
|
||||
EPUB CFI (Canonical Fragment Identifier) 是 IDPF 制定的标准,用于精确定位 EPUB 文档中的位置:
|
||||
|
||||
```
|
||||
epubcfi(/6/22[id19]!/4[section]/40/1,:96,:214)
|
||||
```
|
||||
|
||||
- **Spine 路径** (`/6/22`): 文档结构中的章节位置
|
||||
- **Local 路径** (`/4[section]/40/1`): 章节内的元素位置
|
||||
- **字符偏移** (`:96,:214`): 文本内的精确字符范围
|
||||
|
||||
v1.2 实现完整的 CFI 解析和排序算法,确保笔记按真实阅读顺序而非字符串顺序排列。
|
||||
|
||||
## 2.1 GUI
|
||||
|
||||
@@ -67,9 +91,12 @@
|
||||
|
||||
## 4. 主要数据结构
|
||||
|
||||
### 4.1 booksnote
|
||||
### 4.1 booksnote (v1.2 CFI 排序优化)
|
||||
|
||||
**v1.2 数据结构变更**:为支持 CFI 排序,`annotations` 数据结构从嵌套字典改为列表格式:
|
||||
|
||||
```python
|
||||
# v1.1 及之前版本
|
||||
booksnote = {
|
||||
assetid: { label_path: { uuid: {
|
||||
'creationdate': '2023/7/12',
|
||||
@@ -79,11 +106,28 @@ booksnote = {
|
||||
'selectedtext': '這就是宣傳的恐怖之處'
|
||||
}}}
|
||||
}
|
||||
|
||||
# v1.2 CFI 排序版本
|
||||
annotations = {
|
||||
assetid: [ # 按 CFI 位置排序的列表
|
||||
{
|
||||
'uuid': 'annotation_id',
|
||||
'creationdate': '2023-07-12 14:30:00',
|
||||
'location': 'epubcfi(/6/22[id19]!/4[section]/40/1,:96,:214)',
|
||||
'chapter_info': '章节_id19',
|
||||
'note': '用户笔记内容',
|
||||
'selectedtext': '選中的文本',
|
||||
'physical_location': 1250 # 备用排序
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
- `assetid`:书籍唯一标识
|
||||
- `label_path`:章节名
|
||||
- `uuid`:笔记唯一标识
|
||||
- 其余字段为笔记内容及元数据
|
||||
|
||||
**关键改进**:
|
||||
- **CFI 位置字段**: `location` 存储完整的 EPUB CFI 字符串
|
||||
- **章节信息**: `chapter_info` 自动解析的可读章节名称
|
||||
- **排序保证**: 列表已按 CFI 位置预排序,确保阅读顺序正确
|
||||
- **兼容性**: 保持向后兼容,自动适配新数据结构
|
||||
|
||||
---
|
||||
|
||||
@@ -93,12 +137,30 @@ booksnote = {
|
||||
|
||||
- 自动将 iBooks 的数据库和 plist 文件复制到本地 `data/` 目录,便于后续处理。
|
||||
|
||||
### 5.2 构建 booksnote
|
||||
### 5.2 构建 booksnote (v1.2 CFI 排序优化)
|
||||
|
||||
- 通过 `get_annotations` 解析 SQLite 笔记数据库,获取所有笔记。
|
||||
- 通过 `AnnotationManager.get_annotations()` 解析 SQLite 笔记数据库,获取所有笔记。
|
||||
- **🆕 CFI 排序处理**:
|
||||
- 使用 `EpubCFIParser` 解析每条笔记的 `ZANNOTATIONLOCATION` 字段
|
||||
- 提取 spine 路径、local 路径和字符偏移信息
|
||||
- 按 CFI 语义顺序排序,确保笔记按真实阅读位置排列
|
||||
- 降级处理:CFI 解析失败时使用物理位置和创建时间排序
|
||||
- 通过 `parse_books_plist` 解析书籍元数据,获取书名、路径等信息。
|
||||
- 遍历每本书的所有笔记,结合OPF、NCX文件和HTML 文件,定位章节名。
|
||||
- 若无法通过目录文件定位章节,则尝试通过笔记选中文本在 HTML 文件中查找章节,否则标记为“未找到章节”。
|
||||
- 若无法通过目录文件定位章节,则尝试通过笔记选中文本在 HTML 文件中查找章节,否则标记为"未找到章节"。
|
||||
|
||||
#### CFI 排序技术流程
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[笔记数据] --> B[CFI解析]
|
||||
B --> C{解析成功?}
|
||||
C -->|是| D[CFI排序键]
|
||||
C -->|否| E[物理位置+时间]
|
||||
D --> F[按位置排序]
|
||||
E --> F
|
||||
F --> G[有序笔记列表]
|
||||
```
|
||||
|
||||
### 5.3 交互式选择书籍
|
||||
|
||||
@@ -125,19 +187,62 @@ booksnote = {
|
||||
|
||||
---
|
||||
|
||||
## 6. 关键函数说明
|
||||
## 6. 核心模块架构 (v1.2)
|
||||
|
||||
### 6.1 build_booksnote
|
||||
### 6.1 主要模块
|
||||
|
||||
- 输入:注释数据库路径、书籍 plist 路径
|
||||
- 输出:结构化的 booksnote 字典
|
||||
- 逻辑:遍历所有笔记,结合书籍元数据和目录信息,归类到章节下
|
||||
| 模块 | 功能 | v1.2 更新 |
|
||||
|------|------|----------|
|
||||
| `annotationdata.py` | 笔记数据库接口 | **重构** CFI 排序集成 |
|
||||
| `epub_cfi_parser.py` | **🆕 新增** CFI 解析引擎 | IDPF 规范完整实现 |
|
||||
| `booklist_parse.py` | 书籍元数据与统计 | 适配新数据结构 |
|
||||
| `exportbooknotes.py` | 笔记导出功能 | 支持CFI排序列表 |
|
||||
| `ibook_export_app.py` | 主GUI应用 | 界面优化,统计修复 |
|
||||
| `charts.py` | 统计图表组件 | 性能优化 |
|
||||
|
||||
### 6.2 export_booksnote_to_md
|
||||
### 6.2 关键函数说明
|
||||
|
||||
- 输入:booksnote、booksinfo、导出路径
|
||||
- 输出:Markdown 字符串,并写入文件
|
||||
- 逻辑:遍历每本书、每个章节、每条笔记,按格式输出
|
||||
#### 6.2.1 AnnotationManager.get_annotations (CFI 排序)
|
||||
|
||||
```python
|
||||
def get_annotations(self, bookid=None) -> dict:
|
||||
"""
|
||||
返回按 CFI 位置排序的笔记数据
|
||||
|
||||
Returns:
|
||||
{assetid: [annotations_list]} # v1.2 列表格式
|
||||
"""
|
||||
```
|
||||
|
||||
- **输入**:书籍ID(可选)
|
||||
- **输出**:按 CFI 排序的笔记列表字典
|
||||
- **v1.2 改进**:
|
||||
- 集成 `EpubCFIParser` 进行位置解析
|
||||
- 自动章节信息提取
|
||||
- 多级排序键:CFI → 物理位置 → 创建时间
|
||||
|
||||
#### 6.2.2 EpubCFIParser (新增模块)
|
||||
|
||||
```python
|
||||
class EpubCFIParser:
|
||||
@staticmethod
|
||||
def parse_cfi(cfi_string: str) -> tuple:
|
||||
"""解析 CFI 字符串为结构化数据"""
|
||||
|
||||
@staticmethod
|
||||
def create_sort_key(cfi_string: str) -> tuple:
|
||||
"""创建 CFI 排序键"""
|
||||
|
||||
@staticmethod
|
||||
def extract_chapter_info(cfi_string: str) -> str:
|
||||
"""提取可读的章节信息"""
|
||||
```
|
||||
|
||||
#### 6.2.3 export_booksnote_to_md (适配更新)
|
||||
|
||||
- **输入**:CFI 排序的 annotations、booksinfo、导出路径
|
||||
- **输出**:Markdown 字符串,并写入文件
|
||||
- **v1.2 改进**:适配新的列表数据结构,保持导出格式兼容
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user