---
tags: note
type: "note"
nature: info             # Options : portrait, lieu, info, concept, script, process, tuto, none
ressource: false
univers: PRO
projects:
  - "PROJET"
date: "2026-08-29"
priority: 10
---
# Automatisation de la compression des images dans SilverBullet

Approche: compresser régulièrement les images en `WEBP`, renommer les liens, puis supprimer les images originales au format `JPG` ou `JPEG`.

### Installation de CaesiumCLT sur le serveur VPS

Méthode d’installation la dernière version précompilée sans compilation.

1. **Téléchargez la dernière version** (actuellement la v1.4.0) :
            
```sh
curl -LO https://github.com/Lymphatus/caesium-clt/releases/download/v1.4.0/caesiumclt-v1.4.0-x86_64-unknown-linux-musl.tar.gz
```
        
2. **Extraire l'archive :**
    
```sh
tar -xvf caesiumclt-v1.4.0-*.tar.gz
```
    
3. **Installer l'exécutable dans le PATH système (`/usr/local/bin`) :**
  
```sh
sudo mv caesiumclt /usr/local/bin/
sudo chmod +x /usr/local/bin/caesiumclt
```

Si nécessaire, se déplacer dans le dossier de Caesium créer lors de la décompression de l’archive.

4. **Nettoyer les fichiers temporaires :**

```sh
rm -rf caesiumclt-v1.4.0-*
```
    
5. **Vérifier l'installation :**
  
```sh
caesiumclt --version
```


### Mise en place du script de compression

Le choix a été fait de retenir une solution atomique pour éviter les erreurs, en partant du principe qu'une image peut être référencée à plusieurs endroits dans un ou plusieurs fichiers markdown.
Ainsi, le script:

1. Recherche les fichiers `jpg` et `jpeg`
2. Pour chaque fichier:
  * Génère l’image `wepb`
  * Renomme les liens
  * Supprime le fichier `jpg` ou `jpeg` source

Cela offre :

1. **Une sécurité maximale contre la perte de données** : si la conversion du fichier `photo.jpg` échoue (fichier corrompu, espace disque insuffisant), le script passe au fichier suivant sans modifier aucun lien Markdown ni supprimer l'original.
2. **Une prise en charge du multi-référencement** : l'étape *2.2* cherche la chaîne `photo.jpg` dans **l'ensemble des fichiers `.md`**, peu importe le nombre de fois où cette image est citée.
3. **Une reprise sur erreur transparente** : si le serveur s'arrête brutalement en plein milieu de la nuit, les images déjà traitées sont propres et finalisées. Au prochain lancement, le script reprendra simplement là où il s'est arrêté sans retoucher ce qui a déjà été converti.

Enregistrer le code suivant dans un fichier `optimize-pkm-images.sh`.

```sh
#!/usr/bin/env bash
# optimize-pkm-images.sh - Traitement atomique image par image pour SilverBullet

VAULT_DIR="${1:-/home/yunohost.app/silverbullet/notes/shizendo}"
CAESIUM_BIN="caesiumclt" # Renseignez le chemin absolu si nécessaire

echo "Démarrage du traitement atomique du Vault : $VAULT_DIR"

# 1. Recherche récursive de toutes les images JPG/JPEG
find "$VAULT_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) | while read -r img; do
    dir=$(dirname "$img")
    base_name=$(basename "$img")
    
    # Déduire le nom du fichier .webp dans le même dossier
    webp_name="${base_name%.*}.webp"
    webp_path="$dir/$webp_name"

    echo "--------------------------------------------------"
    echo "Traitement de : $base_name"

    # Step 2.1 : Génération du WebP
    "$CAESIUM_BIN" --verbose 3 \
                   --keep-dates \
                   --exif \
                   --quality 80 \
                   --format webp \
                   --long-edge 1200 \
                   -o "$dir" \
                   "$img"

    # Vérification : On ne continue QUE si le WebP a bien été créé
    if [ -f "$webp_path" ]; then
        echo "  [OK] WebP créé : $webp_name"

        # Step 2.2 : Remplacement des liens dans TOUS les fichiers Markdown (.md)
        find "$VAULT_DIR" -type f -name "*.md" | while read -r md_file; do
            # Remplacement exact du nom du fichier image (insensible à la casse)
            sed -i "s/${base_name}/${webp_name}/gI" "$md_file"
        done
        echo "  [OK] Liens Markdown mis à jour"

        # Step 2.3 : Suppression de l'image originale
        rm -f "$img"
        echo "  [OK] Image originale supprimée : $base_name"
    else
        echo "  [ERREUR] La conversion a échoué. L'image originale et les liens sont conservés."
    fi
done

echo "--------------------------------------------------"
echo "Optimisation terminée avec succès !"
```

Attribuer le script à l’utilisateur/groupe `silverbullet:silverbullet` et le rendre exécutable.

```sh
chown silverbullet:silverbullet optimize-pkm-images.sh
chmod +x optimize-pkm-images.sh
```


**Version 2 avec rapport final**

```sh
#!/usr/bin/env bash
# optimize-pkm-images_v2.sh - Traitement atomique avec rapport final pour SilverBullet

# Exporter le PATH complet pour Cron
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:$PATH"

VAULT_DIR="${1:-/home/yunohost.app/silverbullet/notes/shizendo}"
#CAESIUM_BIN="caesiumclt"
# Indiquez le chemin absolu de caesiumclt (ex: /usr/local/bin/caesiumclt)
CAESIUM_BIN="$(which caesiumclt 2>/dev/null || echo '/usr/local/bin/caesiumclt')"

VAULT_DIR="${1:-/home/yunohost.app/silverbullet/notes/shizendo}"
CAESIUM_BIN="caesiumclt"

# --- Variables pour les statistiques ---
total_images=0
converted_images=0
total_links_updated=0
initial_size_bytes=0
final_size_bytes=0

echo "=================================================="
echo "Démarrage de l'optimisation : $VAULT_DIR"
echo "=================================================="

# 1. Recherche récursive de toutes les images JPG/JPEG
find "$VAULT_DIR" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) | while read -r img; do
    dir=$(dirname "$img")
    base_name=$(basename "$img")
    webp_name="${base_name%.*}.webp"
    webp_path="$dir/$webp_name"

    # Mesurer la taille initiale du fichier en octets
    img_size=$(stat -c%s "$img")

    echo "Traitement de : $base_name"

    # 2.1 : Conversion en WebP
    "$CAESIUM_BIN" --verbose 3 \
                   --keep-dates \
                   --exif \
                   --quality 80 \
                   --format webp \
                   --long-edge 1200 \
                   -o "$dir" \
                   "$img" > /dev/null 2>&1
                   # "$img" >> /home/yunohost.app/silverbullet/optimize-pkm-images_v2.log 2>&1


    # Vérification et traitement
    if [ -f "$webp_path" ]; then
        # Mesurer la taille finale du WebP
        webp_size=$(stat -c%s "$webp_path")

        # 2.2 : Remplacement des liens dans TOUS les fichiers Markdown (.md)
        links_in_img=0
        find "$VAULT_DIR" -type f -name "*.md" | while read -r md_file; do
            # Compter les occurrences dans ce fichier
            count=$(grep -i -c "$base_name" "$md_file" 2>/dev/null || true)
            if [ "$count" -gt 0 ]; then
                sed -i "s/${base_name}/${webp_name}/gI" "$md_file"
                echo "$count" >> /tmp/links_count_tmp
            fi
        done

        # 2.3 : Suppression de l'original
        rm -f "$img"
        echo "  [OK] Converti et nettoyé."

        # Enregistrer les données pour le rapport final (via fichier temporaire pour la boucle subshell)
        echo "$img_size $webp_size" >> /tmp/sizes_tmp
    else
        echo "  [ERREUR] Échec de conversion pour $base_name"
    fi
done

# --- CALCUL DU RAPPORT FINAL ---

# Nettoyage et lecture des données temporaires accumulées
if [ -f /tmp/sizes_tmp ]; then
    while read -r orig webp; do
        ((total_images++))
        ((initial_size_bytes += orig))
        ((final_size_bytes += webp))
    done < /tmp/sizes_tmp
    rm -f /tmp/sizes_tmp
fi

if [ -f /tmp/links_count_tmp ]; then
    while read -r count; do
        ((total_links_updated += count))
    done < /tmp/links_count_tmp
    rm -f /tmp/links_count_tmp
fi

# Convertir les octets en Mégaoctets (Mo) avec prévision lisible
conv_mo() {
    awk -v bytes="$1" 'BEGIN { printf "%.2f Mo", bytes / 1048576 }'
}

# Calcul du pourcentage de gain
if [ "$initial_size_bytes" -gt 0 ]; then
    saved_bytes=$((initial_size_bytes - final_size_bytes))
    gain_percent=$(awk -v init="$initial_size_bytes" -v saved="$saved_bytes" 'BEGIN { printf "%.1f", (saved / init) * 100 }')
    initial_mo=$(conv_mo $initial_size_bytes)
    final_mo=$(conv_mo $final_size_bytes)
    saved_mo=$(conv_mo $saved_bytes)
else
    initial_mo="0 Mo"
    final_mo="0 Mo"
    saved_mo="0 Mo"
    gain_percent="0"
fi

# Affichage du rapport
echo ""
echo "=================================================="
echo "                RAPPORT D'OPTIMISATION            "
echo "=================================================="
echo " Images converties     : $total_images"
echo " Liens .md mis à jour  : $total_links_updated"
echo " Taille initiale       : $initial_mo"
echo " Taille finale         : $final_mo"
echo " Espace gagné          : $saved_mo (-$gain_percent %)"
echo "=================================================="
```

Attribuer le script à l’utilisateur/groupe `silverbullet:silverbullet` et le rendre exécutable.

```sh
chown silverbullet:silverbullet optimize-pkm-images_v2.sh
chmod +x optimize-pkm-images_v2.sh
```


### Utilisation du script

En tant que `root` exécuter :

```sh
# En précisant le chemin du dossier à traiter
sudo -u silverbullet ./optimize-pkm-images.sh /home/me/mon/dossier/a/traiter

# Sans préciser le chemin (c'est la valeur par défaut de la variable `VAULT_DIR` - "/home/yunohost.app/silverbullet/notes/shizendo" - qui est utilisée)
sudo -u silverbullet ./optimize-pkm-images_v2.sh
```


### Automatisation via le CRON de l’utilisateur `silverbullet`

Il ne faut pas que le script soit exécuté par `root` mais directement par l'utilisateur `silverbullet`.

1. **Ouvrez la table `cron` de l’utilisateur `silverbullet` :**

```sh
sudo crontab -u silverbullet -e
```
    
2. **Ajoutez la ligne de planification (ex. tous les jours à 2h00 du matin) :**

```sh
0 2 * * * /home/yunohost.app/silverbullet/optimize-pkm-images_v2.sh >> /home/yunohost.app/silverbullet/optimize-pkm-images_v2.log 2>&1
```

