Installation documentée par plateforme ; commande rtg verifier
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
b9cb4b8b47
commit
d40e963019
3 files changed
+173
-20
No files matched your search
@@ -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…
|
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 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 :
|
| Élément | Rôle | Version |
|
||||||
* Python 3 et les paquets `pandas folium gpxpy markdown2 numpy` (Jinja2, utilisé pour la mise en page, est installé avec folium)
|
| --- | --- | --- |
|
||||||
* `exiftool`
|
| Python | le logiciel lui-même | 3.10 ou plus récent |
|
||||||
* conseillé :
|
| pipx | installe RTG et ses modules Python dans un espace à part | — |
|
||||||
* `ffmpeg` (compression des vidéos et images d'aperçu)
|
| exiftool | lit les dates et positions GPS des photos et des vidéos | toute version récente |
|
||||||
* `pillow` pour les photos allégées (sous macOS, l'outil `sips` du système prend le relais s'il est absent)
|
| 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
|
sudo apt install python3 pipx ffmpeg libimage-exiftool-perl
|
||||||
pip3 install pandas folium gpxpy markdown2 numpy pillow
|
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
|
## 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.
|
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)
|
[La descente](media:videos/GH011272.mp4)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installation et utilisation : la commande `rtg`
|
## 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
|
|
||||||
```
|
|
||||||
|
|
||||||
Depuis le dossier du site (`Road-Trips`) :
|
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 Balades/Vexin-10-2026 # un voyage, puis l'accueil
|
||||||
rtg generer --sans-compression # tous les voyages, sans encoder de vidéo
|
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 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`.
|
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`.
|
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)
|
## Mode d'emploi (anciens scripts)
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
rtg compresser VOYAGE seulement les vidéos
|
rtg compresser VOYAGE seulement les vidéos
|
||||||
rtg accueil seulement la page d'accueil et la carte globale
|
rtg accueil seulement la page d'accueil et la carte globale
|
||||||
rtg migrer écrire site.toml et les voyage.toml depuis l'existant
|
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
|
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.
|
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")
|
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("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)
|
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 import accueil, site, sources, video
|
||||||
from rtg.config import reglages_site, reglages_voyage, trouver_racine
|
from rtg.config import reglages_site, reglages_voyage, trouver_racine
|
||||||
racine = os.path.abspath(args.racine) if args.racine else trouver_racine(".")
|
racine = os.path.abspath(args.racine) if args.racine else trouver_racine(".")
|
||||||
|
|||||||
+100
@@ -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
|
||||||
Reference in new issue
Block a user