# ----------------------------------------------------------------------------- # Lou-Ka — Agrégateur de logements à louer (province de Québec) # Auteur : Simon-Pierre Boucher — contact@spboucher.ai # connectors/m3_laval.py : connecteur M3 Condos locatifs (m3mirabel.com — # Cité Mirabel, boul. de Versailles ; 2 groupes d'immeubles : Bâtiments 1 à 3 # et 4 à 7, ~325 unités). NB : slug historique « m3_laval » de la campagne # Laval/Rive-Nord, mais le projet est bien à MIRABEL (Laurentides). # La page /plans/ affiche ses unités via le widget Planpoint : on interroge # l'API JSON publique (app.planpoint.io/api/projects/find, 2 requêtes/sync, # voir _planpoint.py). Granularité UNITÉ : type (« 4 1/2 »), pi², chambres, # plans par unité, adresse + lat/lng par immeuble ; la source ne publie # AUCUN prix (price null/0 chez Planpoint, pas de prix sur le site non # plus) — rien d'inventé. Seules les unités « Available » sont retenues. # ----------------------------------------------------------------------------- from __future__ import annotations from ..schema import Listing from ._planpoint import planpoint_projects, unit_listing from .base import BaseConnector PAGE_URL = "https://www.m3mirabel.com/plans/" NAMESPACE = "M3MIRABEL" HOST_NAMES = ("Batiment1a3", "Batiments4a7") class M3LavalConnector(BaseConnector): source_id = "m3_laval" request_delay = 0.8 def fetch(self) -> list[Listing]: listings: list[Listing] = [] for host in HOST_NAMES: try: projects = planpoint_projects(self, "projects", NAMESPACE, host) except Exception: continue for project in projects: for floor in project.get("floors") or []: for unit in floor.get("units") or []: lst = unit_listing(self.source_id, project, floor, unit, page_url=PAGE_URL, default_city="Mirabel") if lst is not None: listings.append(lst) return listings