Affected files: family/documents/books-wishlist.md family/documents/car-notes.md family/documents/flea-market-shopping.md family/documents/gift-ideas.md family/documents/google-books-api-key.md family/documents/home-wishlist.md family/documents/loyalty-cards.md family/documents/recipes-wishlist.md family/documents/shopping-lists.md family/documents/shopping-order.md family/index.md personal/books-wishlist.md personal/documents/todo-list.md personal/index.md personal/projects/library-app.md personal/projects/personal-os/enrichment-runs/last.md personal/shopping-order.md
145 lines
5.0 KiB
Markdown
145 lines
5.0 KiB
Markdown
---
|
||
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
|