SPB Git forge

spb/immo-ka

Public

Immo-Ka — agrégateur des propriétés à vendre au Québec (73 connecteurs, ~40 000 annonces, React+FastAPI)

112commits 1branches 0releases
125.4 MBsize
maindefault branch
13 days agolast push
Python 47.5% HTML 27.9% TypeScript 15.5% CSS 7.2% JavaScript 2%
3.7 KB · 87 lines python
Raw Blame History
1# -----------------------------------------------------------------------------2# Immo-Ka — Agrégateur de maisons à vendre (province de Québec)3# Auteur : Simon-Pierre Boucher — contact@spboucher.ai4# connectors/agences_source_immo.py : agences INDÉPENDANTES sur la plateforme5#   source.immo (plugin WordPress). Beaucoup de petites/moyennes agences QC6#   l'utilisent (liste sur source.immo). Chacune expose sa config publique à7#   /wp-content/uploads/_sourceimmo/_configs.json → on lit l'API publique8#   api-v1.source.immo (voir SourceImmoConnector). Ce sont des agences9#   autonomes : leurs inscriptions (leur propre n° Centris) sont ADDITIVES —10#   pas de sous-agence d'une bannière déjà couverte → source_id normal (pas _ag_).11#   EXCEPTION : les équipes/agences dont une partie des inscriptions est12#   co-listée avec une bannière couverte (co-inscription Centris) portent un id13#   « si_ag_<slug> » : la dédup Centris (db.refresh_dedup, sources %_ag_%)14#   masque leurs doublons tout en gardant leurs fiches uniques visibles.15#16#   Un connecteur par agence est généré depuis data/source_immo_agencies.json.17# -----------------------------------------------------------------------------18from __future__ import annotations1920import json21from pathlib import Path2223from .sourceimmo import SourceImmoConnector24from ..schema import PropertyListing2526REGISTRY = Path(__file__).resolve().parent.parent.parent / "data" / "source_immo_agencies.json"272829class _AgenceSourceImmo(SourceImmoConnector):30    """Agence indépendante source.immo. Recharge sa config depuis le site31    (résilient aux rotations d'UUID) ; agency_name pour l'affichage Sources."""3233    agency_name = ""34    # segment d'URL des fiches sur le site WordPress (raccourci source.immo) —35    # certains thèmes utilisent autre chose que « propriete » (ex. BLVD :36    # « details-de-la-propriete ») ; surchargé via listing_path du registre.37    listing_path = "propriete"3839    def fetch(self) -> list[PropertyListing]:40        base = self.site_url.rstrip("/")41        try:42            cfg = self.get(f"{base}/wp-content/uploads/_sourceimmo/_configs.json").json()43            self.account_id = cfg.get("account_id", self.account_id)44            self.api_key = cfg.get("api_key", self.api_key)45            self.app_id = cfg.get("app_id", self.app_id)46            self.view_id = cfg.get("default_view", self.view_id)47        except Exception:48            pass49        return super().fetch()5051    def _to_listing(self, it: dict) -> PropertyListing | None:52        lst = super()._to_listing(it)53        if lst is not None:54            lst.broker_name = self.agency_name55            lst.agency = self.agency_name56            ref = it.get("ref_number") or it.get("id")57            if ref and self.site_url:58                lst.url = f"{self.site_url.rstrip('/')}/{self.listing_path}/{ref}"59        return lst606162def _load() -> list[dict]:63    try:64        return json.loads(REGISTRY.read_text(encoding="utf-8"))65    except Exception:66        return []676869# Génère une classe par agence du registre.70for _ag in _load():71    if not all(_ag.get(k) for k in ("id", "domain", "account", "api", "app", "view")):72        continue73    _sid = _ag["id"]74    _dom = _ag["domain"].rstrip("/")75    globals()[f"AGENCE_{_sid.upper()}"] = type(76        "AgenceSI" + "".join(p.title() for p in _sid.split("_")),77        (_AgenceSourceImmo,),78        {79            "source_id": _sid,80            "account_id": _ag["account"], "api_key": _ag["api"],81            "app_id": _ag["app"], "view_id": _ag["view"],82            "site_url": f"https://{_dom}/",83            "agency_name": _ag.get("name", _sid.title()),84            "listing_path": _ag.get("listing_path", "propriete"),85        },86    )87