# 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 сканов.