--- title: Library App aliases: - Библиотека - Library App - Веб-библиотека - library-app tags: - personal - projects - infra - books - library related: - "[[personal/books-wishlist]]" - "[[personal/documents/books-reading-list]]" - "[[family/documents/google-books-api-key]]" updated: 2026-05-17 --- # Library App Персональный веб-сайт для библиотеки книг на TrueNAS. ## Назначение Замена inpxer — полноценный сайт для просмотра коллекции Flibusta (687k книг) + личных книг, с отметками статуса чтения, связями между книгами и графом. ## Деплой - **Контейнер:** `library-app` на TrueNAS (mallexxx.duckdns.org) - **Домен:** `library.mallexxx.duckdns.org` - **Расположение:** `/mnt/RED_2TB/docker/library/` - **Сеть:** `caddy_default` ## Данные ### Монтирования | Хост | Контейнер | Режим | |------|-----------|-------| | `/mnt/RED_2TB/storage/Downloads/fb2.Flibusta.Net` | `/library` | ro | | `/mnt/RED_2TB/storage/books` | `/books` | ro | | `/mnt/RED_2TB/docker/library/data` | `/data` | rw | ### SQLite файлы в `/data/` **`books.db`** — пересоздаётся при каждом старте контейнера из INPX (≈10 сек): ```sql books(id, author, genre, title, series, format, date, lang, zip_file) ``` **`library.db`** — персистентный, никогда не удалять: ```sql read_log(book_id, status, date_updated, rating, notes, created_at) -- status: 'read' | 'reading' | 'want' relations(book_id, related_id, type, weight, fetched_at) -- type: 'same_author' | 'same_series' | 'same_genre' | 'openlibrary' ``` ## Статусы книг | Статус | Значение | |--------|----------| | `read` | Прочитано | | `reading` | Читаю сейчас | | `want` | Буду читать | ## Источники связей между книгами Связи строятся при **первом открытии** любой книги, кэшируются в `relations`: 1. **`same_author`** — все книги того же автора (из books.db, мгновенно) 2. **`same_series`** — книги той же серии (из books.db, мгновенно) 3. **`same_genre`** — топ-20 книг жанра по дате (из books.db, мгновенно) 4. **`openlibrary`** — "readers also read" через OpenLibrary API (async, ~300ms) Повторное открытие: кэш используется. Фоновое обновление — раз в 30 дней (поле `fetched_at`). ## Стек - **Backend:** Python + FastAPI (JSON API) - **Frontend:** Vue 3 (CDN, no build) + Tailwind CSS (CDN) — mobile-first SPA - **Граф:** vis.js (CDN) - **Контейнер:** python:3.12-slim, uvicorn ## Страницы | URL | Описание | |-----|----------| | `/` | Главная — поиск, жанры (без взрослых), новинки | | `/book/{id}` | Страница книги — статус, связи, скачать | | `/my` | Мои книги — read/reading/want с фильтрами | | `/graph` | Граф прочитанных книг и связей | | `/adult` | Взрослые жанры — отдельная страница, нет ссылки с главной | ## Взрослый контент Жанры-теги в `/data/adult_genres.txt` — один жанр на строку. По умолчанию: ``` love_erotica erotik sex_sf adv_sex prose_sex ``` Эти жанры исключены из главной страницы и поиска по умолчанию. Доступны только через `/adult`. ## Ссылки на скачивание - **Flibusta (inpxer):** `https://books.mallexxx.duckdns.org/download/{id}` - **Личные книги:** `https://docs.mallexxx.duckdns.org/books/{path}` (FileBrowser) ## Entrypoint ```bash # 1. Rebuild books.db из INPX (~10 сек) python inpx2db.py /library/flibusta_fb2_local.inpx /data/books.db # 2. Init library.db (если не существует) python init_db.py /data/library.db # 3. Запуск сервера uvicorn main:app --host 0.0.0.0 --port 8080 ``` ## Статус ✅ **Задеплоен** — `https://library.mallexxx.duckdns.org` - books.db: 687,722 книг, 227 MB, rebuild ~23 сек при старте - library.db: персистентный, в `/mnt/RED_2TB/docker/library/data/` - config: `/mnt/RED_2TB/docker/library/data/config.toml` ## История - **2026-05-16** — задеплоен. INPX parse+SQLite build = 23s (в контейнере), DB = 227MB. ## Связанные заметки - [[personal/books-wishlist]] — книги для чтения - [[personal/documents/books-reading-list]] — личный список чтения - [[family/documents/google-books-api-key]] — API ключ Google Books