SPB Git

spb/lou-ka

Public

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

page 1
  1. Mon, Aug 24, 2026 13

    1. Simon-Pierre Boucher · 7 files +670
    2. Simon-Pierre Boucher · 12 files +1,697 −1
    3. feat(pdf): fiche PDF complète — analyse de prix, registre, TAL, environnement, KA Scores
      …
      Le PDF de fiche reflète désormais tout le contenu de la fiche web :
      analyse de prix Lou-Ka (juste valeur, verdict, histogramme), registre
      des loyers (KPI + tableau), historique TAL, inondation, qualité de
      l'air, électricité, commerces/transport, essence, KA Scores et
      quartier, avec pagination dynamique multi-pages. Les photos sont
      redimensionnées (max 1200 px, JPEG q82) : le PDF passe de 30 Mo à
      ~400 Ko sur une annonce enrichie.
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +468 −39
    4. feat(design): passe « éditorial sharp » sur la fiche — cartes, KPI, tableaux, pastilles
      …
      Blocs de la fiche transformés en cartes encre (bordure 1,5 px + ombre décalée
      douce), titres de section à marqueur accent + filet, tuiles KPI blanches à
      ombre dure, tableaux zébrés avec survol accent, barres de proximité/crime/air
      en dégradé, pastilles d'état unifiées (mono, point, liseré), décisions TAL en
      mini-cartes. Vérifié Playwright desktop 1440 + mobile 390 (overflow 0,
      check-order OK).
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +111
    5. feat(tal): historique du Tribunal administratif du logement par adresse
      …
      Décisions publiques du TAL (diffusées par SOQUIJ) croisées avec l'adresse
      de chaque annonce : recherche « no civique + rue » via Scrapfly (le site
      exige rendu JS + IP résidentielle ; pas de phrases entre guillemets),
      puis vérification de l'adresse exacte dans le texte intégral et
      classification (non-paiement, résiliation, expulsion, reprise/éviction,
      insalubrité…, demande du locateur vs du locataire, verdict). Cache par
      adresse dans data/tal.db, backfill borné dans la boucle watch + file
      prioritaire alimentée par les fiches consultées (/api/tal), bloc
      « Historique au TAL » sur la fiche (aucun nom de partie affiché —
      référence neutre + lien SOQUIJ).
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 9 files +616
    6. Simon-Pierre Boucher · 1 file +123 −38
    7. feat(doc): page documentation /doc (guide + captures) + lien footer + PDF téléchargeable
      …
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 8 files +171 −1
    8. Simon-Pierre Boucher · 3 files +90 −191
    9. Simon-Pierre Boucher · 1 file +16 −7
    10. Stats : panneaux territoire (registre des loyers, population, essence)
      …
      - louka/statsextra.py : 3 panneaux calculés sur nos jeux ouverts (cache 30 min)
        · Registre des loyers : 57 k loyers déclarés — KPI, médiane par nb chambres,
          histogramme, top 15 villes
        · Population & territoire : recensement des aires de diffusion couvertes
          (population, revenu médian, % locataires, âge, défavorisation) via
          listings.dauid
        · Prix de l essence : ~2450 stations gazquebec.ca — médianes régulier/super/
          diesel, barres et tableau par région
      - dashboard : clé panels ; Stats.tsx : rendu groupé et titré réutilisant le kit
        (KpiCard/Donut/BarChart/Histogram/DataTable)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 3 files +376
    11. hydro : postal rooftop (géocodage avant Mapbox + proximity), cache négatif, fix civiques ordinaux
      …
      - _resolve_postal : géocodage AVANT de l adresse complète ancré par proximity
        lat/lng (CP rooftop précis, vérif du numéro civique) au lieu de l inverse
        du lat/lng approximatif — récupère des adresses qui échouaient (ex.
        2038 Charlemagne : 0 -> 618 $/an)
      - cache négatif (NEG_TTL 30 j) : les adresses inconnues d HQ ne re-consomment
        plus de captcha à chaque cycle watch
      - _civic rejette les rues ordinales (15e Avenue, 1re Avenue, 2e Rang) tout en
        gardant la lettre d appartement (2457A)
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +79 −13
  2. Sun, Aug 23, 2026 18

    1. hydro : cache par uid + dérivation du code postal via lat/lng (Mapbox)
      …
      - cache indexé aussi par uid (clé stable annonce) : affichage cache-only sur
        la fiche sans code postal ni appel Mapbox
      - code postal dérivé du lat/lng par géocodage inverse Mapbox quand l adresse
        n en porte pas (cas Immo-Ka) — au moment du calcul seulement
      - estimate(uid, lat, lng) ; endpoint et fiche passent uid+lat+lng ;
        cache-only renvoie en_attente (bouton) si un calcul est faisable
      - precompute sélectionne lat/lng/uid, saute ce qui est déjà en cache par uid
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 5 files +128 −37
    2. hydro : pré-calcul des 100 annonces récentes + auto pour les nouvelles
      …
      - hydro.precompute(limit, budget) : calcule l estimation des annonces les plus
        récentes non encore en cache, plafond de résolutions captcha par appel
        (coût borné) ; run.py hydro-precompute [N] [budget]
      - watch : precompute(100, budget=30) à chaque cycle -> nouvelles annonces
        estimées automatiquement ; le cache data/hydro.db persiste entre releases
      - estimate(solve=False) = lecture cache seule (aucun captcha) ;
        GET /api/hydro cache-only par défaut, solve=1 pour forcer
      - fiche : le bloc s affiche AUTOMATIQUEMENT quand l estimation est en cache,
        sinon bouton de calcul à la demande
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 6 files +112 −26
    3. hydro : flux live fonctionnel (2captcha) — structure API réelle
      …
      - lieu-consommation : clé listeLieuxConsommation + cleUnique au niveau racine,
        code postal reformaté avec espace (exigé), idConso = item.id
      - estimation : {cleUnique, idConso} -> montantAnnuel + consommationAnnuelle
      - expose kwh_annuel ; testé live : 20 rue Lockwell = 283 $/an / 1100 kWh (12 s),
        2e appel servi du cache
      Activé via HQ_CAPTCHA_KEY (2captcha) dans .env.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 3 files +29 −24
    4. Simon-Pierre Boucher · 1 file +1 −3
    5. Fiche : estimation du coût d electricite Hydro-Quebec (a la demande)
      …
      - louka/hydro.py : parcours PUBLIC rétro-conçu de l outil « Estimer les coûts
        d électricité à une résidence » — 2 étapes (lieu-consommation -> estimation)
        sur services-cl.solutions.hydroquebec.com, jeton reCAPTCHA v2 via solveur
        enfichable (2captcha/CapSolver, clé HQ_CAPTCHA_KEY), sortie par proxy
        résidentiel CA (Oxylabs/Bright Data), cache 6 mois data/hydro.db ; sans clé
        captcha -> {disponible:false} et bloc masqué (jamais d estimation inventée)
      - GET /api/hydro?adresse= ; bloc fiche à la demande (bouton, 1 captcha/appel)
        affichant le coût mensuel et annuel estimés
      
      Activation : définir HQ_CAPTCHA_KEY (+ HQ_CAPTCHA_PROVIDER) dans .env.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 7 files +329
    6. Cartes : lignes de métro/REM aux couleurs officielles + transit hors ligne
      …
      - MetroLignes.tsx : couche Ka Maps (useKaMap) qui trace metro-lignes.geojson
        (lignes verte/orange/jaune/bleue + REM, extraites d OSM avec leurs couleurs
        officielles, liseré blanc de lisibilité) sur la carte de recherche, la
        vue carte et la carte 3D de la fiche
      - commerces : transit servi par data/transit.db (extrait OSM pré-calculé,
        37 237 arrêts de bus + 75 stations de métro + 57 REM + 106 gares au
        Québec — les miroirs Overpass refusent l IP du cluster) ; ajoute Station
        REM et Gare de train au bloc Commerces et transport
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 8 files +102 −3
    7. Fiche : bloc Commerces et transport (Mapbox Search Box + cache POI/OSM)
      …
      - louka/commerces.py : point de vente le plus proche de 14 grandes bannières
        (Costco, Walmart, Metro, IGA, Maxi, Super C, Provigo, Canadian Tire,
        Dollarama, SAQ, Pharmaprix, Jean Coutu, Home Depot, RONA) via l API Mapbox
        Search Box (jeton public kamaps, validation du nom retourné, anti
        « Station Métro »), cache par cellule ~1 km TTL 30 j ; station de métro et
        arrêt de bus les plus proches repris du cache POI du projet (repli
        Overpass) ; GET /api/commerces
      - bloc fiche : pastilles SVG monogrammes aux couleurs des bannières,
        nom du point de vente et distance — métro/bus en tête
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 7 files +381
    8. Fiche : qualité de l air (RSQAQ/PST) + essence à proximité (gazquebec.ca)
      …
      - louka/air.py : agrégats annuels par station du RSQAQ (MELCCFP) — horaires
        2024-2025 (PM2.5, NO2, O3, SO2, CO) + séquentielles PST/PM10 (<LD -> LD/2),
        data/air.db minuscule, station la plus proche ≤ 60 km ; bloc fiche avec
        badge global et barres vs repères OMS 2021 / norme RAA (PST 60 µg/m³)
      - louka/gaz.py : copie locale des ~2 450 stations de gazquebec.ca (prix
        Régulier/Super/Diesel, TTL 4 h, auto-refresh au lookup) ; bloc fiche avec
        KPI (stations, médiane du secteur, meilleur prix) et tableau des stations
        les plus proches, la moins chère mise en évidence
      - run.py air-refresh / gaz-refresh, GET /api/air et /api/gaz
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 10 files +577
    9. Quartier : criminalité SPVM détaillée par catégorie (12 mois, tendance)
      …
      _crime_mtl ventile désormais les actes par catégorie (vol dans/sur véhicule,
      introduction, vol de véhicule, méfait, vol qualifié, infractions mortelles) ;
      le bloc quartier affiche des barres par catégorie avec la variation vs les
      12 mois précédents (flèches chiffrées, jamais la couleur seule).
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 4 files +64 −11
    10. Risque d inondation (BDZI) + Registre des loyers v2 (visuel)
      …
      - louka/inondation.py : base locale data/inondation.db construite du GeoPackage
        BDZI officiel (25 k polygones éclatés + R*Tree, couverture Carto_ZI_S),
        lookup point-dans-polygone shapely (0-40 ms), statuts en_zone / a_proximite
        (≤100 m) / hors_zone / non_cartographie ; run.py inondation-build,
        GET /api/inondation — bloc fiche avec badge de sévérité (grand courant
        0-20 ans = élevé, faible courant 20-100 ans = modéré) et rappel que la
        cartographie officielle fait foi (CMM non couverte par la BDZI)
      - Registre des loyers v2 : tuiles KPI (volume, médiane secteur, médiane même
        nombre de chambres), bande de position p10-p90/boîte p25-p75/médiane vs le
        loyer demandé, barres des médianes par chambres (celle de l annonce
        surlignée + étiquette), date de la valeur = année du loyer (mois seulement
        si le bail débute la même année), quartiles côté API
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 10 files +451 −26
    11. Registre des loyers : extraction pancanadienne (57 433 déclarations géocodées) + bloc fiche
      …
      - louka/rdl.py : balayage par boîtes de l API publique de registre-des-loyers.ca
        (subdivision récursive sur erreur ou volume suspect), base séparée data/rdl.db,
        requête de proximité (bbox + haversine) avec médianes globale/récente/par chambres
      - run.py rdl + GET /api/rdl?lat&lng&radius
      - fiche : bloc « Registre des loyers » sous l analyse de prix — médiane du secteur,
        écart du loyer demandé vs les déclarations du même nombre de chambres,
        8 déclarations les plus proches avec la date de la valeur (année du loyer,
        mois si le bail débute la même année), crédit Vivre en ville
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 8 files +398
    12. [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 · 1 file +19 −7
    13. Simon-Pierre Boucher · 4 files +720 −12
    14. ka-agent : balise analytics KA (collect vers administration-ka.com)
      …
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +2
    15. tri_logis : réécriture pour le nouveau site trilogis.ca (Next.js/Supabase) + fenêtre syncs_since_h sur /api/stats
      …
      - tri_logis : l ancien site statique tri-logis.ca a migré vers trilogis.ca
        (Next.js App Router + Supabase) — 23 synchros à found=0. Le connecteur lit
        désormais le payload RSC rendu serveur de /a-louer (tableau "units" JSON
        complet : prix, statut, date de dispo, notation n½, secteur, GPS,
        inclusions) et la galerie signée de chaque fiche /a-louer/<slug>
        (bucket privé property-media, tokens ~7 j re-signés à chaque sync).
        Périmètre : résidentiel longue durée seulement (commercial exclu).
        Sync de test : found=51, added=51.
      - web.py /api/stats : paramètre optionnel syncs_since_h (fenêtre en heures
        pour recent_syncs, LIMIT 4000, repli sur les 20 dernières si <20 dans la
        fenêtre) — le moniteur central api-ka voit enfin toute la fenêtre de 2 h
        au lieu de 20 entrées (~11 min), fin des fausses alertes stale.
        Sans paramètre : comportement inchangé.
      - Diagnostics sans changement de code : courtemanche, place_florimay et
        atlas_immo retournent 0 annonce parce que les sites n affichent réellement
        aucune disponibilité (vérifié en live) — connecteurs sains.
      
      Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
      Simon-Pierre Boucher · 2 files +222 −190
    16. court terme : 2e vague — 5 connecteurs (Expedia, Hipcamp, Glamping Hub, Parcs Canada, Sinistar, Corporate Stays) + 3 sources fermées documentées
      …
      - expedia : SSR + rendu Scrapfly ASP (pile Vrbo), 13 destinations QC × 2 tris
      - hipcamp : GraphQL public (LandsSearch bbox QC + détail camper), ~350 terrains
      - glampinghub : endpoint AJAX ouvert, 208 fiches QC, prix CAD seulement
      - parcscanada : API GoingToCamp (reservation.pc.gc.ca), oTENTik/Ôasis/MicrOcube
        des 12 terrains québécois, prix via feeDetails
      - sinistar : index Algolia public prod_housings (state:QC + quadtree bbox),
        ~5 600 hébergements de relogement, pas de prix public (assumé)
      - corporatestays : API REST WordPress properties, 47 meublés MTL/QC
      - tripadvisor (vertical locations fermé nov. 2024), sonder (liquidée nov. 2025,
        devenue affilié Booking), blueground (aucun marché QC) : disabled documentés
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 9 files +1,396
  3. Sat, Aug 22, 2026 9

    1. airbnb : polygone frontière Québec (élagage cellules + filtre cartes) et budget mélangé
      …
      Le bbox provincial englobe l'est de l'Ontario, le nord des É.-U. et le NB :
      4 857 annonces hors province (Ottawa & cie étiquetées « Outaouais ») ont été
      récoltées puis purgées. QC_POLY filtre désormais les cartes et élague les
      cellules entièrement hors Québec ; l'ordre des cellules est mélangé à chaque
      run pour que les cellules restantes tournent, budget par défaut 900 → 1200.
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 1 file +52 −6
    2. court terme : 12 connecteurs supplémentaires + Airbnb réécrit en quadrillage carte (quadtree)
      …
      - airbnb : couverture provinciale robuste via search_by_map + bbox — subdivision
        en 4 quand une cellule sature (15 cursors ≈ 270 résultats), région déduite des
        coordonnées (centroïde le plus proche), dédoublonnage par room id.
        Env : LOUKA_AIRBNB_PAGES / LOUKA_AIRBNB_BUDGET / LOUKA_AIRBNB_DEPTH.
      - Nouveaux connecteurs QC : monsieurchalets, wechalet, chaletsalouer,
        chaletsarabais, mcal, qldc, rsvpchalets, sepaq, bonjourquebec (CITQ), vrbo.
      - chaletsquebec (domaine mort), chaletsdirect, locationschalets (redirigé)
        livrés désactivés.
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 13 files +2,688 −70
    3. Simon-Pierre Boucher · 24 files +2,844 −2
    4. apartments_com : acteur Apify maison ka-apartments-com (toute la province via Bright Data) + enrichissement PDP fb_marketplace
      …
      - nouvel acteur actors/ka-apartments-com : recherche /qc/ paginée (arrêt sur
        retombée page 1 via <title>), fiches détail en français (GPS, description,
        plans d'unités dédoublonnés, commodités, galerie), déblocage Akamai délégué
        au Web Unlocker Bright Data (curl_cffi/Scrapfly/Oxylabs → 403)
      - connecteur louka/connectors/apartments_com.py : 1 annonce = 1 propriété,
        prix « à partir de » (minimum des plans), bedrooms/bathrooms = minimum,
        cache détail 30 j, cadence LOUKA_APTS_INTERVAL_H (12 h) avec ré-émission
        des actives entre deux runs — 615 propriétés QC au premier passage
      - fb_marketplace : acteur 0.1.3 (adresse civique, beds/sdb, commodités,
        disponibilité, walk/transit/bike scores, visite virtuelle) + PAYLOAD_VERSION
        pour re-visiter progressivement le cache, filtre hors-Québec state+bbox GPS
      - sources.json : apartments_com passe de « non connectable » à actif
      - docs connecteurs régénérées (218 fiches)
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 230 files +1,672 −756
    5. fb_marketplace : acteur Apify maison ka-fb-marketplace (33 villes, tout le Québec)
      …
      Remplace la chaîne Scrapfly par un acteur Apify maison (curl_cffi sans rendu
      JS, proxy Oxylabs résidentiel CA via proxyUrlTemplate) : recherche 116 URLs
      (10 grandes villes × 7 tranches de prix + 23 régions par ID Marketplace),
      fiches détail (GPS, description, statut) et galerie complète via le
      MediaViewer préchargé. Filtre hors-Québec à deux niveaux : state du
      reverse_geocode dès la recherche + filet bbox GPS côté connecteur (FB glisse
      des suggestions d'autres provinces dans le flux public). Coût ~100× moindre.
      
      Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
      Simon-Pierre Boucher · 227 files +2,615 −2,173
    6. Simon-Pierre Boucher · 2 files +10 −8
    7. Simon-Pierre Boucher · 2 files +17 −14
    8. Simon-Pierre Boucher · 1 file +1 −1
Menu

Theme