128 lines
5.3 KiB
Markdown
128 lines
5.3 KiB
Markdown
# Jardin App — Améliorations récentes
|
|
|
|
> Date : **2026-03-22**
|
|
|
|
---
|
|
|
|
## 1. Conversion HEIC → PNG automatique à l'upload
|
|
|
|
**Problème :** Les photos prises avec un iPhone sont au format HEIC, non reconnu par les navigateurs web.
|
|
|
|
**Solution :** Lors de tout upload de média (route `POST /api/media/upload`), le backend détecte automatiquement le format HEIC/HEIF et le convertit en WEBP avant stockage.
|
|
|
|
**Fichiers modifiés :**
|
|
- `backend/app/routers/media.py` — détection par magic bytes + conversion via `pillow-heif`
|
|
- `backend/requirements.txt` — ajout de `pillow-heif`
|
|
- `frontend/src/views/*` — inputs file acceptent désormais `.heic,.HEIC`
|
|
|
|
**Comportement :**
|
|
- Fichier `.heic` reçu → converti en WEBP (même qualité que les autres imports)
|
|
- Miniature 300 px générée normalement
|
|
- Nom de fichier stocké en `.webp` dans la base de données
|
|
|
|
---
|
|
|
|
## 2. Redimensionnement des images de la bibliothèque
|
|
|
|
**Contexte :** Le paramètre "Largeur max des photos" dans Réglages s'appliquait uniquement aux nouvelles photos. Les photos déjà importées restaient à leur taille d'origine.
|
|
|
|
**Ajout :** Un bouton **"Appliquer à la bibliothèque"** dans la section Images des Réglages permet de redimensionner rétroactivement toutes les photos existantes.
|
|
|
|
**Règle appliquée :** Si la largeur d'une photo est **inférieure ou égale** au paramètre configuré, elle n'est **pas modifiée** (pas d'agrandissement).
|
|
|
|
**Fichiers modifiés :**
|
|
- `backend/app/routers/settings.py` — endpoint `POST /api/settings/images/resize-all`
|
|
- `frontend/src/api/settings.ts` — méthode `resizeAllImages()`
|
|
- `frontend/src/views/ReglagesView.vue` — bouton + feedback avec stats (redimensionnées / ignorées / erreurs)
|
|
|
|
**Endpoint retourne :**
|
|
```json
|
|
{ "ok": true, "redimensionnees": 42, "ignorees": 128, "erreurs": 0 }
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Sauvegarde Samba (backup réseau)
|
|
|
|
**Contexte :** La sauvegarde ZIP existante ne proposait qu'un téléchargement local.
|
|
|
|
**Ajout :** Section **"Sauvegarde Samba"** dans les Réglages permettant d'envoyer automatiquement la sauvegarde vers un partage réseau Windows/NAS.
|
|
|
|
**Paramètres configurables :**
|
|
| Champ | Exemple |
|
|
|-------|---------|
|
|
| Adresse IP / nom du serveur | `192.168.1.10` ou `nas.local` |
|
|
| Partage | `Sauvegardes` |
|
|
| Sous-dossier | `jardin/backups` |
|
|
| Utilisateur | `gilles` |
|
|
| Mot de passe | *(masqué)* |
|
|
|
|
**Fichiers modifiés :**
|
|
- `backend/app/routers/settings.py` — endpoint `POST /api/settings/backup/samba` (génère le ZIP, copie via `smbclient` ou `pysmb`)
|
|
- `backend/app/models/user_settings.py` — clés `samba_*` persistées en base
|
|
- `frontend/src/api/settings.ts` — méthodes `getSambaSettings()`, `saveSambaSettings()`, `backupToSamba()`
|
|
- `frontend/src/views/ReglagesView.vue` — formulaire Samba + bouton "Envoyer la sauvegarde" + feedback
|
|
|
|
---
|
|
|
|
## 4. Restauration de sauvegarde
|
|
|
|
**Contexte :** Il était possible de créer un backup ZIP mais pas de le restaurer depuis l'interface.
|
|
|
|
**Ajout :** Bouton **"Restaurer une sauvegarde"** dans la section Sauvegarde des Réglages.
|
|
|
|
**Deux modes de restauration :**
|
|
|
|
| Mode | Comportement |
|
|
|------|-------------|
|
|
| **Écraser tout** (toggle activé, rouge) | Remplace la BDD entière + écrase tous les fichiers uploads |
|
|
| **Ajouter uniquement** (toggle désactivé, jaune) | Insère les lignes absentes (`INSERT OR IGNORE`) + copie uniquement les fichiers manquants |
|
|
|
|
**Sécurité :**
|
|
- Confirmation obligatoire avec `window.confirm()` décrivant le mode sélectionné
|
|
- Message d'avertissement "irréversible" affiché avant action
|
|
|
|
**Technique (mode écraser) :**
|
|
1. `engine.dispose()` — libère les connexions SQLAlchemy
|
|
2. `PRAGMA wal_checkpoint(TRUNCATE)` — vide le WAL SQLite
|
|
3. Copie directe du fichier `.db` depuis le ZIP
|
|
|
|
**Technique (mode ajouter) :**
|
|
- `sqlite3` natif — `INSERT OR IGNORE` table par table depuis la BDD du ZIP
|
|
- `foreign_keys=OFF` pendant la fusion pour éviter les conflits de contraintes
|
|
|
|
**Fichiers modifiés :**
|
|
- `backend/app/routers/settings.py` — helper `_merge_db_add_only()` + endpoint `POST /api/settings/backup/restore`
|
|
- `frontend/src/api/settings.ts` — méthode `restoreBackup(file, overwrite)`
|
|
- `frontend/src/views/ReglagesView.vue` — sélecteur ZIP + toggle mode + bouton ♻️ + feedback coloré
|
|
|
|
**Endpoint retourne :**
|
|
```json
|
|
{
|
|
"ok": true,
|
|
"uploads_copies": 27,
|
|
"uploads_ignores": 0,
|
|
"db_restauree": true,
|
|
"db_lignes_ajoutees": 0,
|
|
"erreurs": 0
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Résumé des endpoints ajoutés
|
|
|
|
| Méthode | Route | Description |
|
|
|---------|-------|-------------|
|
|
| `POST` | `/api/settings/images/resize-all` | Redimensionne toutes les images de la bibliothèque |
|
|
| `POST` | `/api/settings/backup/samba` | Envoie la sauvegarde ZIP vers un partage Samba |
|
|
| `POST` | `/api/settings/backup/restore` | Restaure un backup ZIP (écraser ou ajouter) |
|
|
|
|
---
|
|
|
|
## Dette technique restante
|
|
|
|
- Le redimensionnement "bibliothèque" tourne de façon synchrone — pour de très grandes bibliothèques (> 500 photos), envisager une tâche en arrière-plan avec progression SSE.
|
|
- La connexion Samba utilise `subprocess` + `smbclient` ou `pysmb` : tester la compatibilité avec les NAS Synology / QNAP.
|
|
- Après une restauration "écraser", les sessions utilisateurs actives travaillent toujours sur l'ancienne BDD jusqu'au prochain cycle de connexion SQLAlchemy. Un rechargement de page suffit.
|