这是一个为个人电子书库设计的“章节原文 PDF 信息流”应用(单用户、本地优先)。
- PDF 目录驱动切分:按目录小节生成章节 PDF(不从小节中间切断)。
- 手工目录标注台:批量粘贴目录 -> 预览定位 -> 保存并立即物化。
- 目录审核门禁:所有书默认“待审核”,审核通过后才进入 Feed。
- 首页双列 Feed:上封面下标题,点击进入章节阅读。
- Reader:章节原文 PDF 阅读 + 上一节/下一节 + 完成/看不懂/点赞/评论。
- 书籍拼图页:已读点亮、未读灰态,展示完成率。
- 互动上报:
impression/enter_context/backtrack/section_complete/confusion/like/comment。 - 回忆帖框架:
with_memory=1时可混入 memory_post(若数据库中有数据)。
- OCR 自动目录识别。
- AI 重写/压缩。
- 复杂语义推荐(向量召回/重排)。
python3 server/app.py --host 127.0.0.1 --port 8000./scripts/deploy_device_oneplus6t.sh可选:安装 systemd 常驻服务
./scripts/deploy_device_oneplus6t.sh --install-systemd后端默认启用“启动自举”:
- 服务启动后后台自动扫描
data/books/inbox并导入新增书目(不依赖前端触发)。 - 自动预热 Feed 查询与部分封面缓存,前端打开即可用。
- 周期巡检目录,发现新增文件会自动导入。
可选环境变量(按需覆盖):
BOOKFLOW_STARTUP_BOOTSTRAP_ENABLED=1|0BOOKFLOW_STARTUP_BOOTSTRAP_INPUT_DIR=data/books/inboxBOOKFLOW_STARTUP_BOOTSTRAP_INTERVAL_SEC=300BOOKFLOW_STARTUP_BOOTSTRAP_SKIP_EXISTING=1BOOKFLOW_STARTUP_BOOTSTRAP_WARM_COVER_LIMIT=24BOOKFLOW_STARTUP_BOOTSTRAP_AUTO_APPROVE_IMPORTED=0(设为1可导入后自动审核通过)
打开:
http://127.0.0.1:8000/app(Feed)http://127.0.0.1:8000/app/toc(目录标注台)
首页已提供“导入图书”路径输入与一键导入按钮(调用 /v1/books/import)。
将 PDF 放到 data/books/inbox(或你自己的目录),执行:
python3 scripts/import_library.py \
--input-dir data/books/inbox \
--recursive \
--database-url "$DATABASE_URL" \
--book-type-strategy auto \
--pdf-section-storage on_demand导入默认会跳过“已审核通过”的同源书(按 source_path 匹配),避免重复打回审核。
如需强制重扫,可加:--rescan-approved。
--pdf-section-storage 两种模式:
precut:预切章节 PDF 到data/books/derived(更快,占空间)。on_demand:不落章节 PDF,每次阅读从原始 PDF 按页码实时生成(省空间)。
导入时目录处理策略:
- 若 PDF 含可解析目录(Outline/Bookmarks),会自动标准化并保存目录文件。
- 若无可用目录,才进入待处理队列(
/app/toc人工标注)。 - 目录记录会绑定书籍
SHA-256校验码与源路径,降低book_id变化导致的丢失风险。
- 默认 token:
local-dev-token - API 请求头:
Authorization: Bearer <token>
GET /health(包含startup_bootstrap状态)GET /v1/feedGET /v1/booksPOST /v1/books/import_start(异步导入,返回job_id)GET /v1/books/import_job?job_id=<id>(查询导入进度与结果)GET /v1/chunk_detailGET /v1/chunk_contextGET /v1/chunk_pdf?book_id=<uuid>&chunk_id=<uuid>GET /v1/book_mosaic?book_id=<uuid>&user_id=<uuid>POST /v1/interactionsGET /v1/user/export?user_id=<uuid>&export_dir=<path>GET /v1/toc/pendingPOST /v1/toc/previewPOST /v1/toc/savePOST /v1/toc/review(审核状态:pending_review|approved|rejected)POST /v1/toc/write_back(把当前目录写回原 PDF Outline,并更新校验码)POST /v1/toc/llm_extract(目录截图 + 提示词 -> 大模型识别目录文本)POST /v1/toc/llm_extract_pages(按目录页段批量调用 LLM 识别)POST /v1/toc/llm_extract_pages_start(启动异步批量 LLM 任务,返回job_id)GET /v1/toc/llm_extract_pages_job?job_id=<id>(查询批量 LLM 进度/失败页/结果)GET /v1/toc/llm_config(读取已保存 LLM 配置)POST /v1/toc/llm_config(保存 LLM 配置)POST /v1/toc/llm_validate(检测 LLM 配置有效性:鉴权/模型/图像探测)
GET /v1/feed 返回 feed_source:postgres 或 memory_fallback。
当启动导入导致数据库暂时繁忙时,会自动回退 memory_fallback 保证前端可用。
/v1/toc/llm_extract 支持 OpenAI 兼容接口,参数可在请求体传入:
llm.base_url、llm.model、llm.api_key、prompt。
也支持环境变量默认值:BOOKFLOW_LLM_TOC_BASE_URL、BOOKFLOW_LLM_TOC_MODEL、BOOKFLOW_LLM_TOC_API_KEY。
LLM 识别结果会落盘到:data/toc/llm_runs/*.json(接口返回 saved_result_file)。
批量 LLM 支持重试参数:max_retries_per_page、retry_backoff_ms,并支持指定 pages 仅重试失败页。
data/books/derived/<book_id>/<chunk_id>.pdf
- 封面缓存(独立于用户数据):
data/cache/covers - PDF 页面缓存(目录标注台预览):
data/cache/pages - 用户导出(自动/手动):
data/users/export - 标准化目录文件:
data/toc/normalized/<book_fingerprint>.json - LLM 配置:
data/toc/llm_config.json - LLM 识别结果归档:
data/toc/llm_runs/*.json
可预热封面缓存:
python3 scripts/warm_cover_cache.py --database-url "$DATABASE_URL"./scripts/smoke_first_product.sh --base-url http://127.0.0.1:8000 --token local-dev-token