#!/bin/bash # ============================================================================= # GÉNÉRATION DU SITE — orchestre la chaîne complète # # Pour chaque dossier de voyage : # 1. extraction_infos.sh → CSV des métadonnées EXIF/GPS # 2. compress.sh → encodage web des rushs # 3. genere_carte.py → cartes du voyage # Puis, UNE SEULE FOIS à la fin : # 4. genere_index_general.py → page d'accueil listant tous les voyages # # Un dossier est considéré comme un voyage s'il contient AU MOINS un des # sous-dossiers rushs/, routes/ ou photos/. Les manquants sont signalés et # l'étape correspondante est simplement sautée (un voyage sans vidéo ou sans # trace GPX reste parfaitement valable). # # Usage : # ./genere_site.sh # tous les voyages # ./genere_site.sh Ete-2026 # un seul voyage # ./genere_site.sh Ete-2026 corse # plusieurs # # Variables : celles de compress.sh (JOBS, ENCODER, CRF_HEVC…) sont # transmises telles quelles. # SKIP_COMPRESS=1 régénère les cartes sans réencoder les vidéos # ============================================================================= set -uo pipefail shopt -s nullglob SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # La racine du site est le dossier PARENT de Scripts/. On ne dépend donc pas # du répertoire courant : le script marche depuis n'importe où. ROOT="${ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}" SKIP_COMPRESS="${SKIP_COMPRESS:-0}" cd "$ROOT" || { echo "❌ Racine introuvable : $ROOT"; exit 1; } for s in extraction_infos.sh compress.sh genere_carte.py genere_index_general.py; do if [ ! -f "$SCRIPT_DIR/$s" ]; then echo "❌ Script manquant : $SCRIPT_DIR/$s" exit 1 fi [ -x "$SCRIPT_DIR/$s" ] || chmod +x "$SCRIPT_DIR/$s" 2>/dev/null done # --- Diagnostic d'un sous-dossier ------------------------------------------- # `ls -l` affiche un lien symbolique CASSÉ exactement comme un lien valide : # rien ne le distingue à l'œil. `test -d` renvoie faux dessus, d'où des # « dossier manquant » incompréhensibles. On sépare donc les deux cas. etat_dossier() { if [ -d "$1" ]; then echo ok elif [ -L "$1" ]; then echo lien_casse else echo absent fi } # Résout la cible d'un lien en chemin absolu, pour pouvoir la montrer. resoudre_lien() { python3 -c 'import os,sys p = sys.argv[1] print(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(p)), os.readlink(p))))' "$1" 2>/dev/null \ || readlink "$1" 2>/dev/null \ || echo "?" } echo "==================================================" echo " GÉNÉRATION DU SITE" echo " Racine : $ROOT" echo "==================================================" echo # --- Sélection des voyages --------------------------------------------------- candidats=() if [ "$#" -gt 0 ]; then EXPLICITE=1 for d in "$@"; do candidats+=("${d%/}"); done else EXPLICITE=0 for d in */; do candidats+=("${d%/}"); done fi voyages=(); ignores=0 for dir in "${candidats[@]+"${candidats[@]}"}"; do [ "$dir" = "Scripts" ] && continue if [ ! -d "$dir" ]; then [ "$EXPLICITE" = "1" ] && echo "❌ $dir : ce dossier n'existe pas." ignores=$((ignores + 1)); continue fi presents=0; details="" for sub in rushs routes photos; do case "$(etat_dossier "$dir/$sub")" in ok) presents=$((presents + 1)) ;; lien_casse) # Toujours signalé, même en mode automatique : un lien cassé # est une erreur à corriger, pas un dossier qu'on ignore. echo "🔗 $dir/$sub : LIEN SYMBOLIQUE CASSÉ" echo " pointe vers : $(resoudre_lien "$dir/$sub")" echo " → cette cible n'existe pas. Le lien a probablement été" echo " créé en relatif puis le dossier a été déplacé." echo " Correction (avec un chemin absolu, plus robuste) :" echo " rm '$dir/$sub' && ln -s /chemin/absolu/vers/$sub '$dir/$sub'" details="$details $sub(lien cassé)" ;; absent) details="$details $sub(absent)" ;; esac done if [ "$presents" -gt 0 ]; then voyages+=("$dir") [ -n "$details" ] && echo "⚠️ $dir : sous-dossier(s) indisponible(s) :$details — étape(s) sautée(s)" else [ "$EXPLICITE" = "1" ] && echo "❌ $dir : aucun de rushs/ routes/ photos/ n'est utilisable :$details" ignores=$((ignores + 1)) fi done if [ "${#voyages[@]}" -eq 0 ]; then echo echo "❌ Aucun voyage à traiter." echo " Un voyage doit contenir au moins un de : rushs/ routes/ photos/" exit 1 fi echo echo "📁 ${#voyages[@]} voyage(s) à traiter : ${voyages[*]}" [ "$ignores" -gt 0 ] && [ "$EXPLICITE" = "0" ] && echo " ($ignores dossier(s) ignoré(s), ce ne sont pas des voyages)" echo # --- Traitement -------------------------------------------------------------- ok=0; ko=0 T0=$(date +%s) for dir in "${voyages[@]}"; do echo "==================================================" echo "▶ $dir" echo "==================================================" if ! "$SCRIPT_DIR/extraction_infos.sh" "$dir"; then echo "❌ Extraction échouée sur $dir — voyage ignoré." ko=$((ko + 1)); echo; continue fi if [ "$SKIP_COMPRESS" = "1" ]; then echo "⏭️ Compression sautée (SKIP_COMPRESS=1)" elif [ "$(etat_dossier "$dir/rushs")" != "ok" ]; then echo "⏭️ Compression sautée : pas de dossier rushs/ utilisable." elif ! "$SCRIPT_DIR/compress.sh" "$dir"; then echo "⚠️ Compression incomplète sur $dir — on continue," echo " les cartes seront générées avec les vidéos disponibles." fi if ! "$SCRIPT_DIR/genere_carte.py" "$dir"; then echo "❌ Génération des cartes échouée sur $dir." ko=$((ko + 1)); echo; continue fi ok=$((ok + 1)) echo "✅ $dir terminé" echo done # --- Index général : UNE SEULE FOIS, après la boucle ------------------------- # (l'ancienne version l'appelait à chaque itération, y compris pour les # dossiers non conformes — soit N fois le même travail.) echo "==================================================" echo "▶ Index général" echo "==================================================" "$SCRIPT_DIR/genere_index_general.py" "$ROOT" T1=$(date +%s); EL=$((T1 - T0)) echo echo "==================================================" printf " ✅ %d voyage(s) généré(s)" "$ok" [ "$ko" -gt 0 ] && printf ", ❌ %d en échec" "$ko" printf " — %d min %02d s\n" $((EL / 60)) $((EL % 60)) echo " 🌍 Ouvre index.html à la racine du site." echo "==================================================" [ "$ko" -gt 0 ] && exit 1 exit 0