Refonte : templates, balades, photos web, aperçus, carte globale
- Mise en page sortie du Python : Scripts/templates/ (Jinja2 + CSS/JS communs copiés dans assets/ de chaque voyage) - Voyages rangés dans un sous-dossier (Balades/…) : rubriques sur l'accueil, 2 plus récents par rubrique, pages voyages.html et balades.html - prepare_web.py : photos allégées (photos_web/) et images d'aperçu des vidéos (apercus/) - Voyage d'une seule journée : la page du voyage est la carte du jour - Carte globale de l'accueil (OpenStreetMap) : voyages du site + cartes Google My Maps récupérées (mymaps.txt, _mymaps/), moto par voyage (moto.txt) - KML par voyage pour My Maps - compress.sh : réencode une sortie illisible (encodage interrompu) ; repli automatique sur l'autre qualité dans la page - Corrections : CSV vide (voyage sans photo), racine de genere_site.sh, fichiers ._ de macOS - README réécrit, commentaires allégés Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mf2kATMtqVABHSYdxJMnim
This commit is contained in:
1 parent
5a04f159ca
commit
97b936fd3e
17 files changed
+2042
-829
No files matched your search
+85
-79
@@ -1,41 +1,41 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# GÉNÉRATION DU SITE — orchestre la chaîne complète
|
||||
# GÉNÉRATION DU SITE — enchaîne toutes les étapes
|
||||
#
|
||||
# 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
|
||||
# Pour chaque voyage :
|
||||
# 1. extraction_infos.sh → CSV des positions GPS des photos et vidéos
|
||||
# 2. compress.sh → vidéos web (1080p HEVC + 720p H.264)
|
||||
# 3. prepare_web.py → photos allégées et images d'aperçu des vidéos
|
||||
# 4. genere_carte.py → pages et cartes du voyage
|
||||
# Puis une fois : genere_index_general.py → page d'accueil du site.
|
||||
#
|
||||
# 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).
|
||||
# Un voyage est un dossier qui contient au moins un de rushs/, routes/,
|
||||
# photos/. Il peut être rangé un niveau plus bas, dans un dossier de
|
||||
# regroupement (Balades/Aisne-06-2026). Une étape sans matière est sautée.
|
||||
#
|
||||
# Usage :
|
||||
# ./genere_site.sh # tous les voyages
|
||||
# ./genere_site.sh Ete-2026 # un seul voyage
|
||||
# ./genere_site.sh Ete-2026 corse # plusieurs
|
||||
# À lancer depuis la racine du site (le dossier qui contient les voyages) :
|
||||
# ../RoadTripsGenerator/Scripts/genere_site.sh # tous
|
||||
# ../RoadTripsGenerator/Scripts/genere_site.sh Ete-2026 # un seul
|
||||
# ../RoadTripsGenerator/Scripts/genere_site.sh Balades/Vexin-10-2026
|
||||
#
|
||||
# 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
|
||||
# Variables :
|
||||
# ROOT=chemin racine du site (défaut : dossier courant)
|
||||
# SKIP_COMPRESS=1 ne lance pas compress.sh
|
||||
# + celles de compress.sh (JOBS, ENCODER…) et de prepare_web.py (WEB_PX…)
|
||||
# =============================================================================
|
||||
|
||||
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)}"
|
||||
ROOT="${ROOT:-$PWD}"
|
||||
SKIP_COMPRESS="${SKIP_COMPRESS:-0}"
|
||||
|
||||
cd "$ROOT" || { echo "❌ Racine introuvable : $ROOT"; exit 1; }
|
||||
ROOT="$PWD"
|
||||
export RT_RACINE="$ROOT" # cible du bouton « Retour » des voyages
|
||||
|
||||
for s in extraction_infos.sh compress.sh genere_carte.py genere_index_general.py; do
|
||||
for s in extraction_infos.sh compress.sh prepare_web.py genere_carte.py genere_index_general.py; do
|
||||
if [ ! -f "$SCRIPT_DIR/$s" ]; then
|
||||
echo "❌ Script manquant : $SCRIPT_DIR/$s"
|
||||
exit 1
|
||||
@@ -43,10 +43,17 @@ for s in extraction_infos.sh compress.sh genere_carte.py genere_index_general.py
|
||||
[ -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.
|
||||
# Dossiers qui ne sont jamais des voyages ni des regroupements.
|
||||
ignore() {
|
||||
case "$1" in
|
||||
Scripts|RoadTripsGenerator|html|assets|videos|photos|photos_web|apercus|rushs|routes) return 0 ;;
|
||||
_*|.*) return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
# ok | lien_casse | absent. Un lien symbolique cassé ressemble à un lien valide
|
||||
# dans `ls -l`, mais `test -d` renvoie faux : on le signale à part.
|
||||
etat_dossier() {
|
||||
if [ -d "$1" ]; then echo ok
|
||||
elif [ -L "$1" ]; then echo lien_casse
|
||||
@@ -54,13 +61,31 @@ etat_dossier() {
|
||||
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 "?"
|
||||
|| readlink "$1" 2>/dev/null || echo "?"
|
||||
}
|
||||
|
||||
# Vrai si le dossier a au moins un sous-dossier exploitable. Signale au passage
|
||||
# les liens cassés et les sous-dossiers manquants (dans $DETAILS).
|
||||
DETAILS=""
|
||||
est_voyage() {
|
||||
local dir="$1" sub presents=0
|
||||
DETAILS=""
|
||||
for sub in rushs routes photos; do
|
||||
case "$(etat_dossier "$dir/$sub")" in
|
||||
ok) presents=$((presents + 1)) ;;
|
||||
lien_casse)
|
||||
echo "🔗 $dir/$sub : LIEN SYMBOLIQUE CASSÉ"
|
||||
echo " pointe vers : $(resoudre_lien "$dir/$sub")"
|
||||
echo " (disque externe non branché, ou dossier déplacé ?)"
|
||||
DETAILS="$DETAILS $sub(lien cassé)" ;;
|
||||
absent) DETAILS="$DETAILS $sub(absent)" ;;
|
||||
esac
|
||||
done
|
||||
[ "$presents" -gt 0 ]
|
||||
}
|
||||
|
||||
echo "=================================================="
|
||||
@@ -70,52 +95,35 @@ echo "=================================================="
|
||||
echo
|
||||
|
||||
# --- Sélection des voyages ---------------------------------------------------
|
||||
candidats=()
|
||||
voyages=()
|
||||
ajoute() {
|
||||
voyages+=("$1")
|
||||
[ -n "$DETAILS" ] && echo "⚠️ $1 : sous-dossier(s) indisponible(s) :$DETAILS — étape(s) sautée(s)"
|
||||
}
|
||||
|
||||
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
|
||||
for d in "$@"; do
|
||||
d="${d%/}"
|
||||
if [ ! -d "$d" ]; then echo "❌ $d : ce dossier n'existe pas."; continue; fi
|
||||
if est_voyage "$d"; then ajoute "$d"
|
||||
else echo "❌ $d : aucun de rushs/ routes/ photos/ n'est utilisable :$DETAILS"; fi
|
||||
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
|
||||
else
|
||||
for d in */; do
|
||||
d="${d%/}"
|
||||
ignore "$d" && continue
|
||||
if est_voyage "$d"; then
|
||||
ajoute "$d"
|
||||
else
|
||||
# Pas un voyage : peut-être un regroupement (Balades/…).
|
||||
for s in "$d"/*/; do
|
||||
s="${s%/}"
|
||||
ignore "$(basename "$s")" && continue
|
||||
est_voyage "$s" && ajoute "$s"
|
||||
done
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "${#voyages[@]}" -eq 0 ]; then
|
||||
echo
|
||||
@@ -126,7 +134,6 @@ 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 --------------------------------------------------------------
|
||||
@@ -148,10 +155,12 @@ for dir in "${voyages[@]}"; do
|
||||
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."
|
||||
echo "⚠️ Compression incomplète sur $dir — on continue avec les vidéos disponibles."
|
||||
fi
|
||||
|
||||
# Non bloquant : sans photos web ni aperçus, les pages utilisent les originaux.
|
||||
"$SCRIPT_DIR/prepare_web.py" "$dir" || echo "⚠️ Préparation web incomplète sur $dir — on continue."
|
||||
|
||||
if ! "$SCRIPT_DIR/genere_carte.py" "$dir"; then
|
||||
echo "❌ Génération des cartes échouée sur $dir."
|
||||
ko=$((ko + 1)); echo; continue
|
||||
@@ -162,9 +171,6 @@ for dir in "${voyages[@]}"; do
|
||||
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 "=================================================="
|
||||
|
||||
Reference in new issue
Block a user