SPB Git

spb/lou-ka

Public

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

Lou-Ka — agrégateur de logements à louer (Québec, Lévis, Grand Montréal)

Plateforme complète : 68 connecteurs de gestionnaires immobiliers, schéma
standardisé avec détection de changements (hash), API FastAPI, frontend
React/Vite PWA (design éditorial sharp, thème clair), déployée sur
www.lou-ka.com avec resynchronisation horaire.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Aug 6, 2026) Browse files

96 changed files +16,690 −0

96 changed files
added .gitignore +8 −0
@@ -0,0 +1,8 @@
1 +.env
2 +.venv/
3 +__pycache__/
4 +*.pyc
5 +data/louka.db
6 +frontend/node_modules/
7 +frontend/dist/
8 +.DS_Store
added README.md +179 −0
@@ -0,0 +1,179 @@
1 +<div align="center">
2 +
3 +# Lou·Ka
4 +
5 +### Tous les logements à louer du Québec. Un seul endroit.
6 +
7 +**[www.lou-ka.com](https://www.lou-ka.com)**
8 +
9 +![Python](https://img.shields.io/badge/Python-3.14-141814?style=for-the-badge&logo=python&logoColor=d9f26b)
10 +![FastAPI](https://img.shields.io/badge/FastAPI-API-141814?style=for-the-badge&logo=fastapi&logoColor=d9f26b)
11 +![React](https://img.shields.io/badge/React_18-Vite_+_TS-141814?style=for-the-badge&logo=react&logoColor=d9f26b)
12 +![SQLite](https://img.shields.io/badge/SQLite-storage-141814?style=for-the-badge&logo=sqlite&logoColor=d9f26b)
13 +![PWA](https://img.shields.io/badge/PWA-mobile_ready-141814?style=for-the-badge&logoColor=d9f26b)
14 +
15 +![Sources](https://img.shields.io/badge/sources_recens%C3%A9es-74-1c5c41?style=flat-square)
16 +![Connecteurs](https://img.shields.io/badge/connecteurs_actifs-68-1c5c41?style=flat-square)
17 +![Annonces](https://img.shields.io/badge/annonces_agr%C3%A9g%C3%A9es-4000%2B-1c5c41?style=flat-square)
18 +![Couverture](https://img.shields.io/badge/couverture-Qu%C3%A9bec_·_L%C3%A9vis_·_Grand_Montr%C3%A9al-1c5c41?style=flat-square)
19 +
20 +*Agrégateur indépendant de logements locatifs — chaque annonce avec toutes ses photos,
21 +ses détails standardisés, et un lien direct vers l'annonce originale du gestionnaire.
22 +Toujours à jour, automatiquement.*
23 +
24 +</div>
25 +
26 +---
27 +
28 +## Pourquoi Lou-Ka ?
29 +
30 +Chercher un appartement au Québec, c'est ouvrir 70 sites web différents — chacun avec sa
31 +propre navigation, ses propres filtres, son propre format. **Lou-Ka retourne le problème** :
32 +un connecteur dédié par gestionnaire immobilier visite chaque site, normalise chaque annonce
33 +vers un schéma unique, et détecte les changements en continu.
34 +
35 +> Les sites d'agences n'offrent pas de webhooks. Lou-Ka reproduit l'équivalent :
36 +> **synchronisation périodique + hash de contenu** → ajouts, mises à jour et retraits
37 +> détectés automatiquement. Une annonce qui disparaît du site source disparaît de Lou-Ka.
38 +
39 +## L'architecture en 30 secondes
40 +
41 +```mermaid
42 +flowchart LR
43 + subgraph Sources["74 gestionnaires immobiliers"]
44 + S1["Logisco · Cogir · CAPREIT<br/>Immostar · DMA · Laberge<br/>Akelius · Devimco · Mondev<br/>… 68 connecteurs actifs"]
45 + end
46 + subgraph LouKa["Lou-Ka"]
47 + C["Connecteurs<br/><i>1 adaptateur / site</i>"] --> N["Normalisation<br/><i>schéma Listing unique</i>"]
48 + N --> D[("SQLite<br/>hash + diff")]
49 + D --> A["API FastAPI<br/>/api/listings · /api/facets"]
50 + A --> F["React 18 + Vite<br/>PWA mobile · thème clair"]
51 + end
52 + W["⏱ Watcher horaire<br/>(PM2)"] -.-> C
53 + S1 --> C
54 + F --> U["🔑 Locataire"]
55 +```
56 +
57 +| Couche | Rôle | Fichiers |
58 +|---|---|---|
59 +| **Connecteurs** | 1 module Python par gestionnaire : HTML rendu serveur, API JSON internes (Building Stack, RealVuu, Planpoint, Rentsync, source.immo, JetEngine…), ou Firecrawl pour les sites derrière Cloudflare | `louka/connectors/*.py` |
60 +| **Schéma** | `Listing` standardisé : adresse, secteur, ville, type (3½…), prix, disponibilité, commodités, **toutes les images** | `louka/schema.py` |
61 +| **Diff engine** | Upsert par hash de contenu — nouvelle / modifiée / disparue (désactivée) | `louka/db.py` |
62 +| **API** | Filtres ville / secteur / taille / prix / gestionnaire / recherche, facettes, stats, déclencheur de sync | `louka/web.py` |
63 +| **Frontend** | Design « éditorial sharp » : Space Grotesk, ombres décalées, accent lime, ticker temps réel, bottom sheet mobile, galeries photos, PWA installable | `frontend/` |
64 +
65 +## Démarrage rapide
66 +
67 +```bash
68 +git clone https://github.com/spboucher-ai/lou-ka.git && cd lou-ka
69 +
70 +# Backend
71 +python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
72 +
73 +# Frontend
74 +cd frontend && npm install && npm run build && cd ..
75 +
76 +# (optionnel) sites JavaScript/anti-bot
77 +echo "FIRECRAWL_API_KEY=fc-votre-cle" > .env
78 +
79 +# Ingestion puis service
80 +.venv/bin/python run.py sync # toutes les sources (ou: run.py sync logisco msi)
81 +.venv/bin/python run.py serve 8080 # → http://localhost:8080
82 +.venv/bin/python run.py watch 60 # resynchronisation en boucle (minutes)
83 +```
84 +
85 +## Ajouter un gestionnaire (≈ 30 lignes)
86 +
87 +L'enregistrement est **auto-découvrant** : déposez un module dans `louka/connectors/`,
88 +c'est tout — aucun fichier partagé à modifier.
89 +
90 +```python
91 +# louka/connectors/mon_agence.py
92 +from ..schema import Listing, infer_city, normalize_unit_type, parse_price
93 +from .base import BaseConnector
94 +
95 +class MonAgenceConnector(BaseConnector):
96 + source_id = "mon_agence"
97 +
98 + def fetch(self) -> list[Listing]:
99 + html = self.get("https://mon-agence.ca/logements").text # throttlé, poli
100 + # ... parser les cartes, les fiches, les photos ...
101 + return [Listing(
102 + source=self.source_id, external_id="123",
103 + url="https://mon-agence.ca/logement/123",
104 + title="555, avenue Exemple", sector="Limoilou",
105 + city=infer_city("Limoilou"), unit_type=normalize_unit_type("4 1/2"),
106 + price=parse_price("1 250 $ / mois"), images=[...],
107 + )]
108 +```
109 +
110 +Puis : `.venv/bin/python run.py sync mon_agence` — et l'annonce apparaît sur le site,
111 +avec sa fiche, sa galerie et son lien source. Ajoutez l'entrée correspondante dans
112 +`data/sources.json` pour la page **Sources**.
113 +
114 +## API
115 +
116 +| Endpoint | Description |
117 +|---|---|
118 +| `GET /api/listings?city=&sector=&unit_type=&source=&price_min=&price_max=&q=` | Recherche filtrée, triée par prix |
119 +| `GET /api/listings/{uid}` | Fiche complète (toutes les images, commodités, source) |
120 +| `GET /api/facets` | Valeurs distinctes pour construire les filtres |
121 +| `GET /api/sources` | Registre des 74 gestionnaires + compteurs + dernière sync |
122 +| `GET /api/stats` | Totaux par région, loyer moyen, journal de synchronisation |
123 +| `POST /api/sync` | Déclenche une synchronisation en arrière-plan |
124 +
125 +## Couverture
126 +
127 +**Ville de Québec & Lévis** — Logisco, Cogir, Groupe Laberge, Immostar, DMA/Locago,
128 +Groupe Dallaire, Trudel, Immeubles Roussin, Immeubles Simard, MSI, Gestipro, Logisma,
129 +Lafrance & Mathieu, SIB, SDG, SGIQ, GIM Côté, Logisbourg, Bribourg, Paul-E. Richard,
130 +Headway, Contraste, Appartements Urbains, Picard, Brochu, GParadis, CAPREIT, Lokalia,
131 +Immoappart, OK Louer, et une douzaine de complexes (Huma, Le Clif, Terra, La Klé,
132 +Sentinelle, Rivero, Viridi, Quartier les Éléments…).
133 +
134 +**Grand Montréal** — Akelius, InterRent, Boardwalk, Minto, MetCap, Realstar, Hazelview,
135 +Groupe Copley, Cromwell, Lynk/Olymbec, Trylon, Plan A, Lofts MTL, Axia, Mondev, Devimco,
136 +Collection Équinoxe (Batimo/EMD), Progim, Rentalys, UTILE, Werkliv, 1 Square Phillips,
137 +Firma, Le Domaine, Beaudoin, Denux, Gestion Montréal, Nid d'Amour, SHDM…
138 +
139 +Chaque source non-connectable est **documentée avec sa raison** dans `data/sources.json`
140 +(ex. : aucun prix affiché, inventaire vide, site placeholder).
141 +
142 +## Production
143 +
144 +Déployé sous **PM2** (3 processus) derrière **ngrok** :
145 +
146 +```
147 +lou-ka-web .venv/bin/python run.py serve 8095 # API + frontend
148 +lou-ka-sync .venv/bin/python run.py watch 60 # resync horaire
149 +lou-ka-ngrok ngrok http --url=www.lou-ka.com 8095 # tunnel
150 +```
151 +
152 +Philosophie d'exploitation : **on ne pousse que le code — le serveur maintient ses
153 +données lui-même.**
154 +
155 +## Principes
156 +
157 +1. **Politesse** — délai ≥ 0,5 s entre requêtes, garde-fous de crawl, User-Agent identifié.
158 +2. **Fidélité** — aucun prix inventé : si la source n'affiche pas de prix, `price = null`.
159 +3. **Traçabilité** — chaque fiche renvoie vers l'annonce originale du gestionnaire.
160 +4. **Robustesse** — un connecteur qui casse n'affecte jamais les autres (auto-découverte
161 + tolérante, try/except par annonce, journal `sync_log`).
162 +
163 +---
164 +
165 +<div align="center">
166 +
167 +## Auteur
168 +
169 +**Simon-Pierre Boucher**
170 +
171 +[![Email](https://img.shields.io/badge/contact@spboucher.ai-141814?style=for-the-badge&logo=minutemailer&logoColor=d9f26b)](mailto:contact@spboucher.ai)
172 +[![GitHub](https://img.shields.io/badge/spboucher--ai-141814?style=for-the-badge&logo=github&logoColor=d9f26b)](https://github.com/spboucher-ai)
173 +
174 +*Conçu, construit et déployé en une journée — de la recherche de marché
175 +(74 gestionnaires recensés et vérifiés) au produit en production.*
176 +
177 +© 2026 Simon-Pierre Boucher — tous droits réservés.
178 +
179 +</div>
added data/sources.json +745 −0
@@ -0,0 +1,745 @@
1 +{
2 + "_comment": "Lou-Ka — Registre des sources (agences/gestionnaires immobiliers, Québec & Lévis). Auteur : Simon-Pierre Boucher — contact@spboucher.ai",
3 + "sources": [
4 + {
5 + "id": "lafrance_mathieu",
6 + "name": "Lafrance & Mathieu",
7 + "url": "https://lafrance-mathieu.com",
8 + "listing_url": "https://lafrance-mathieu.com/louer-appartement-quebec",
9 + "sectors": "Beauport, Charlesbourg, Limoilou, St-Roch, Lévis, Val-Bélair, Loretteville, L'Ancienne-Lorette, St-Augustin",
10 + "connector": "lafrance_mathieu",
11 + "status": "actif",
12 + "region": "Québec"
13 + },
14 + {
15 + "id": "msi",
16 + "name": "MSI Gestion immobilière",
17 + "url": "https://www.msimmobiliers.com",
18 + "listing_url": "https://www.msimmobiliers.com/appartements-a-louer/quebec",
19 + "sectors": "Ville de Québec, Lévis, Limoilou, Beauport, Ste-Foy, Vanier, St-Nicolas",
20 + "connector": "msi",
21 + "status": "actif",
22 + "region": "Québec"
23 + },
24 + {
25 + "id": "logisco",
26 + "name": "Logisco",
27 + "url": "https://logisco.com/fr",
28 + "listing_url": "https://logisco.com/fr/appartements-a-louer",
29 + "sectors": "Québec (Ste-Foy, Val-Bélair, Loretteville, Vanier, St-Augustin) + Lévis (St-Romuald, St-David, St-Nicolas, Desjardins)",
30 + "connector": "logisco",
31 + "status": "actif",
32 + "region": "Québec"
33 + },
34 + {
35 + "id": "laberge",
36 + "name": "Groupe Laberge",
37 + "url": "https://www.laberge.qc.ca",
38 + "listing_url": "https://www.laberge.qc.ca/recherche",
39 + "sectors": "Ste-Foy, Beauport, Vanier, L'Ancienne-Lorette, Limoilou",
40 + "connector": "laberge",
41 + "status": "actif",
42 + "region": "Québec"
43 + },
44 + {
45 + "id": "cogir",
46 + "name": "Cogir Immobilier",
47 + "url": "https://www.cogir.net",
48 + "listing_url": "https://www.cogir.net/gestion-immeubles-residentiels.html",
49 + "sectors": "Québec (Le Bacc, Loretteville, Père-Lelièvre...)",
50 + "connector": "cogir",
51 + "status": "actif",
52 + "region": "Québec"
53 + },
54 + {
55 + "id": "immostar",
56 + "name": "Immostar",
57 + "url": "https://immostar.ca",
58 + "listing_url": "https://immostaralouer.ca",
59 + "sectors": "Ste-Foy/blvd Laurier, Cap-Rouge, Lévis (Loges St-Nicolas), Wendake",
60 + "connector": "immostar",
61 + "status": "actif",
62 + "region": "Québec"
63 + },
64 + {
65 + "id": "dma_locago",
66 + "name": "DMA / Locago (Douville, Moffet & Associés)",
67 + "url": "https://locago.ca",
68 + "listing_url": "https://locago.ca",
69 + "sectors": "Ste-Foy, Vanier, Lebourgneuf, Charlesbourg, Beauport",
70 + "connector": "dma_locago",
71 + "status": "actif",
72 + "region": "Québec"
73 + },
74 + {
75 + "id": "groupe_dallaire",
76 + "name": "Groupe Dallaire (Faubourg du Moulin)",
77 + "url": "https://faubourgdumoulin.ca",
78 + "listing_url": "https://faubourgdumoulin.ca/disponibilite",
79 + "sectors": "Québec (Alizé I-II)",
80 + "connector": "groupe_dallaire",
81 + "status": "actif",
82 + "region": "Québec"
83 + },
84 + {
85 + "id": "trudel",
86 + "name": "Trudel (Fleur de Lys, LGC)",
87 + "url": "https://trudel.ca",
88 + "listing_url": "https://18juillet.trudel.ca",
89 + "sectors": "Vanier/Fleur de Lys, Charlesbourg",
90 + "connector": "trudel",
91 + "status": "actif",
92 + "region": "Québec"
93 + },
94 + {
95 + "id": "roussin",
96 + "name": "Immeubles Roussin",
97 + "url": "https://immeublesroussin.com",
98 + "listing_url": "https://immeublesroussin.com",
99 + "sectors": "Sainte-Foy, Lévis, Beauport",
100 + "connector": "roussin",
101 + "status": "actif",
102 + "region": "Québec"
103 + },
104 + {
105 + "id": "simard",
106 + "name": "Immeubles Simard",
107 + "url": "https://immeublessimard.com",
108 + "listing_url": "https://immeublessimard.com/a-louer/categorie/appartement",
109 + "sectors": "Québec (Grande Allée, centre-ville)",
110 + "connector": "simard",
111 + "status": "actif",
112 + "region": "Québec"
113 + },
114 + {
115 + "id": "gestipro",
116 + "name": "Gestipro",
117 + "url": "https://gestipro.info",
118 + "listing_url": "https://gestipro.info/a-louer",
119 + "sectors": "Québec + Lévis",
120 + "connector": "gestipro",
121 + "status": "actif",
122 + "region": "Québec"
123 + },
124 + {
125 + "id": "logisma",
126 + "name": "Logisma",
127 + "url": "https://logisma.ca",
128 + "listing_url": "https://logisma.ca",
129 + "sectors": "Ville de Québec",
130 + "connector": "logisma",
131 + "status": "actif",
132 + "region": "Québec"
133 + },
134 + {
135 + "id": "sibelanger",
136 + "name": "Société immobilière Bélanger",
137 + "url": "https://sibelanger.com",
138 + "listing_url": "https://sibelanger.com",
139 + "sectors": "Québec + Lévis",
140 + "connector": "sibelanger",
141 + "status": "actif",
142 + "region": "Québec"
143 + },
144 + {
145 + "id": "sdg",
146 + "name": "SDG Immobilier",
147 + "url": "https://www.sdgimmobilier.ca",
148 + "listing_url": "https://www.sdgimmobilier.ca",
149 + "sectors": "Charlesbourg, Ste-Foy, Limoilou, Charny",
150 + "connector": "sdg",
151 + "status": "actif",
152 + "region": "Québec"
153 + },
154 + {
155 + "id": "sgiq",
156 + "name": "SGIQ (Société de gestion immobilière du Québec)",
157 + "url": "https://gestionimmobilierequebec.com",
158 + "listing_url": "https://gestionimmobilierequebec.com/immeubles",
159 + "sectors": "Limoilou, St-Sauveur, Ste-Foy, Sillery",
160 + "connector": "sgiq",
161 + "status": "actif",
162 + "region": "Québec"
163 + },
164 + {
165 + "id": "gimcote",
166 + "name": "GIM Côté",
167 + "url": "https://gimcote.com",
168 + "listing_url": "https://gimcote.com/property-type/appartement",
169 + "sectors": "Ste-Foy, Limoilou/Charlesbourg, Lévis",
170 + "connector": "gimcote",
171 + "status": "actif",
172 + "region": "Québec"
173 + },
174 + {
175 + "id": "logisbourg",
176 + "name": "Logisbourg",
177 + "url": "https://www.logisbourg.com",
178 + "listing_url": "https://www.logisbourg.com/appartements-disponibles.asp",
179 + "sectors": "Charlesbourg, Lebourgneuf, Beauport, Cité-Limoilou, Ste-Foy",
180 + "connector": "logisbourg",
181 + "status": "actif",
182 + "region": "Québec"
183 + },
184 + {
185 + "id": "bribourg",
186 + "name": "Bribourg",
187 + "url": "https://bribourg.com",
188 + "listing_url": "https://bribourg.com/Immeubles.php",
189 + "sectors": "Charlesbourg, Vanier, Beauport",
190 + "connector": "bribourg",
191 + "status": "actif",
192 + "region": "Québec"
193 + },
194 + {
195 + "id": "per",
196 + "name": "Les Immeubles Paul-E. Richard",
197 + "url": "https://immeublesper.com",
198 + "listing_url": "https://immeublesper.com",
199 + "sectors": "Limoilou, Charlesbourg, Beauport",
200 + "connector": "per",
201 + "status": "actif",
202 + "region": "Québec"
203 + },
204 + {
205 + "id": "headway",
206 + "name": "La Corporation Headway",
207 + "url": "https://www.headwayltee.com",
208 + "listing_url": "https://www.headwayltee.com/logements-a-louer/levis",
209 + "sectors": "Vanier, Ste-Foy, Charlesbourg, Lévis",
210 + "connector": "headway",
211 + "status": "actif",
212 + "region": "Québec"
213 + },
214 + {
215 + "id": "contraste",
216 + "name": "Contraste Immobilier",
217 + "url": "https://contrasteimmobilier.ca",
218 + "listing_url": "https://contrasteimmobilier.ca",
219 + "sectors": "Beauport, Limoilou, Ste-Foy, Val-Bélair, Lévis, St-Nicolas, St-Romuald",
220 + "connector": "contraste",
221 + "status": "actif",
222 + "region": "Québec"
223 + },
224 + {
225 + "id": "app_urbains",
226 + "name": "Appartements Urbains",
227 + "url": "https://www.appartementsurbains.ca",
228 + "listing_url": "https://www.appartementsurbains.ca",
229 + "sectors": "Ste-Foy, Montcalm, Limoilou, Loretteville, Lévis",
230 + "connector": "app_urbains",
231 + "status": "actif",
232 + "region": "Québec"
233 + },
234 + {
235 + "id": "picard",
236 + "name": "Picard Immobilier",
237 + "url": "https://picardimmobilier.net",
238 + "listing_url": "https://picardimmobilier.net/logement/arrondissement=charny",
239 + "sectors": "Charny, Les Saules, Ste-Foy, Beauport, Limoilou, Loretteville, Vieux-Québec, Montcalm",
240 + "connector": "picard",
241 + "status": "actif",
242 + "region": "Québec"
243 + },
244 + {
245 + "id": "brochu",
246 + "name": "Groupe Immobilier Brochu",
247 + "url": "https://groupeimmobilierbrochu.com",
248 + "listing_url": "https://groupeimmobilierbrochu.com",
249 + "sectors": "Lévis (St-Romuald, Charny, St-Nicolas), Les Saules",
250 + "connector": "brochu",
251 + "status": "actif",
252 + "region": "Québec"
253 + },
254 + {
255 + "id": "gparadis",
256 + "name": "GParadis",
257 + "url": "https://gparadis.com",
258 + "listing_url": "https://gparadis.com",
259 + "sectors": "Montcalm, St-Sauveur, St-Roch, Limoilou, Vieux-Québec, Ste-Foy, Duberger, Lévis",
260 + "connector": "gparadis",
261 + "status": "actif",
262 + "region": "Québec"
263 + },
264 + {
265 + "id": "lokalia",
266 + "name": "Espaces Lokalia",
267 + "url": "https://www.espaceslokalia.ca",
268 + "listing_url": "https://www.espaceslokalia.ca/immeuble/vivaxces-le-nicolas",
269 + "sectors": "Lévis (Vivaxcès Le Nicolas)",
270 + "connector": "lokalia",
271 + "status": "actif",
272 + "region": "Québec"
273 + },
274 + {
275 + "id": "capreit",
276 + "name": "CAPREIT",
277 + "url": "https://www.capreit.ca",
278 + "listing_url": "https://www.capreit.ca/fr/appartements-a-louer/ville-de-quebec-qc/appartements-le-samuel-holland",
279 + "sectors": "Ville de Québec (Samuel-Holland)",
280 + "connector": "capreit",
281 + "status": "actif",
282 + "region": "Québec"
283 + },
284 + {
285 + "id": "immomarketing",
286 + "name": "IMMOMARKETING (Immoappart)",
287 + "url": "https://immoappart.ca",
288 + "listing_url": "https://immoappart.ca/appartements-a-louer",
289 + "sectors": "Lebourgneuf, Saint-Roch",
290 + "connector": "immomarketing",
291 + "status": "actif",
292 + "region": "Québec"
293 + },
294 + {
295 + "id": "presquile",
296 + "name": "Logis Presqu'Île",
297 + "url": "https://logispresquile.ca",
298 + "listing_url": "https://logispresquile.ca",
299 + "sectors": "Presqu'île / St-Nicolas, près de Ste-Foy",
300 + "connector": null,
301 + "status": "non connectable — aucun prix/disponibilité publié sur le site",
302 + "region": "Québec"
303 + },
304 + {
305 + "id": "brio",
306 + "name": "Les Immeubles Brio",
307 + "url": "https://immeublesbrio.com",
308 + "listing_url": "https://immeublesbrio.com/appartements-a-louer-val-belair",
309 + "sectors": "Val-Bélair, Neufchâtel, Loretteville",
310 + "connector": "brio",
311 + "status": "actif",
312 + "region": "Québec"
313 + },
314 + {
315 + "id": "oklouer",
316 + "name": "OK Louer (location temporaire)",
317 + "url": "https://www.oklouer.com",
318 + "listing_url": "https://www.oklouer.com/logements/limoilou",
319 + "sectors": "Limoilou, Charlesbourg/Beauport, Lac-Beauport",
320 + "connector": "oklouer",
321 + "status": "actif",
322 + "region": "Québec"
323 + },
324 + {
325 + "id": "elements",
326 + "name": "Quartier les Éléments",
327 + "url": "https://www.quartierleselements.com",
328 + "listing_url": "https://www.quartierleselements.com",
329 + "sectors": "Lévis (St-Romuald)",
330 + "connector": "elements",
331 + "status": "actif",
332 + "region": "Québec"
333 + },
334 + {
335 + "id": "huma",
336 + "name": "HUMĀ Condos locatifs",
337 + "url": "https://humalevis.com",
338 + "listing_url": "https://humalevis.com",
339 + "sectors": "Lévis (St-Romuald)",
340 + "connector": "huma",
341 + "status": "actif",
342 + "region": "Québec"
343 + },
344 + {
345 + "id": "leclif",
346 + "name": "Le Clif",
347 + "url": "https://leclif.ca",
348 + "listing_url": "https://leclif.ca",
349 + "sectors": "Charlesbourg",
350 + "connector": "leclif",
351 + "status": "actif",
352 + "region": "Québec"
353 + },
354 + {
355 + "id": "terra",
356 + "name": "Terra Condos locatifs",
357 + "url": "https://www.terracondolocatif.ca",
358 + "listing_url": "https://www.terracondolocatif.ca",
359 + "sectors": "Lévis (Desjardins)",
360 + "connector": "terra",
361 + "status": "actif",
362 + "region": "Québec"
363 + },
364 + {
365 + "id": "rivero",
366 + "name": "Le Rivero",
367 + "url": "https://www.lerivero.ca",
368 + "listing_url": "https://www.lerivero.ca",
369 + "sectors": "Québec (rivière St-Charles)",
370 + "connector": "rivero",
371 + "status": "actif",
372 + "region": "Québec"
373 + },
374 + {
375 + "id": "viridi",
376 + "name": "Le Viridi",
377 + "url": "https://condosleviridi.ca",
378 + "listing_url": "https://condosleviridi.ca",
379 + "sectors": "Québec",
380 + "connector": "viridi",
381 + "status": "actif",
382 + "region": "Québec"
383 + },
384 + {
385 + "id": "lakle",
386 + "name": "La Klé",
387 + "url": "https://lakle.ca",
388 + "listing_url": "https://lakle.ca",
389 + "sectors": "Québec (Cité Verte)",
390 + "connector": "lakle",
391 + "status": "actif",
392 + "region": "Québec"
393 + },
394 + {
395 + "id": "sentinelle",
396 + "name": "La Sentinelle (Groupe Immobilier Brochu)",
397 + "url": "https://lasentinellelevis.com",
398 + "listing_url": "https://lasentinellelevis.com",
399 + "sectors": "Vieux-Lévis",
400 + "connector": "sentinelle",
401 + "status": "actif",
402 + "region": "Québec"
403 + },
404 + {
405 + "id": "legc",
406 + "name": "Le GC (géré par Lafrance & Mathieu)",
407 + "url": "https://condoslegc.ca",
408 + "listing_url": "https://condoslegc.ca",
409 + "sectors": "Lévis (St-Romuald)",
410 + "connector": null,
411 + "status": "couvert via lafrance_mathieu",
412 + "region": "Québec"
413 + },
414 + {
415 + "id": "minto",
416 + "name": "Minto Apartments",
417 + "url": "https://www.mintoapartments.com",
418 + "listing_url": "https://www.mintoapartments.com/montreal/apartment-rentals/projects.html",
419 + "sectors": "Côte-des-Neiges, Westmount, centre-ville",
420 + "connector": "minto",
421 + "status": "actif",
422 + "region": "Montréal"
423 + },
424 + {
425 + "id": "realstar",
426 + "name": "Realstar",
427 + "url": "https://www.realstar.ca",
428 + "listing_url": "https://www.realstar.ca/apartments/qc/montreal/excelsior-apartments",
429 + "sectors": "Côte-Saint-Luc, Brossard",
430 + "connector": "realstar",
431 + "status": "actif",
432 + "region": "Montréal"
433 + },
434 + {
435 + "id": "hazelview",
436 + "name": "Hazelview Properties",
437 + "url": "https://www.hazelviewproperties.com",
438 + "listing_url": "https://www.hazelviewproperties.com/cities/montreal",
439 + "sectors": "Centre-ville, Vieux-Port, Plateau",
440 + "connector": "hazelview",
441 + "status": "actif",
442 + "region": "Montréal"
443 + },
444 + {
445 + "id": "interrent",
446 + "name": "InterRent REIT (CLV Group)",
447 + "url": "https://www.irent.com",
448 + "listing_url": "https://www.irent.com/communities/city/montreal",
449 + "sectors": "Centre-ville, CDN, Côte Saint-Luc",
450 + "connector": "interrent",
451 + "status": "actif",
452 + "region": "Montréal"
453 + },
454 + {
455 + "id": "metcap",
456 + "name": "MetCap Living",
457 + "url": "https://www.metcap.com",
458 + "listing_url": "https://www.metcap.com/province-search-results?lang=en&province=115&city=Montréal",
459 + "sectors": "Montréal, Saint-Laurent, Pointe-Claire",
460 + "connector": "metcap",
461 + "status": "actif",
462 + "region": "Montréal"
463 + },
464 + {
465 + "id": "akelius",
466 + "name": "Akelius Montréal",
467 + "url": "https://rent.akelius.com",
468 + "listing_url": "https://rent.akelius.com/en/search/canada/apartment/montreal",
469 + "sectors": "Plateau, CDN, NDG, Villeray",
470 + "connector": "akelius",
471 + "status": "actif",
472 + "region": "Montréal"
473 + },
474 + {
475 + "id": "boardwalk",
476 + "name": "Boardwalk REIT",
477 + "url": "https://www.bwalk.com",
478 + "listing_url": "https://www.bwalk.com/fr-ca/appartements-a-louer-a-montreal-longueuil/longueuil",
479 + "sectors": "Longueuil",
480 + "connector": "boardwalk",
481 + "status": "actif",
482 + "region": "Montréal"
483 + },
484 + {
485 + "id": "copley",
486 + "name": "Groupe Copley",
487 + "url": "https://www.groupecopley.com",
488 + "listing_url": "https://www.groupecopley.com/",
489 + "sectors": "Westmount, Mont-Royal, Saint-Laurent",
490 + "connector": "copley",
491 + "status": "actif",
492 + "region": "Montréal"
493 + },
494 + {
495 + "id": "cromwell",
496 + "name": "Cromwell Management",
497 + "url": "https://cromwellmgt.ca",
498 + "listing_url": "https://cromwellmgt.ca/en/apartments-for-rent-montreal",
499 + "sectors": "Centre-ville, Outremont, CSL, NDG",
500 + "connector": "cromwell",
501 + "status": "actif",
502 + "region": "Montréal"
503 + },
504 + {
505 + "id": "lynk_olymbec",
506 + "name": "Lynk (Olymbec)",
507 + "url": "https://lynk.ca",
508 + "listing_url": "https://lynk.ca/",
509 + "sectors": "De la Savane / Côte-des-Neiges",
510 + "connector": "lynk_olymbec",
511 + "status": "actif",
512 + "region": "Montréal"
513 + },
514 + {
515 + "id": "trylon",
516 + "name": "Trylon Apartments",
517 + "url": "https://trylonmontreal.com",
518 + "listing_url": "https://trylonmontreal.com/fr",
519 + "sectors": "Centre-ville",
520 + "connector": "trylon",
521 + "status": "actif",
522 + "region": "Montréal"
523 + },
524 + {
525 + "id": "plan_a",
526 + "name": "Plan A Immobilier",
527 + "url": "https://plan-a.ca",
528 + "listing_url": "https://plan-a.ca/plan-a-appartements-et-condos-a-louer/",
529 + "sectors": "Pierrefonds, Laval, Vaudreuil",
530 + "connector": "plan_a",
531 + "status": "actif",
532 + "region": "Montréal"
533 + },
534 + {
535 + "id": "loftsmtl",
536 + "name": "Lofts MTL",
537 + "url": "https://www.loftsmtl.com",
538 + "listing_url": "https://www.loftsmtl.com/",
539 + "sectors": "Vieux-Montréal, Mile-End, NDG, VMR",
540 + "connector": "loftsmtl",
541 + "status": "actif",
542 + "region": "Montréal"
543 + },
544 + {
545 + "id": "axia",
546 + "name": "Axia Appartements",
547 + "url": "https://www.axiaappartements.com",
548 + "listing_url": "https://www.axiaappartements.com/",
549 + "sectors": "Lachine",
550 + "connector": "axia",
551 + "status": "actif",
552 + "region": "Montréal"
553 + },
554 + {
555 + "id": "firma",
556 + "name": "Groupe Firma",
557 + "url": "https://groupefirma.ca",
558 + "listing_url": "https://groupefirma.ca/",
559 + "sectors": "Montérégie, banlieue sud-ouest",
560 + "connector": "firma",
561 + "status": "actif",
562 + "region": "Montréal"
563 + },
564 + {
565 + "id": "ledomaine",
566 + "name": "Les Habitations Le Domaine",
567 + "url": "https://www.ledomaine.ca",
568 + "listing_url": "https://www.ledomaine.ca/",
569 + "sectors": "Mercier/Hochelaga",
570 + "connector": "ledomaine",
571 + "status": "actif",
572 + "region": "Montréal"
573 + },
574 + {
575 + "id": "beaudoin",
576 + "name": "Société Beaudoin Immobilier",
577 + "url": "https://www.beaudoinimmobilier.ca",
578 + "listing_url": "https://www.beaudoinimmobilier.ca/index.php/decouvrez-nos-immeubles",
579 + "sectors": "Longueuil, Boucherville, Lachine",
580 + "connector": "beaudoin",
581 + "status": "actif",
582 + "region": "Montréal"
583 + },
584 + {
585 + "id": "mondev",
586 + "name": "Mondev",
587 + "url": "https://www.mondev.ca",
588 + "listing_url": "https://mondev.ca/apartments-and-condos-for-rent/",
589 + "sectors": "Ville-Marie, Sud-Ouest, Plateau",
590 + "connector": "mondev",
591 + "status": "actif",
592 + "region": "Montréal"
593 + },
594 + {
595 + "id": "rester",
596 + "name": "Rester Management",
597 + "url": "https://rester.ca",
598 + "listing_url": "https://rester.ca/rester-ca-properties/rent-apartment/",
599 + "sectors": "Centre-ville, CDN",
600 + "connector": null,
601 + "status": "non connectable — aucune unité disponible affichée",
602 + "region": "Montréal"
603 + },
604 + {
605 + "id": "hillpark",
606 + "name": "Hillpark Capital",
607 + "url": "https://www.hillpark.ca",
608 + "listing_url": "https://www.hillpark.ca/",
609 + "sectors": "Centre-ville, Plateau, Mile-End",
610 + "connector": null,
611 + "status": "non connectable — hillpark.ca est un site placeholder vide",
612 + "region": "Montréal"
613 + },
614 + {
615 + "id": "denux",
616 + "name": "Groupe Denux",
617 + "url": "https://www.groupedenux.com",
618 + "listing_url": "https://www.groupedenux.com/",
619 + "sectors": "Montréal, Saint-Lambert, Mascouche",
620 + "connector": "denux",
621 + "status": "actif",
622 + "region": "Montréal"
623 + },
624 + {
625 + "id": "utile",
626 + "name": "UTILE (logement étudiant)",
627 + "url": "https://www.utile.org",
628 + "listing_url": "https://www.utile.org/en",
629 + "sectors": "Griffintown, Angus, Milton-Parc",
630 + "connector": "utile",
631 + "status": "actif",
632 + "region": "Montréal"
633 + },
634 + {
635 + "id": "werkliv",
636 + "name": "Werkliv",
637 + "url": "https://werkliv.com",
638 + "listing_url": "https://werkliv.com/en",
639 + "sectors": "Centre-ville, Milton-Parc (étudiant)",
640 + "connector": "werkliv",
641 + "status": "actif",
642 + "region": "Montréal"
643 + },
644 + {
645 + "id": "brivia_1sp",
646 + "name": "Groupe Brivia (1 Square Phillips)",
647 + "url": "https://briviagroup.ca",
648 + "listing_url": "https://www.1squarephillips.ca/locatif",
649 + "sectors": "Centre-ville",
650 + "connector": "brivia_1sp",
651 + "status": "actif",
652 + "region": "Montréal"
653 + },
654 + {
655 + "id": "equinoxe_batimo",
656 + "name": "Batimo/EMD — Collection Équinoxe",
657 + "url": "https://collectionequinoxe.com",
658 + "listing_url": "https://collectionequinoxe.com/",
659 + "sectors": "Laval, Bois-Franc (Saint-Laurent)",
660 + "connector": "equinoxe_batimo",
661 + "status": "actif",
662 + "region": "Montréal"
663 + },
664 + {
665 + "id": "devimco",
666 + "name": "Devimco Appartements",
667 + "url": "https://devimco.com",
668 + "listing_url": "https://devimco.com/appartements",
669 + "sectors": "Griffintown, Brossard (Solar Uniquartier)",
670 + "connector": "devimco",
671 + "status": "actif",
672 + "region": "Montréal"
673 + },
674 + {
675 + "id": "progim",
676 + "name": "Progim",
677 + "url": "https://progim.com",
678 + "listing_url": "http://progimannonces.bstk.io/Listing/Listings",
679 + "sectors": "Grand Montréal (base Brossard)",
680 + "connector": "progim",
681 + "status": "actif",
682 + "region": "Montréal"
683 + },
684 + {
685 + "id": "rentalys",
686 + "name": "Rentalys",
687 + "url": "https://www.rentalys.ca",
688 + "listing_url": "https://location.rentalys.ca/",
689 + "sectors": "Grande région de Montréal",
690 + "connector": "rentalys",
691 + "status": "actif",
692 + "region": "Montréal"
693 + },
694 + {
695 + "id": "gestion_montreal",
696 + "name": "Gestion Montréal",
697 + "url": "https://gestion-montreal.com",
698 + "listing_url": "https://gestion-montreal.com/fr/inscriptions",
699 + "sectors": "Montréal, Repentigny, La Prairie",
700 + "connector": "gestion_montreal",
701 + "status": "actif",
702 + "region": "Montréal"
703 + },
704 + {
705 + "id": "niddamour",
706 + "name": "Nid d'Amour",
707 + "url": "https://niddamour.ca",
708 + "listing_url": "https://niddamour.ca/",
709 + "sectors": "Plateau, Verdun, Outremont, Rosemont",
710 + "connector": "niddamour",
711 + "status": "actif",
712 + "region": "Montréal"
713 + },
714 + {
715 + "id": "shdm",
716 + "name": "SHDM",
717 + "url": "https://www.shdm.org",
718 + "listing_url": "https://www.shdm.org/fr/logements-abordables/louer-un-appartement",
719 + "sectors": "Île de Montréal (abordable)",
720 + "connector": "shdm",
721 + "status": "actif",
722 + "region": "Montréal"
723 + },
724 + {
725 + "id": "quintcap",
726 + "name": "Quintcap",
727 + "url": "https://quintcap.com",
728 + "listing_url": "https://quintcap.com/propriete/square-chateauguay-logements-a-louer/",
729 + "sectors": "La Prairie, Châteauguay",
730 + "connector": null,
731 + "status": "non connectable — unités sans prix (« Contactez-nous »), Belle-Dame 100% loué",
732 + "region": "Montréal"
733 + },
734 + {
735 + "id": "rama",
736 + "name": "Groupe Rama",
737 + "url": "https://grouperama.com",
738 + "listing_url": "https://grouperama.com/mes-proprietes",
739 + "sectors": "Ahuntsic, Rosemont, RDP",
740 + "connector": null,
741 + "status": "non connectable — aucune annonce résidentielle locative actuellement",
742 + "region": "Montréal"
743 + }
744 + ]
745 +}
\ No newline at end of file
added frontend/index.html +27 −0
@@ -0,0 +1,27 @@
1 +<!doctype html>
2 +<!-- ---------------------------------------------------------------------------
3 + Lou-Ka — Agrégateur de logements à louer (province de Québec)
4 + Auteur : Simon-Pierre Boucher — contact@spboucher.ai
5 +---------------------------------------------------------------------------- -->
6 +<html lang="fr">
7 + <head>
8 + <meta charset="UTF-8" />
9 + <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
10 + <title>Lou-Ka — Logements à louer au Québec</title>
11 + <meta name="description" content="Lou-Ka agrège les appartements à louer affichés par les gestionnaires immobiliers de Québec et Lévis, toujours à jour." />
12 + <meta name="theme-color" content="#f5f3ee" />
13 + <meta name="mobile-web-app-capable" content="yes" />
14 + <meta name="apple-mobile-web-app-capable" content="yes" />
15 + <meta name="apple-mobile-web-app-status-bar-style" content="default" />
16 + <meta name="apple-mobile-web-app-title" content="Lou-Ka" />
17 + <link rel="manifest" href="/manifest.webmanifest" />
18 + <link rel="preconnect" href="https://fonts.googleapis.com" />
19 + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
20 + <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet" />
21 + <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='12' fill='%23121712'/%3E%3Ctext x='32' y='45' font-family='Arial Black,sans-serif' font-size='32' font-weight='900' fill='%23d9f26b' text-anchor='middle'%3ELK%3C/text%3E%3C/svg%3E" />
22 + </head>
23 + <body>
24 + <div id="root"></div>
25 + <script type="module" src="/src/main.tsx"></script>
26 + </body>
27 +</html>
added frontend/package-lock.json +1834 −0
Large diff (1,834 lines) is not loaded by default to keep the page fast.Load diff
added frontend/package.json +24 −0
Large diff (24 lines) is not loaded by default to keep the page fast.Load diff
added frontend/public/manifest.webmanifest +18 −0
Large diff (18 lines) is not loaded by default to keep the page fast.Load diff
added frontend/src/App.tsx +119 −0
Large diff (119 lines) is not loaded by default to keep the page fast.Load diff
added frontend/src/api.ts +101 −0
Large diff (101 lines) is not loaded by default to keep the page fast.Load diff
added frontend/src/components/ListingCard.tsx +41 −0
Large diff (41 lines) is not loaded by default to keep the page fast.Load diff
added frontend/src/main.tsx +18 −0
Large diff (18 lines) is not loaded by default to keep the page fast.Load diff
added frontend/src/pages/Home.tsx +226 −0
Large diff (226 lines) is not loaded by default to keep the page fast.Load diff
added frontend/src/pages/Listing.tsx +146 −0
Large diff (146 lines) is not loaded by default to keep the page fast.Load diff
added frontend/src/pages/Sources.tsx +74 −0
Large diff (74 lines) is not loaded by default to keep the page fast.Load diff
added frontend/src/styles.css +425 −0
Large diff (425 lines) is not loaded by default to keep the page fast.Load diff
added frontend/tsconfig.json +20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added frontend/tsconfig.tsbuildinfo +1 −0
Large diff (2 lines) is not loaded by default to keep the page fast.Load diff
added frontend/vite.config.ts +15 −0
Large diff (15 lines) is not loaded by default to keep the page fast.Load diff
added gestion-immobiliere-quebec.md +475 −0
Large diff (475 lines) is not loaded by default to keep the page fast.Load diff
added louka/__init__.py +6 −0
Large diff (6 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/__init__.py +30 −0
Large diff (30 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/akelius.py +144 −0
Large diff (144 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/app_urbains.py +157 −0
Large diff (157 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/axia.py +118 −0
Large diff (118 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/base.py +72 −0
Large diff (72 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/beaudoin.py +190 −0
Large diff (190 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/boardwalk.py +229 −0
Large diff (229 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/bribourg.py +170 −0
Large diff (170 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/brio.py +126 −0
Large diff (126 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/brivia_1sp.py +116 −0
Large diff (116 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/brochu.py +130 −0
Large diff (130 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/capreit.py +219 −0
Large diff (219 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/cogir.py +229 −0
Large diff (229 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/contraste.py +141 −0
Large diff (141 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/copley.py +168 −0
Large diff (168 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/cromwell.py +211 −0
Large diff (211 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/denux.py +234 −0
Large diff (234 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/devimco.py +180 −0
Large diff (180 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/dma_locago.py +207 −0
Large diff (207 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/elements.py +126 −0
Large diff (126 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/equinoxe_batimo.py +200 −0
Large diff (200 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/firma.py +227 −0
Large diff (227 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/gestion_montreal.py +200 −0
Large diff (200 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/gestipro.py +161 −0
Large diff (161 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/gimcote.py +149 −0
Large diff (149 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/gparadis.py +153 −0
Large diff (153 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/groupe_dallaire.py +253 −0
Large diff (253 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/hazelview.py +164 −0
Large diff (164 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/headway.py +184 −0
Large diff (184 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/huma.py +125 −0
Large diff (125 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/immomarketing.py +213 −0
Large diff (213 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/immostar.py +280 −0
Large diff (280 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/interrent.py +231 −0
Large diff (231 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/laberge.py +200 −0
Large diff (200 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/lafrance_mathieu.py +89 −0
Large diff (89 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/lakle.py +123 −0
Large diff (123 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/leclif.py +110 −0
Large diff (110 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/ledomaine.py +120 −0
Large diff (120 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/loftsmtl.py +186 −0
Large diff (186 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/logisbourg.py +166 −0
Large diff (166 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/logisco.py +209 −0
Large diff (209 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/logisma.py +145 −0
Large diff (145 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/lokalia.py +194 −0
Large diff (194 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/lynk_olymbec.py +133 −0
Large diff (133 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/metcap.py +192 −0
Large diff (192 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/minto.py +175 −0
Large diff (175 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/mondev.py +175 −0
Large diff (175 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/msi.py +127 −0
Large diff (127 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/niddamour.py +198 −0
Large diff (198 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/oklouer.py +136 −0
Large diff (136 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/per.py +139 −0
Large diff (139 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/picard.py +140 −0
Large diff (140 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/plan_a.py +171 −0
Large diff (171 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/progim.py +198 −0
Large diff (198 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/realstar.py +201 −0
Large diff (201 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/rentalys.py +234 −0
Large diff (234 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/rivero.py +150 −0
Large diff (150 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/roussin.py +143 −0
Large diff (143 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/sdg.py +143 −0
Large diff (143 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/sentinelle.py +115 −0
Large diff (115 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/sgiq.py +181 −0
Large diff (181 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/shdm.py +166 −0
Large diff (166 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/sibelanger.py +139 −0
Large diff (139 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/simard.py +153 −0
Large diff (153 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/terra.py +153 −0
Large diff (153 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/trudel.py +143 −0
Large diff (143 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/trylon.py +146 −0
Large diff (146 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/utile.py +182 −0
Large diff (182 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/viridi.py +173 −0
Large diff (173 lines) is not loaded by default to keep the page fast.Load diff
added louka/connectors/werkliv.py +179 −0
Large diff (179 lines) is not loaded by default to keep the page fast.Load diff
added louka/db.py +148 −0
Large diff (148 lines) is not loaded by default to keep the page fast.Load diff
added louka/ingest.py +52 −0
Large diff (52 lines) is not loaded by default to keep the page fast.Load diff
added louka/schema.py +113 −0
Large diff (113 lines) is not loaded by default to keep the page fast.Load diff
added louka/web.py +158 −0
Large diff (158 lines) is not loaded by default to keep the page fast.Load diff
added requirements.txt +6 −0
Large diff (6 lines) is not loaded by default to keep the page fast.Load diff
added run.py +47 −0
Large diff (48 lines) is not loaded by default to keep the page fast.Load diff
Menu

Theme