- Remove unused image dependencies from Cargo.lock. - Update API to handle thumbnail generation and checkup processes. - Introduce new routes for rebuilding and regenerating thumbnails. - Enhance job tracking with progress indicators for thumbnail jobs. - Update front-end components to display thumbnail job status and progress. - Add backend logic for managing thumbnail jobs and integrating with the API. - Refactor existing code to accommodate new thumbnail functionalities.
142 lines
4.9 KiB
Markdown
142 lines
4.9 KiB
Markdown
# Plan: Génération des vignettes à l'index
|
|
|
|
## 1. Base de données
|
|
|
|
### Migration SQL (`0010_add_thumbnails.sql`)
|
|
- [x] Ajouter `thumbnail_path TEXT` à la table `books` (nullable)
|
|
- [x] Ajouter settings pour thumbnails dans `app_settings`:
|
|
```json
|
|
{
|
|
"thumbnail": {
|
|
"enabled": true,
|
|
"width": 300,
|
|
"height": 400,
|
|
"quality": 80,
|
|
"format": "webp"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Configuration
|
|
|
|
### `crates/core/src/config.rs`
|
|
- [x] Ajouter `ThumbnailConfig` struct
|
|
- [x] Ajouter champs dans `IndexerConfig`:
|
|
- `thumbnail_width: u32` (défaut: 300)
|
|
- `thumbnail_height: u32` (défaut: 400)
|
|
- `thumbnail_quality: u8` (défaut: 80)
|
|
- `thumbnail_dir: String` (défaut: `/data/thumbnails`)
|
|
- [x] Ajouter getter depuis env vars
|
|
|
|
---
|
|
|
|
## 3. Indexer - Extraction de la 1ère page
|
|
|
|
### Fonction à créer dans `crates/parsers/src/lib.rs`
|
|
- [x] `extract_first_page(path: &Path, format: BookFormat) -> Result<Vec<u8>>`
|
|
- Réutiliser logique de `pages.rs:extract_cbz_page`
|
|
- Réutiliser logique de `pages.rs:extract_cbr_page`
|
|
- Réutiliser logique de `pages.rs:render_pdf_page`
|
|
|
|
### Fonction de génération vignette dans `apps/indexer/src/main.rs`
|
|
- [x] `generate_thumbnail(image_bytes: &[u8], config: &ThumbnailConfig) -> Result<Vec<u8>>`
|
|
- Load image avec `image::load_from_memory`
|
|
- Resize avec `image::resize` (ratio kept)
|
|
- Encode en WebP avec `webp::Encoder`
|
|
|
|
- [x] `save_thumbnail(book_id: Uuid, thumbnail_bytes: &[u8], config: &ThumbnailConfig) -> Result<String>`
|
|
|
|
### Intégration dans `scan_library`
|
|
- [x] Après parsing metadata, extraire 1ère page
|
|
- [x] Générer vignette et sauvegarder
|
|
- [x] Stocker chemin en DB (via batch insert)
|
|
|
|
---
|
|
|
|
## 4. Indexer - WalkDir parallèle
|
|
|
|
### Remplacement de `WalkDir` séquentiel
|
|
- [x] Utiliser `rayon` pour paralléliser le scan:
|
|
```rust
|
|
let total_files: usize = library_paths.par_iter()
|
|
.map(|root_path| { ... })
|
|
.sum();
|
|
```
|
|
- [x] Ajouter `rayon = "1.10"` dans workspace dependencies
|
|
|
|
---
|
|
|
|
## 5. API - Service des vignettes
|
|
|
|
### Mise à jour models dans `apps/api/src/books.rs`
|
|
- [x] Ajouter `thumbnail_url: Option<String>` à `BookItem`
|
|
- [x] Ajouter `thumbnail_url: Option<String>` à `BookDetails`
|
|
- [x] Mise à jour des requêtes SQL pour récupérer `thumbnail_path`
|
|
|
|
### Nouvelle route dans `apps/api/src/main.rs`
|
|
- [x] Route `/books/:id/thumbnail` (GET)
|
|
- Retourne fichier statique depuis `thumbnail_path`
|
|
- Content-Type: image/webp
|
|
- Cache-Control: public, max-age=31536000
|
|
|
|
### Suppression cache 1ère page (optionnel)
|
|
- [ ] Optionnel: simplifier `pages.rs` car thumbnail pré-générée
|
|
- [ ] Garder render pour pages > 1
|
|
|
|
### Adapter backoffice
|
|
|
|
La recupération des thumbnail est fait par une route page/1.
|
|
- [x] Passer par la nouvelle route avec une route clean /thumbnail pour chaque cover.
|
|
|
|
### refacto code entre api et indexer
|
|
|
|
En fait l'indexer pourrait appeler l'api pour qu'il fasse les vignettes et c'est l'api qui est responsable des images et des lectures ebooks. Je préfère que chaque domaine soit bien respecté. A la fin d'une build, on appelle l'api pour faire le checkup des thumbnails.
|
|
Il faudra que coté backoffice on voit partout ou on peut voir le traitement live des jobs, une phase ou on voit en sse le traitement des thumbnails. Coté api, si on a pas de thumbnail on passe par le code actuel de pages.
|
|
|
|
- [x] Migration `0010_index_job_thumbnails_phase.sql`: status `generating_thumbnails` dans index_jobs
|
|
- [x] API: `get_thumbnail` fallback sur page 1 si pas de thumbnail_path (via `pages::render_book_page_1`)
|
|
- [x] API: module `thumbnails.rs`, POST `/index/jobs/:id/thumbnails/checkup` (admin), lance la génération en tâche de fond et met à jour la job
|
|
- [x] Indexer: plus de génération de thumbnails; en fin de build: status = `generating_thumbnails`, puis appel API checkup; config `api_base_url` + `api_bootstrap_token` (core)
|
|
- [x] Backoffice: StatusBadge "Thumbnails" pour `generating_thumbnails`; JobProgress/JobRow/JobsIndicator/page job détail: phase thumbnails visible en SSE (X/Y thumbnails, barre de progression)
|
|
|
|
---
|
|
|
|
## 6. Settings API
|
|
|
|
### Endpoint settings existant
|
|
- [ ] Vérifier que `/settings` expose thumbnail config
|
|
- [ ] Ajouter endpoint PUT pour mettre à jour thumbnail settings
|
|
|
|
---
|
|
|
|
## 7. Taches diverses
|
|
|
|
- [x] Ajouter dependency `image` et `webp` dans indexer `Cargo.toml`
|
|
- [x] Build release vérifié
|
|
|
|
---
|
|
|
|
## Ordre d'implémentation suggéré
|
|
|
|
1. [x] Migration DB + settings
|
|
2. [x] Config + parsers (extract first page)
|
|
3. [x] Indexer thumbnail generation + save to disk
|
|
4. [x] API serve thumbnail
|
|
5. [x] Parallel walkdir
|
|
6. [ ] Tests & polish (à faire)
|
|
|
|
---
|
|
|
|
## Post-déploiement
|
|
|
|
- [ ] Appliquer migration SQL: `psql -f infra/migrations/0009_add_thumbnails.sql`
|
|
- [ ] Créer dossier thumbnails: `mkdir -p /data/thumbnails`
|
|
- [ ] Configurer env vars si besoin:
|
|
- `THUMBNAIL_ENABLED=true`
|
|
- `THUMBNAIL_WIDTH=300`
|
|
- `THUMBNAIL_HEIGHT=400`
|
|
- `THUMBNAIL_QUALITY=80`
|
|
- `THUMBNAIL_DIRECTORY=/data/thumbnails`
|