books: код переехал в отдельный репо ruzzy/books

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gilfanovr
2026-10-13 10:45:05 +03:00
co-authored by Claude Opus 5.5
parent 9aab5b3f40
commit 0f2a403b99
19 changed files with 6 additions and 1448 deletions
+4 -45
View File
@@ -1,46 +1,5 @@
# books.ruzzy.dev — читалка с ИИ
# books.ruzzy.dev
Личная веб-читалка владельца (только его Telegram ID): загрузка PDF/EPUB → главы по оглавлению →
чтение в браузере (iPhone, Boox, Mac) → выделил текст → **перевести / объяснить / спросить**; **рекапы глав**
(ИИ пишет, владелец правит), **вопросы по книге и по всей библиотеке** с цитатами [гл. N, с. P] и проверкой фактов
по интернету; поиск по книгам и рекапам (RAG).
## Как устроено
- `app/library.py` — разбор: PDF — PyMuPDF (оглавление; если его нет — заголовки «Глава N/Chapter N» в начале
страниц, колонтитулы отсекаются; иначе — по 20 страниц), EPUB — свой разбор (nav/NCX + spine; у PyMuPDF нет
оглавления EPUB 3), «страница» EPUB ≈ 2000 символов. Хранение — SQLite `data/books.db`. Поиск — гибрид:
FTS5 (BM25) + эмбеддинги `paraphrase-multilingual-MiniLM-L12-v2` (fastembed/ONNX, на CPU fr1, модель в `data/models`),
слияние по рангам (RRF). Рекапы тоже попадают в индекс.
- `app/llm.py` — ИИ: **Claude Code в фоновом режиме** (`claude -p --output-format stream-json`) по подписке владельца
(`CLAUDE_CODE_OAUTH_TOKEN` из `claude setup-token`), **без инструментов** (`--tools ""`) — текст книги и выделения
чужие, в них может быть внедрённая инструкция. Для «проверить по интернету» — только `WebSearch`. Модели:
`MODEL_MAIN=sonnet` (рекапы, вопросы), `MODEL_FAST=haiku` (перевод, объяснение). До 3 запросов параллельно.
⚠️ `--bare` нельзя: в нём Claude Code принимает только API-ключ, не OAuth подписки.
- `app/main.py` — FastAPI: вход **Telegram Login Widget** (проверка HMAC подписи ключом sha256(токен бота),
`auth_date` ≤ сутки, ID из `ALLOWED_TG_IDS`), сессия — подписанная cookie на 30 дней. Ответы ИИ — потоком.
`noindex` везде, `robots.txt` — Disallow.
- Интерфейс — серверные шаблоны + `static/app.js` без сборки; вёрстка под e-ink (чёрное на белом, без анимаций).
Markdown ответов рендерится после экранирования — HTML из ответа ИИ не исполняется.
## Установка на fr1
```bash
rsync -a --exclude data --exclude .env stacks/books/ rus-161:books/
ssh rus-161 'cd ~/books && docker compose up -d --build'
sudo sh ~/books/nginx/install.sh # vhost + certbot (на fr1, один раз)
```
`.env` (только на сервере, 600): `TG_BOT_NAME`, `TG_BOT_TOKEN` (бот для входа; у @BotFather `/setdomain` →
books.ruzzy.dev), `ALLOWED_TG_IDS=607015`, `SESSION_SECRET` (случайный, сменить = разлогинить всех),
`CLAUDE_CODE_OAUTH_TOKEN`, `MODEL_MAIN`, `MODEL_FAST`. После правки — `docker compose up -d`.
## Данные
`~/books/data/`: `books.db` (книги, главы, текст, рекапы, вопросы, индекс), `files/` (оригиналы), `models/`
(эмбеддинги, ~0,5 ГБ, скачиваются при первом запуске), `claude/` (конфиг Claude Code, `CLAUDE_CONFIG_DIR`).
## Потом
- Интеграция с малиной: рекапы → vault `Книги/<книга>.md`, вопросы из Telegram через Astra (отдельный этап).
- Импорт библиотеки из OneDrive (229 PDF в `Ruslan/Книги`), OCR сканов.
Код и стек переехали в отдельный репо **`ruzzy/books`** (gitea, приватный; локально — `~/pets/books`) 2026-10-13.
Здесь не дублируем: два источника кода уже однажды разъехались (см. astra-bot).
Состояние на сервере — `servers/fr1.md`, раздел «books.ruzzy.dev».