SPB Git forge

spb/lou-ka

Public

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

232commits 1branches 0releases
172.9 MBsize
maindefault branch
2 days agolast push
HTML 98.9% Python 0.6%

[ka2] fix connecteur devimco : nouveau format d'iframe Planpoint groupe (/g/<x>/<ns>)

Le widget groupe Planpoint est passé de /g/<ns> à /g/<x>/<ns> (le namespace
de l'API groups/find est le DERNIER segment, parfois avec majuscules dans le
premier). L'ancien regex envoyait le 1er segment -> 404 sur Alexander,
Maestria et Hexagone depuis le 2026-08-19 (479 -> 231 annonces). On essaie
maintenant les deux segments (en minuscules), et on accepte les namespaces
projet avec espace encodé (%20) -> Éolia (20 unités) capté pour la 1re fois.

Volume mesuré : 231 -> 481 trouvées (sync réelle : +22 ajouts, ~85 màj).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Simon-Pierre Boucher committed 1 mo ago (Aug 23, 2026) parent 834c92c

1 changed file +19 −7

modified louka/connectors/devimco.py +19 −7
@@ -121,23 +121,35 @@ class DevimcoConnector(BaseConnector):
121 121 html = self.get(proj_url).text
122 122
123 123 # iframe Planpoint : soit un projet (/<ns>/<host>), soit un groupe
124 − # de phases (/g/<ns>)
124 + # de phases. Depuis 2026-08, le widget groupe est /g/<x>/<ns> (deux
125 + # segments, le namespace de l'API est le DERNIER) ; l'ancien format
126 + # /g/<ns> reste possible -> on essaie les deux segments.
125 127 projects: list[dict] = []
126 128 m = re.search(
127 − r"https://app\.planpoint\.io/g/([a-z0-9\-]+)", html)
129 + r"https://app\.planpoint\.io/g/([A-Za-z0-9\-]+)"
130 + r"(?:/([A-Za-z0-9\-]+))?", html)
128 131 if m:
129 − group = self._planpoint(PLANPOINT_GROUP_FIND,
130 − {"namespace": m.group(1)})
131 − projects = group.get("projects") or []
132 + for ns in filter(None, (m.group(2), m.group(1))):
133 + try:
134 + group = self._planpoint(PLANPOINT_GROUP_FIND,
135 + {"namespace": ns.lower()})
136 + except Exception:
137 + continue
138 + projects = group.get("projects") or []
139 + if projects:
140 + break
132 141 else:
142 + # namespace parfois avec espace encodé (ex. groupe%20devimco)
133 143 m = re.search(
134 − r"https://app\.planpoint\.io/([a-z0-9\-]+)/([a-z0-9\-]+)\?",
144 + r"https://app\.planpoint\.io/([a-z0-9\-]+(?:%20[a-z0-9\-]+)*)"
145 + r"/([a-z0-9\-]+)\?",
135 146 html)
136 147 if not m:
137 148 return out
138 149 projects = [self._planpoint(
139 150 PLANPOINT_FIND,
140 − {"namespace": m.group(1), "hostName": m.group(2)})]
151 + {"namespace": urllib.parse.unquote(m.group(1)),
152 + "hostName": m.group(2)})]
141 153
142 154 # Adresse affichée sur la page Devimco (lien Google Maps) : repli
143 155 # pour les phases dont l'API Planpoint n'a pas d'adresse
144 156