Files
RoadTripsGenerator/rtg/cli.py
T
FabriceandClaude Opus 5.5 71779f6f53 Interface : corrections à la souris et accès protégé
Onglet « Carte et corrections » : glisser une photo ou une vidéo, placer
les médias sans position, masquer des zones de trace (pour un voyage, ou
zone privée pour tous). Corrections notées dans voyage.toml ([positions],
[corrections]) ou site.toml ([confidentialite]), appliquées par les pages ;
les originaux ne changent pas. L'extraction garde les médias datés sans
position pour qu'on puisse les placer.

Accès : clé d'accès aléatoire à chaque lancement, session par cookie
HttpOnly/SameSite=Strict, mot de passe facultatif (rtg mot-de-passe,
empreinte scrypt hors du site, blocage après 5 échecs), accès réseau
seulement avec mot de passe (--distant), HTTPS possible (--certificat,
--cle), Content-Security-Policy et interdiction des cadres.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mf2kATMtqVABHSYdxJMnim
2026-10-09 14:35:43 +00:00

113 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Commande `rtg`.
rtg generer [VOYAGE…] tout faire (sources, positions, vidéos, photos, pages, accueil)
rtg etat avancement de chaque voyage
rtg analyser VOYAGE ce que RTG trouve dans les sources d'un voyage
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é ?
rtg interface ouvrir l'interface dans le navigateur
rtg mot-de-passe définir le mot de passe de l'interface (accès distant)
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.
"""
import argparse
import os
import sys
from rtg import __version__
def main(argv=None):
p = argparse.ArgumentParser(prog="rtg", description="RoadTripsGenerator : site web de road-trips.")
p.add_argument("--version", action="version", version=f"rtg {__version__}")
p.add_argument("--racine", help="racine du site (défaut : recherche de site.toml)")
sp = p.add_subparsers(dest="commande", required=True)
g = sp.add_parser("generer", help="générer un, plusieurs ou tous les voyages, puis l'accueil")
g.add_argument("voyages", nargs="*", help="dossiers des voyages (défaut : tous)")
g.add_argument("--sans-compression", action="store_true", help="ne pas encoder les vidéos")
g.add_argument("--force", action="store_true", help="tout refaire, même ce qui est à jour")
g.add_argument("--mymaps-maj", action="store_true", help="récupérer à nouveau les cartes My Maps")
sp.add_parser("etat", help="avancement de chaque voyage")
a = sp.add_parser("analyser", help="inventaire des sources d'un voyage")
a.add_argument("voyage")
c = sp.add_parser("compresser", help="encoder les vidéos d'un voyage")
c.add_argument("voyage")
c.add_argument("--force", action="store_true")
ac = sp.add_parser("accueil", help="régénérer l'accueil et la carte globale")
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")
i = sp.add_parser("interface", help="ouvrir l'interface dans le navigateur")
i.add_argument("--port", type=int, default=8765)
i.add_argument("--sans-navigateur", action="store_true", help="ne pas ouvrir le navigateur")
i.add_argument("--distant", action="store_true",
help="accepter les connexions depuis le réseau (mot de passe obligatoire)")
i.add_argument("--certificat", help="certificat TLS (PEM) pour servir en HTTPS")
i.add_argument("--cle", help="clé privée du certificat TLS (PEM)")
mp = sp.add_parser("mot-de-passe", help="définir ou supprimer le mot de passe de l'interface")
mp.add_argument("--supprimer", action="store_true")
args = p.parse_args(argv)
if args.commande == "mot-de-passe":
from rtg import acces
if args.supprimer:
print("✅ Mot de passe supprimé." if acces.supprimer() else "ℹ️ Aucun mot de passe défini.")
return
import getpass
mdp = getpass.getpass("Nouveau mot de passe : ")
if mdp != getpass.getpass("Le même, encore une fois : "):
sys.exit("❌ Les deux saisies diffèrent.")
try:
print(f"✅ Mot de passe enregistré ({acces.definir(mdp)}).")
except ValueError as e:
sys.exit(f"❌ {e}")
return
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(".")
try:
if args.commande == "generer":
ok = site.generer(racine, args.voyages, compression=not args.sans_compression,
force=args.force, mymaps_maj=args.mymaps_maj)
sys.exit(0 if ok else 1)
elif args.commande == "etat":
site.etat(racine)
elif args.commande == "analyser":
site.analyser(args.voyage, racine)
elif args.commande == "compresser":
v = os.path.abspath(args.voyage)
cfg = reglages_voyage(v, reglages_site(racine))
sys.exit(0 if video.compresser(v, cfg, sources.analyser(v, cfg), force=args.force) else 1)
elif args.commande == "accueil":
accueil.generer(racine, reglages_site(racine), args.mymaps_maj)
elif args.commande == "migrer":
site.migrer(racine)
elif args.commande == "interface":
from rtg.interface.serveur import lancer
if bool(args.certificat) != bool(args.cle):
sys.exit("❌ --certificat et --cle vont ensemble.")
lancer(racine, args.port, ouvrir=not args.sans_navigateur, distant=args.distant,
certificat=args.certificat, cle=args.cle)
except KeyboardInterrupt:
print("\nInterrompu.")
sys.exit(130)