Deux hypothèses du code ne tiennent plus dès qu'on l'installe ailleurs que dans son dépôt : - la racine était déduite de l'emplacement du module. Une installation non éditable la fait pointer vers site-packages, et le corpus de data/input/ est alors cherché à côté du venv, où il n'est pas. VEILLE_RACINE lève l'ambiguïté ; sans elle, le comportement d'avant est conservé. - l'export JSON était figé sous data/, donc dans le répertoire d'installation. Sur YunoHost celui-ci est effacé à chaque mise à jour. VEILLE_DUMP_JSON le déplace avec la base et le cache. Constaté en simulant l'installation, pas en relisant le code : VEILLE_DB était honorée et VEILLE_DUMP_JSON ignorée, le dump repartant dans l'arbre des sources. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
84 lines
3.4 KiB
Python
84 lines
3.4 KiB
Python
"""Localisation des fichiers du projet.
|
|
|
|
Un unique point de vérité pour les chemins, afin que les parseurs, les tests et
|
|
les collecteurs ne fassent jamais d'hypothèse sur le répertoire courant.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
# pipeline/chemins.py → pipeline/ → racine du dépôt.
|
|
#
|
|
# Ce calcul suppose que le paquet est exécuté depuis l'arbre des sources, ce qui
|
|
# est le cas en développement. Une installation non éditable le met en défaut :
|
|
# `__file__` pointe alors vers site-packages, et le corpus de `data/input/` est
|
|
# cherché à côté du venv, où il n'est pas.
|
|
#
|
|
# `VEILLE_RACINE` lève l'ambiguïté. Les déploiements la renseignent ; sans elle,
|
|
# le comportement historique est conservé.
|
|
_RACINE_PAR_DEFAUT = Path(__file__).resolve().parent.parent
|
|
RACINE = Path(os.environ.get("VEILLE_RACINE") or _RACINE_PAR_DEFAUT).resolve()
|
|
|
|
load_dotenv(RACINE / ".env")
|
|
|
|
# ── Corpus d'entrée — LECTURE SEULE ──────────────────────────────────────────
|
|
ENTREE = RACINE / "data" / "input"
|
|
RECHERCHE = ENTREE / "research"
|
|
|
|
RAPPORT_FINAL = ENTREE / "lois-france-2026-guadeloupe.agent.final.md"
|
|
RAPPORT_OUTLINE = ENTREE / "lois-france-2026-guadeloupe.agent.outline.md"
|
|
BIBLIOGRAPHIE = ENTREE / "lois-france-2026-guadeloupe_ref.md"
|
|
|
|
CROSS_VERIFICATION = RECHERCHE / "lois-2026_cross_verification.md"
|
|
INSIGHTS = RECHERCHE / "lois-2026_insight.md"
|
|
PHASE5_VALIDATION = RECHERCHE / "lois-2026_phase5_validation.md"
|
|
|
|
|
|
def chapitre(numero: int) -> Path:
|
|
"""Chemin d'un chapitre du rapport : `chapitre(10)` → `…_sec10.md`."""
|
|
return ENTREE / f"lois-france-2026-guadeloupe_sec{numero:02d}.md"
|
|
|
|
|
|
def dimension(numero: int) -> Path:
|
|
"""Chemin d'un rapport de dimension : `dimension(7)` → `lois-2026_dim07.md`."""
|
|
return RECHERCHE / f"lois-2026_dim{numero:02d}.md"
|
|
|
|
|
|
CHAPITRES = [chapitre(n) for n in range(11)]
|
|
DIMENSIONS = [dimension(n) for n in range(1, 13)]
|
|
|
|
# ── Sorties ──────────────────────────────────────────────────────────────────
|
|
#
|
|
# Les trois chemins de sortie sont configurables par variable d'environnement,
|
|
# et acceptent une valeur absolue — `Path("/a") / "/b"` vaut `/b`.
|
|
#
|
|
# Ce n'est pas de la souplesse gratuite : sur un déploiement YunoHost, la mise
|
|
# à jour efface intégralement le répertoire d'installation (`ynh_setup_source
|
|
# --full_replace`). Tout ce qui doit survivre — base, cache, export — vit donc
|
|
# ailleurs, dans le répertoire de données persistant de l'application.
|
|
DONNEES = RACINE / "data"
|
|
BASE_SQLITE = RACINE / os.environ.get("VEILLE_DB", "data/veille.db")
|
|
DUMP_JSON = RACINE / os.environ.get("VEILLE_DUMP_JSON", "data/textes.json")
|
|
CACHE_HTTP = RACINE / os.environ.get("VEILLE_CACHE", "data/cache_http")
|
|
|
|
MIGRATIONS = Path(__file__).resolve().parent / "migrations"
|
|
CONFIG = Path(__file__).resolve().parent / "config.yaml"
|
|
|
|
|
|
def verifier_corpus() -> list[str]:
|
|
"""Retourne la liste des fichiers d'entrée attendus mais absents."""
|
|
attendus = [
|
|
RAPPORT_FINAL,
|
|
BIBLIOGRAPHIE,
|
|
CROSS_VERIFICATION,
|
|
INSIGHTS,
|
|
PHASE5_VALIDATION,
|
|
*CHAPITRES,
|
|
*DIMENSIONS,
|
|
]
|
|
return [str(p.relative_to(RACINE)) for p in attendus if not p.exists()]
|