4.0 KiB
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 символов. Хранение — SQLitedata/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
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 сканов.