From d40e963019b7235b9ac92b6946dd00a714be4076 Mon Sep 17 00:00:00 2001 From: Fabrice Date: Fri, 9 Oct 2026 11:53:47 +0000 Subject: [PATCH] =?UTF-8?q?Installation=20document=C3=A9e=20par=20platefor?= =?UTF-8?q?me=20;=20commande=20rtg=20verifier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Mf2kATMtqVABHSYdxJMnim --- README.md | 86 +++++++++++++++++++++++++++++++---------- rtg/cli.py | 7 ++++ rtg/verifier.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 20 deletions(-) create mode 100644 rtg/verifier.py diff --git a/README.md b/README.md index c8bbcd9..b9bcb27 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -*RoadTripsGenerator* est un ensemble de scripts (bash et Python) qui génèrent un site web statique de road-trips : une carte interactive par voyage et par jour, avec les photos, les vidéos, les traces GPS et le récit du voyage. +*RoadTripsGenerator* (RTG) est un logiciel qui génère un site web statique de road-trips : une carte interactive par voyage et par jour, avec les photos, les vidéos, les traces GPS et le récit du voyage. C'est sans prétention et il faudrait probablement des développements bien plus sérieux pour obtenir un logiciel « presse-bouton », mais si cela peut donner des idées… @@ -18,22 +18,74 @@ Ils préparent aussi les médias pour le web : Les originaux ne sont jamais modifiés. Le site produit est statique : une simple copie suffit pour le publier ou le transporter. -## Les prérequis +## Installation -Les scripts fonctionnent sous macOS et Linux. +RTG fonctionne sous macOS et Linux ; Windows devrait fonctionner mais n'a pas encore été testé. Il lui faut : -* obligatoirement : - * Python 3 et les paquets `pandas folium gpxpy markdown2 numpy` (Jinja2, utilisé pour la mise en page, est installé avec folium) - * `exiftool` -* conseillé : - * `ffmpeg` (compression des vidéos et images d'aperçu) - * `pillow` pour les photos allégées (sous macOS, l'outil `sips` du système prend le relais s'il est absent) +| Élément | Rôle | Version | +| --- | --- | --- | +| Python | le logiciel lui-même | 3.10 ou plus récent | +| pipx | installe RTG et ses modules Python dans un espace à part | — | +| exiftool | lit les dates et positions GPS des photos et des vidéos | toute version récente | +| ffmpeg (avec libx265 et libx264) | compresse les vidéos, tire les images d'aperçu | 5 ou plus récent | + +Les modules Python (folium, pandas, gpxpy, Pillow, pillow-heif…) sont installés automatiquement avec RTG. + +### macOS + +1. Installer [Homebrew](https://brew.sh) s'il n'est pas déjà là : + ``` + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + ``` +2. Installer les outils, puis rendre pipx accessible : + ``` + brew install python pipx exiftool ffmpeg + pipx ensurepath + ``` +3. Fermer et rouvrir le Terminal. + +Le ffmpeg de Homebrew contient libx265, libx264 et l'encodeur matériel VideoToolbox du Mac. + +### Linux (Debian, Ubuntu et dérivées) ``` -brew install exiftool ffmpeg -pip3 install pandas folium gpxpy markdown2 numpy pillow +sudo apt install python3 pipx ffmpeg libimage-exiftool-perl +pipx ensurepath ``` +Puis fermer et rouvrir le terminal. Sur Fedora : `sudo dnf install pipx perl-Image-ExifTool` et ffmpeg depuis RPM Fusion. + +### Windows (non testé) + +Dans PowerShell : + +``` +winget install Python.Python.3.12 Gyan.FFmpeg OliverBetz.ExifTool +py -m pip install --user pipx +py -m pipx ensurepath +``` + +Puis fermer et rouvrir PowerShell. + +### Installer RTG + +Récupérer le dépôt (ou le copier, par exemple sur un disque externe) : + +``` +git clone https://git.ouaibe.fr/Korrigan/RoadTripsGenerator.git +pipx install --editable ./RoadTripsGenerator +``` + +Avec `--editable`, la commande `rtg` utilise directement le code du dossier : une mise à jour du dépôt (`git pull`) est prise en compte sans réinstaller. Le dossier doit alors rester accessible (disque branché). + +### Vérifier + +``` +rtg verifier +``` + +La commande contrôle Python, les modules, exiftool, ffmpeg et ses encodeurs, et donne pour chaque élément manquant la commande à taper sur votre système. + ## Organisation des dossiers Le dépôt et le site sont deux dossiers voisins. Un voyage est un dossier qui contient au moins un des sous-dossiers `photos`, `rushs` ou `routes`. Les voyages rangés à la racine du site forment la rubrique « Voyages » de la page d'accueil. Ceux rangés un niveau plus bas, dans un dossier de regroupement (ici `Balades`), forment une rubrique du nom de ce dossier. L'accueil montre les 2 plus récents de chaque rubrique (`ACCUEIL_NB=3` pour en montrer plus), avec un lien vers la liste complète. @@ -62,14 +114,7 @@ Dans le récit `voyage.md`, deux raccourcis évitent les liens écrits en dur (q [La descente](media:videos/GH011272.mp4) ``` -## Installation et utilisation : la commande `rtg` - -RTG s'installe comme un logiciel, avec une seule commande `rtg` utilisable depuis n'importe quel dossier : - -``` -brew install exiftool ffmpeg # ou l'équivalent sous Linux / Windows -pipx install ./RoadTripsGenerator # depuis le dossier du dépôt -``` +## Utilisation : la commande `rtg` Depuis le dossier du site (`Road-Trips`) : @@ -79,6 +124,7 @@ rtg etat # avancement de chaque voyage rtg generer Balades/Vexin-10-2026 # un voyage, puis l'accueil rtg generer --sans-compression # tous les voyages, sans encoder de vidéo rtg analyser Balades/Vexin-10-2026 # ce que RTG trouve dans les sources +rtg verifier # tout est-il installé ? ``` Les sources d'un voyage peuvent rester où elles sont, nommées n'importe comment : on les indique dans son `voyage.toml`. @@ -95,7 +141,7 @@ photos = ["~/Pictures/Export/Vexin"] RTG range alors lui-même les traces par journée (`routes/AAAA-MM-JJ.gpx`, d'après leurs horodatages ou, à défaut, la date du nom de fichier) et copie les photos dans `photos/` (les HEIC de l'iPhone sont converties en JPEG). Une photo sans GPS reçoit la position de la trace à son heure, quand la trace est horodatée. Les réglages communs (qualité vidéo, taille des photos, fuseau horaire, cartes My Maps…) sont dans `site.toml`. -Les scripts de `Scripts/` restent disponibles pendant la transition ; ils produisent le même site. +Les scripts de `Scripts/` restent disponibles pendant la transition ; ils produisent le même site. Ils demandent en plus d'installer à la main les modules Python : `pip3 install pandas folium gpxpy markdown2 numpy pillow`. ## Mode d'emploi (anciens scripts) diff --git a/rtg/cli.py b/rtg/cli.py index 96c4578..c41f3ca 100644 --- a/rtg/cli.py +++ b/rtg/cli.py @@ -6,6 +6,7 @@ rtg compresser VOYAGE seulement les vidéos rtg accueil seulement la page d'accueil et la carte globale rtg migrer écrire site.toml et les voyage.toml depuis l'existant + rtg verifier tout ce dont RTG a besoin est-il installé ? La racine du site est le premier dossier, en remontant depuis le dossier courant, qui contient site.toml (sinon le dossier courant) ; --racine la force. @@ -42,9 +43,15 @@ def main(argv=None): ac.add_argument("--mymaps-maj", action="store_true") sp.add_parser("migrer", help="écrire site.toml et voyage.toml depuis l'organisation actuelle") + sp.add_parser("verifier", help="contrôler que Python, exiftool et ffmpeg sont bien installés") args = p.parse_args(argv) + if args.commande == "verifier": + # Avant tout autre import : doit fonctionner même si un module manque. + from rtg.verifier import verifier + sys.exit(0 if verifier() else 1) + from rtg import accueil, site, sources, video from rtg.config import reglages_site, reglages_voyage, trouver_racine racine = os.path.abspath(args.racine) if args.racine else trouver_racine(".") diff --git a/rtg/verifier.py b/rtg/verifier.py new file mode 100644 index 0000000..2a5c4a2 --- /dev/null +++ b/rtg/verifier.py @@ -0,0 +1,100 @@ +"""`rtg verifier` : tout ce dont RTG a besoin est-il installé ? + +Pour chaque élément manquant, la commande à taper sur ce système. +""" +import importlib +import platform +import subprocess +import sys + +from rtg.outils import dire, programme + +SYSTEME = {"Darwin": "mac", "Windows": "windows"}.get(platform.system(), "linux") + +# Commande d'installation par système, pour chaque programme externe. +INSTALLER = { + "exiftool": {"mac": "brew install exiftool", "linux": "sudo apt install libimage-exiftool-perl", + "windows": "winget install OliverBetz.ExifTool"}, + "ffmpeg": {"mac": "brew install ffmpeg", "linux": "sudo apt install ffmpeg", + "windows": "winget install Gyan.FFmpeg"}, +} + +# Modules Python : (nom à importer, nom du paquet, indispensable ?) +MODULES = [ + ("folium", "folium", True), ("gpxpy", "gpxpy", True), ("jinja2", "jinja2", True), + ("markdown2", "markdown2", True), ("numpy", "numpy", True), ("pandas", "pandas", True), + ("PIL", "pillow", True), ("pillow_heif", "pillow-heif", False), +] + + +def _version(cmd): + try: + r = subprocess.run(cmd, capture_output=True, text=True, timeout=20) + return (r.stdout or r.stderr).strip().splitlines()[0] + except Exception: + return "" + + +def verifier(): + """Affiche le bilan ; renvoie True si l'essentiel est là.""" + ok = True + dire(f"Système : {platform.system()} {platform.release()} ({platform.machine()})") + + v = sys.version_info + if v >= (3, 10): + dire(f"✅ Python {v.major}.{v.minor}.{v.micro}") + else: + ok = False + dire(f"❌ Python {v.major}.{v.minor} : il faut Python 3.10 ou plus récent") + + manquants = [] + for module, paquet, indispensable in MODULES: + try: + importlib.import_module(module) + except ImportError: + if indispensable: + ok = False + manquants.append(paquet) + dire(f"❌ Module Python {paquet} absent") + else: + dire(f"⚠️ Module Python {paquet} absent : les photos HEIC de l'iPhone seront ignorées") + if manquants: + dire(f" → réinstaller RTG avec pipx (il installe les modules), ou : " + f"python3 -m pip install {' '.join(manquants)}") + if not manquants: + dire("✅ Modules Python") + if sys.version_info < (3, 11): + try: + importlib.import_module("tomli") + except ImportError: + ok = False + dire("❌ Module Python tomli absent (nécessaire avant Python 3.11)") + + if programme("exiftool"): + dire(f"✅ exiftool {_version(['exiftool', '-ver'])}") + else: + ok = False + dire(f"❌ exiftool absent (positions GPS des photos et vidéos) → {INSTALLER['exiftool'][SYSTEME]}") + + if programme("ffmpeg") and programme("ffprobe"): + dire(f"✅ {_version(['ffmpeg', '-version'])[:60]}") + enc = subprocess.run(["ffmpeg", "-hide_banner", "-encoders"], capture_output=True, text=True).stdout + for nom, role in (("libx265", "1080p HEVC"), ("libx264", "720p H.264")): + if nom in enc: + dire(f" ✅ {nom} ({role})") + else: + ok = False + dire(f" ❌ {nom} absent de ce ffmpeg ({role}) → installer un ffmpeg complet : " + f"{INSTALLER['ffmpeg'][SYSTEME]}") + if SYSTEME == "mac": + if "hevc_videotoolbox" in enc: + dire(" ✅ VideoToolbox (encodeur « matériel », facultatif)") + else: + dire(" ⚠️ VideoToolbox absent : seul l'encodeur « processeur » sera disponible") + else: + ok = False + dire(f"❌ ffmpeg absent (vidéos et aperçus) → {INSTALLER['ffmpeg'][SYSTEME]}") + + dire() + dire("✅ Tout est prêt." if ok else "❌ Il manque des éléments : voir les lignes ❌ ci-dessus.") + return ok