SPB Git

spb/lou-ka

Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

3.7 KB · 93 lines python
1#!/usr/bin/env python32# -----------------------------------------------------------------------------3# Lou-Ka — Agrégateur de logements à louer (province de Québec)4# Auteur : Simon-Pierre Boucher — contact@spboucher.ai5# run.py : point d'entrée — `sync`, `watch`, `serve`6# -----------------------------------------------------------------------------7"""Utilisation :8    python run.py sync [source ...]     # synchronise les annonces9    python run.py watch [minutes]       # synchronise en boucle (défaut 60 min)10    python run.py serve [port]          # démarre l'API + le frontend (défaut 8080)11    python run.py record <source ...>   # enregistre les fixtures de test d'une source12    python run.py geocode [n]           # géocode les annonces sans coordonnées (max n requêtes)13    python run.py poi [n]               # commodités de proximité par immeuble (max n requêtes)14"""15from __future__ import annotations1617import os18import sys19from pathlib import Path2021# Charger .env (FIRECRAWL_API_KEY, etc.) sans dépendance externe22_env = Path(__file__).parent / ".env"23if _env.exists():24    for line in _env.read_text().splitlines():25        line = line.strip()26        if line and not line.startswith("#") and "=" in line:27            k, _, v = line.partition("=")28            os.environ.setdefault(k.strip(), v.strip())293031def main() -> None:32    cmd = sys.argv[1] if len(sys.argv) > 1 else "serve"33    if cmd == "sync":34        from louka import ingest35        ingest.run(sys.argv[2:] or None)36    elif cmd == "watch":37        from louka import ingest38        minutes = int(sys.argv[2]) if len(sys.argv) > 2 else 6039        ingest.watch(minutes * 60)40    elif cmd == "geocode1":41        from louka import geocode42        limit = int(sys.argv[2]) if len(sys.argv) > 2 else None43        geocode.run(limit)44    elif cmd == "geocode":45        # lot Adresses Québec (rapide) ; « geocode1 » = ancien mode 1-par-146        from louka import geocode47        limit = int(sys.argv[2]) if len(sys.argv) > 2 else None48        geocode.run_batch(limit)49    elif cmd == "quality":50        # (re)calcule le score de complétude + publication/quarantaine51        from louka import quality52        limit = int(sys.argv[2]) if len(sys.argv) > 2 else None53        quality.backfill(limit)54    elif cmd == "imgaudit":55        # contrôle qualité des images (liens morts, minuscules, placeholders,56        # doublons) — incrémental : python run.py imgaudit [n_annonces] [source]57        from louka import imgcheck58        limit = int(sys.argv[2]) if len(sys.argv) > 2 else 150059        src = sys.argv[3] if len(sys.argv) > 3 else None60        imgcheck.run(limit, source=src)61    elif cmd == "fairvalue":62        # (re)calcule la juste valeur locative de toutes les annonces publiées63        from louka import fairvalue64        fairvalue.compute_all()65    elif cmd == "poi":66        from louka import poi67        limit = int(sys.argv[2]) if len(sys.argv) > 2 else None68        poi.run(limit)69    elif cmd == "quartier":70        from louka import quartier71        limit = int(sys.argv[2]) if len(sys.argv) > 2 else None72        quartier.enrich(limit)73    elif cmd == "record":74        from louka import fixtures75        from louka.connectors import CONNECTORS76        targets = sys.argv[2:] or sorted(CONNECTORS)77        for sid in targets:78            try:79                print(f"[lou-ka] record {sid} ... {fixtures.record(sid)}")80            except Exception as exc:81                print(f"[lou-ka] record {sid} ÉCHEC : {exc}", file=sys.stderr)82    elif cmd == "serve":83        import uvicorn84        port = int(sys.argv[2]) if len(sys.argv) > 2 else 808085        uvicorn.run("louka.web:app", host="0.0.0.0", port=port)86    else:87        print(__doc__)88        sys.exit(1)899091if __name__ == "__main__":92    main()93
Files · bcd2a31102cee5353811a2d37d88dc7ddcece7d6
Menu

Theme