SPB Git forge

spb/auto-ka

Public
61commits 1branches 0releases
14.4 MBsize
maindefault branch
14 days agolast push
Python 61.6% TypeScript 20.9% CSS 11.4% JavaScript 5.1% HTML 1.1%

docs: documentation standardisée des connecteurs (générateur + 27 fiches module + 4 transverses)

scripts/gen_connector_docs.py croise data/sources.json, l en-tête mécanique
des modules connecteurs et la BD live (volumétrie, complétude par champ,
sync_log) pour régénérer docs/connecteurs/ (INDEX.md + fiches).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 1 mo ago (Aug 18, 2026) parent bbc070b

33 changed files +2,374 −0

added docs/connecteurs/INDEX.md +60 −0
@@ -0,0 +1,60 @@
1 +# Auto-Ka — Documentation des connecteurs
2 +
3 +_Générée le 2026-08-18 03:24 par `scripts/gen_connector_docs.py` (rejouable : `.venv/bin/python3 scripts/gen_connector_docs.py`)._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Sources** : 139 (registre `data/sources.json`)
8 +- **Modules connecteurs** : 27 (`autoka/connectors/`)
9 +- **Annonces en base** : 23110 — dont 20452 actives (19822 autos, 606 motos, 24 scooters)
10 +- **Doublons VIN masqués** : 2315 (voir [dédup VIN](transverse-dedup-vin.md))
11 +- **Rappels Transports Canada** : 16969 rappels distincts (voir [rappels TC](transverse-rappels-tc.md))
12 +- **Concessionnaires géolocalisés** : 138 (voir [dealers](transverse-dealers.md))
13 +
14 +## Fiches par module connecteur
15 +
16 +| Module | Fiche | Sources | Annonces actives | Backend |
17 +|---|---|---|---|---|
18 +| `d2c_dealers` | [d2c_dealers.md](d2c_dealers.md) | 66 | 5229 | requests direct — Firecrawl par source au besoin |
19 +| `sm360_dealers` | [sm360_dealers.md](sm360_dealers.md) | 15 | 1434 | requests direct — Firecrawl par source au besoin |
20 +| `moto_dealers` | [moto_dealers.md](moto_dealers.md) | 13 | 630 | requests direct |
21 +| `central_dealers` | [central_dealers.md](central_dealers.md) | 9 | 345 | requests direct |
22 +| `gatsby_dealers` | [gatsby_dealers.md](gatsby_dealers.md) | 6 | 191 | requests direct |
23 +| `magnetis_dealers` | [magnetis_dealers.md](magnetis_dealers.md) | 4 | 423 | requests direct |
24 +| `vvu_dealers` | [vvu_dealers.md](vvu_dealers.md) | 4 | 183 | requests direct |
25 +| `convertus_fc` | [convertus_fc.md](convertus_fc.md) | 3 | 296 | Firecrawl |
26 +| `albioccasion` | [albioccasion.md](albioccasion.md) | 1 | 1136 | requests direct |
27 +| `autodurocher` | [autodurocher.md](autodurocher.md) | 1 | 196 | requests direct |
28 +| `automobileendirect` | [automobileendirect.md](automobileendirect.md) | 1 | 1687 | requests direct |
29 +| `classeauto` | [classeauto.md](classeauto.md) | 1 | 109 | requests direct |
30 +| `clubautozone` | [clubautozone.md](clubautozone.md) | 1 | 47 | requests direct |
31 +| `desmeules` | [desmeules.md](desmeules.md) | 1 | 243 | requests direct |
32 +| `dupontford` | [dupontford.md](dupontford.md) | 1 | 65 | requests direct |
33 +| `hgregoire` | [hgregoire.md](hgregoire.md) | 1 | 1672 | Scrapfly |
34 +| `jlkauto` | [jlkauto.md](jlkauto.md) | 1 | 68 | requests direct |
35 +| `kijiji` | [kijiji.md](kijiji.md) | 1 | 3002 | requests direct |
36 +| `leprixdugros` | [leprixdugros.md](leprixdugros.md) | 1 | 886 | Scrapfly |
37 +| `megacentre` | [megacentre.md](megacentre.md) | 1 | 455 | requests direct |
38 +| `montjolichrysler` | [montjolichrysler.md](montjolichrysler.md) | 1 | 414 | requests direct |
39 +| `occasionbeaucage` | [occasionbeaucage.md](occasionbeaucage.md) | 1 | 1226 | requests direct |
40 +| `occasioncharlevoix` | [occasioncharlevoix.md](occasioncharlevoix.md) | 1 | 30 | requests direct |
41 +| `okaze` | [okaze.md](okaze.md) | 1 | 50 | requests direct |
42 +| `ototr` | [ototr.md](ototr.md) | 1 | 4 | requests direct |
43 +| `stefoychrysler` | [stefoychrysler.md](stefoychrysler.md) | 1 | 414 | requests direct |
44 +| `yannicklaberge` | [yannicklaberge.md](yannicklaberge.md) | 1 | 17 | requests direct |
45 +
46 +## Fiches transverses
47 +
48 +| Sujet | Fiche |
49 +|---|---|
50 +| Dédoublonnage VIN inter-sources | [transverse-dedup-vin.md](transverse-dedup-vin.md) |
51 +| Rappels Transports Canada | [transverse-rappels-tc.md](transverse-rappels-tc.md) |
52 +| Coordonnées des concessionnaires | [transverse-dealers.md](transverse-dealers.md) |
53 +| Référentiel GPS des villes | [transverse-villes-gps.md](transverse-villes-gps.md) |
54 +
55 +## Historique des vagues (2026-08-18)
56 +
57 +| Commit | Contenu |
58 +|---|---|
59 +| `2a35ac2` | Enrichissement connecteurs : Carfax, détails AED/LPDG, verticale moto, photos Magnetis, GPS concessionnaires |
60 +| `bbc070b` | Vague 2 : dédup VIN inter-sources, Kijiji particuliers, rappels Transports Canada, coordonnées concessionnaires |
added docs/connecteurs/albioccasion.md +61 −0
@@ -0,0 +1,61 @@
1 +# Module `albioccasion` — ASP.NET WebForms maison
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/albioccasion.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 1136
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : microdata schema.org
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, AUTOKA_MAX_PAGES, cache détail BD (detail_cache)
13 +- **Classes** : `AlbiOccasion` → `albioccasion`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/albioccasion.py : connecteur ALBI Occasion (albioccasion.com),
18 +> la division occasion d'ALBI le Géant — très grosse chaîne multi-
19 +> succursales (Mascouche, Repentigny, Blainville, Laval, Rive-Nord…),
20 +> ~1 100+ véhicules d'occasion.
21 +>
22 +> Plateforme : ASP.NET WebForms maison. La liste /fr/inventaire/?page=N
23 +> (12 véhicules/page, « Page X de Y » dans le HTML) référence chaque page
24 +> détail /fr/vehicule/<id>/<slug>/. La page détail expose un microdata
25 +> schema.org complet (itemprop) : prix, km, VIN, année, version,
26 +> transmission, portes, places, couleurs, carrosserie + des lignes de
27 +> spécifications (SpecLine : entraînement, catégorie…), la galerie photos
28 +> (S3 enzo-production …/vehicules_medias/…) et la succursale réelle du
29 +> véhicule (lien Google Maps « ALBI Occasion <Ville> »).
30 +>
31 +> Pages détail en cache BD (clé hebdomadaire — le prix est revalidé chaque
32 +> semaine). AUTOKA_MAX_PAGES limite la pagination liste et
33 +> AUTOKA_MAX_DETAILS plafonne les vraies requêtes détail par sync.
34 +
35 +## Complétude des champs (annonces actives, N = 1 136)
36 +
37 +| Champ | % rempli |
38 +|---|---|
39 +| Marque | 100.0 % |
40 +| Modèle | 100.0 % |
41 +| Année | 100.0 % |
42 +| Kilométrage | 100.0 % |
43 +| Prix | 100.0 % |
44 +| Carburant | 5.4 % |
45 +| Boîte (transmission) | 100.0 % |
46 +| VIN | 100.0 % |
47 +| Photos | 100.0 % |
48 +| Carfax | 0.0 % |
49 +| GPS (lat/lng) | 100.0 % |
50 +
51 +## Sources membres (BD live)
52 +
53 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
54 +|---|---|---|---|---|---|---|---|
55 +| `albioccasion` | ALBI Occasion | Mascouche | Lanaudière | 1136 | 0 | 2026-08-18 02:15 | OK (1136 trouvés) |
56 +
57 +## Erreurs de synchronisation récentes (sync_log, ok = 0)
58 +
59 +| Source | Quand | Message |
60 +|---|---|---|
61 +| `albioccasion` | 2026-08-12 10:01 | 429 Client Error: Too Many Requests for url: https://www.albioccasion.com/fr/inventaire/?page=64 |
added docs/connecteurs/autodurocher.md +58 −0
@@ -0,0 +1,58 @@
1 +# Module `autodurocher` — WordPress Elementor + JetEngine
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/autodurocher.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 196
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, JSON-LD schema.org
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `AutoDurocher` → `autodurocher`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/autodurocher.py : connecteur Entrepôt Auto Durocher
18 +> (autodurocher.com), gros marchand indépendant de Mirabel (~200 véhicules,
19 +> occasion seulement).
20 +>
21 +> Plateforme : WordPress + Elementor + JetEngine (CPT « vehicles »).
22 +> Le sitemap /fr/sitemap_index.xml expose des vehicles-sitemapN.xml qui ne
23 +> recensent QUE l'inventaire courant (/fr/vehicles/<slug>/). Chaque page
24 +> détail embarque un JSON-LD (script class="fute-custom-schema-vehicles",
25 +> Organization -> makesOffer -> itemOffered @type Car) : prix, km,
26 +> transmission, couleur, carrosserie, rouage, année, marque, modèle — et la
27 +> galerie photos (CDN AutoTrader 1s-photomanager). Le no de stock est le
28 +> dernier segment du slug. Le JSON contient des sauts de ligne bruts ->
29 +> json.loads(strict=False).
30 +>
31 +> Pages détail en cache BD (clé hebdomadaire) ; AUTOKA_MAX_DETAILS (env)
32 +> plafonne les vraies requêtes détail par synchronisation.
33 +
34 +## Complétude des champs (annonces actives, N = 196)
35 +
36 +| Champ | % rempli |
37 +|---|---|
38 +| Marque | 100.0 % |
39 +| Modèle | 100.0 % |
40 +| Année | 100.0 % |
41 +| Kilométrage | 100.0 % |
42 +| Prix | 100.0 % |
43 +| Carburant | 2.6 % |
44 +| Boîte (transmission) | 100.0 % |
45 +| VIN | 0.0 % |
46 +| Photos | 100.0 % |
47 +| Carfax | 0.0 % |
48 +| GPS (lat/lng) | 100.0 % |
49 +
50 +## Sources membres (BD live)
51 +
52 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
53 +|---|---|---|---|---|---|---|---|
54 +| `autodurocher` | Entrepôt Auto Durocher | Mirabel | Laurentides | 196 | 0 | 2026-08-18 02:16 | OK (196 trouvés) |
55 +
56 +## Erreurs de synchronisation récentes
57 +
58 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/automobileendirect.md +64 −0
@@ -0,0 +1,64 @@
1 +# Module `automobileendirect` — Site custom
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/automobileendirect.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 1687
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, AUTOKA_MAX_PAGES, cache détail BD (detail_cache)
13 +- **Classes** : `AutomobileEnDirect` → `automobileendirect`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/automobileendirect.py : connecteur Automobile En Direct
18 +> (automobileendirect.com), grande chaîne d'occasion — Saint-Constant,
19 +> Laval, Saint-Hubert, Île-Perrot, Québec, Gatineau.
20 +>
21 +> Stratégie : le site est une SPA React alimentée par une API REST
22 +> publique non authentifiée : https://api.automobileendirect.com
23 +> GET /cars?page=N (en-tête accept-language: fr)
24 +> -> {"totalResults": ~1725, "results": [22 véhicules]}
25 +> chaque résultat : vin, slug, année/marque/modèle/version, prix
26 +> courant + régulier (CAD), km, transmission, carburant, carrosserie,
27 +> couleur, no de stock, photos, succursale (store.title.fr = ville).
28 +> GET /cars/detailed/<vin> (optionnel, mise en cache BD, clé statique :
29 +> contenu quasi immuable, le prix/km frais viennent de la liste)
30 +> -> traction, portes, passagers, moteur, couleurs, description,
31 +> options, anciens propriétaires ET la galerie complète
32 +> (photos.all ≈ 25 images vs 4 aperçus dans la liste).
33 +> ~80 requêtes de liste pour tout l'inventaire ; les pages détail sont
34 +> plafonnées par AUTOKA_MAX_DETAILS (défaut 1200 — API JSON rapide,
35 +> ~1 s/requête) et complétées aux syncs suivants via le cache BD.
36 +>
37 +> URL publique d'une fiche : /auto-usage/<slug>/<vin> (route SPA fr).
38 +> AUTOKA_MAX_PAGES (env) limite le nombre de pages de liste (tests).
39 +
40 +## Complétude des champs (annonces actives, N = 1 687)
41 +
42 +| Champ | % rempli |
43 +|---|---|
44 +| Marque | 100.0 % |
45 +| Modèle | 100.0 % |
46 +| Année | 100.0 % |
47 +| Kilométrage | 100.0 % |
48 +| Prix | 100.0 % |
49 +| Carburant | 100.0 % |
50 +| Boîte (transmission) | 100.0 % |
51 +| VIN | 100.0 % |
52 +| Photos | 100.0 % |
53 +| Carfax | 0.0 % |
54 +| GPS (lat/lng) | 100.0 % |
55 +
56 +## Sources membres (BD live)
57 +
58 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
59 +|---|---|---|---|---|---|---|---|
60 +| `automobileendirect` | Automobile En Direct | Saint-Constant | Montérégie | 1687 | 0 | 2026-08-18 02:17 | OK (1687 trouvés) |
61 +
62 +## Erreurs de synchronisation récentes
63 +
64 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/central_dealers.md +79 −0
@@ -0,0 +1,79 @@
1 +# Module `central_dealers` — AMVOQ Focus 360
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/central_dealers.py`
8 +- **Sources membres** : 9
9 +- **Annonces actives (BD)** : 345
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : parsing HTML, endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS
13 +- **Classes** : `DenisAuto` → `denisauto` ; `JRAuto` → `jrautotr` ; `Autosag` → `autosag` ; `LeCentreAutoQuebec` → `lecentreautoquebec` ; `AutoCreditPlus` → `autocreditplus` ; `FleuryAutoGroupe` → `fleuryautogroupe` … (+3)
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/central_dealers.py : connecteurs des concessionnaires sur la
18 +> plateforme AMVOQ « Focus 360 / Instavid360 » (thème WordPress
19 +> `theme_central`, inventaire Vue.js alimenté par un index Solr).
20 +>
21 +> Stratégie : le thème expose un endpoint JSON non authentifié
22 +> /wp-content/themes/theme_central/include/functions/RechercheVoitures.php
23 +> (exige seulement un en-tête Referer du même site) qui renvoie les
24 +> documents Solr complets de l'inventaire : gvo_id, année, marque, modèle,
25 +> sous-modèle, prix, km, transmission, carburant, traction, carrosserie,
26 +> couleurs, portes, VIN, no d'unité, municipalité/région et 1re photo.
27 +>
28 +> La page détail (/vehicule-usage/<slug>/<gvo_id>/, rendue côté serveur,
29 +> le slug est ignoré par le serveur) complète : galerie photos complète,
30 +> description, options/équipements, nb de passagers, cylindrée. Ces pages
31 +> sont mises en cache BD (clé statique v1 : le prix/km frais viennent
32 +> toujours de l'API liste, le contenu détail est quasi immuable).
33 +>
34 +> vehicule_type_i discrimine le type d'inventaire (1 = automobile,
35 +> 2 = moto, 3 = VR) ; on garde le type 1 + un garde-fou regex sur la
36 +> catégorie/carrosserie (motoneige, VTT, Classe A/B/C, récréatif…).
37 +
38 +## Complétude des champs (annonces actives, N = 345)
39 +
40 +| Champ | % rempli |
41 +|---|---|
42 +| Marque | 100.0 % |
43 +| Modèle | 100.0 % |
44 +| Année | 100.0 % |
45 +| Kilométrage | 100.0 % |
46 +| Prix | 100.0 % |
47 +| Carburant | 100.0 % |
48 +| Boîte (transmission) | 100.0 % |
49 +| VIN | 100.0 % |
50 +| Photos | 100.0 % |
51 +| Carfax | 0.0 % |
52 +| GPS (lat/lng) | 100.0 % |
53 +
54 +## Sources membres (BD live)
55 +
56 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
57 +|---|---|---|---|---|---|---|---|
58 +| `autobsl` | Auto BSL | Rimouski | Bas-Saint-Laurent | 55 | 0 | 2026-08-18 02:17 | OK (55 trouvés) |
59 +| `autocreditplus` | Auto Crédit Plus | Trois-Rivières | Mauricie | 83 | 0 | 2026-08-18 02:17 | OK (83 trouvés) |
60 +| `autosag` | Autosag | Chicoutimi | Saguenay-Lac-Saint-Jean | 5 | 0 | 2026-08-18 02:17 | OK (5 trouvés) |
61 +| `autoxtreme` | Auto Xtrême | Montréal | Montréal | 50 | 0 | 2026-08-18 02:17 | OK (50 trouvés) |
62 +| `dastousauto` | D'Astous Auto | Montréal | Montréal | 24 | 0 | 2026-08-18 02:17 | OK (24 trouvés) |
63 +| `denisauto` | Denis Auto | Gatineau | Outaouais | 37 | 0 | 2026-08-18 02:17 | OK (37 trouvés) |
64 +| `fleuryautogroupe` | Fleury Auto Groupe | Gatineau | Outaouais | 60 | 0 | 2026-08-18 02:17 | OK (60 trouvés) |
65 +| `jrautotr` | J.R. Auto | Trois-Rivières | Mauricie | 25 | 0 | 2026-08-18 02:17 | OK (25 trouvés) |
66 +| `lecentreautoquebec` | Le Centre Auto Québec Plus | Québec | Capitale-Nationale | 6 | 0 | 2026-08-18 02:17 | OK (6 trouvés) |
67 +
68 +## Erreurs de synchronisation récentes (sync_log, ok = 0)
69 +
70 +| Source | Quand | Message |
71 +|---|---|---|
72 +| `autobsl` | 2026-08-14 11:17 | HTTPSConnectionPool(host='www.autobsl.com', port=443): Max retries exceeded with url: /wp-content/themes/theme_central/include/functions/RechercheVoitures.php?o |
73 +| `autobsl` | 2026-08-14 08:51 | HTTPSConnectionPool(host='www.autobsl.com', port=443): Max retries exceeded with url: /wp-content/themes/theme_central/include/functions/RechercheVoitures.php?o |
74 +| `autobsl` | 2026-08-14 06:27 | HTTPSConnectionPool(host='www.autobsl.com', port=443): Max retries exceeded with url: /wp-content/themes/theme_central/include/functions/RechercheVoitures.php?o |
75 +| `autobsl` | 2026-08-14 04:02 | HTTPSConnectionPool(host='www.autobsl.com', port=443): Max retries exceeded with url: /wp-content/themes/theme_central/include/functions/RechercheVoitures.php?o |
76 +| `autobsl` | 2026-08-14 01:28 | HTTPSConnectionPool(host='www.autobsl.com', port=443): Max retries exceeded with url: /wp-content/themes/theme_central/include/functions/RechercheVoitures.php?o |
77 +| `autobsl` | 2026-08-13 23:03 | HTTPSConnectionPool(host='www.autobsl.com', port=443): Max retries exceeded with url: /wp-content/themes/theme_central/include/functions/RechercheVoitures.php?o |
78 +| `autobsl` | 2026-08-13 20:38 | HTTPSConnectionPool(host='www.autobsl.com', port=443): Max retries exceeded with url: /wp-content/themes/theme_central/include/functions/RechercheVoitures.php?o |
79 +| `autobsl` | 2026-08-13 18:08 | HTTPSConnectionPool(host='www.autobsl.com', port=443): Max retries exceeded with url: /wp-content/themes/theme_central/include/functions/RechercheVoitures.php?o |
added docs/connecteurs/classeauto.md +57 −0
@@ -0,0 +1,57 @@
1 +# Module `classeauto` — WordPress Astra + DriveGood
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/classeauto.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 109
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : endpoint JSON
12 +- **Plafonds / cache** : aucun
13 +- **Classes** : `ClasseAuto` → `classeauto`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/classeauto.py : connecteur Classe Auto (classeauto.ca),
18 +> marchand d'occasion de l'île de Montréal (boul. Industriel,
19 +> Montréal-Nord/Anjou) — ~140 véhicules.
20 +>
21 +> Plateforme : WordPress (thème Astra) + moteur d'inventaire DriveGood
22 +> (cdn.drivegood.com). Le site expose un export JSON STATIQUE de tout
23 +> l'inventaire :
24 +> /wp-content/themes/astra/car_single_page_data/cars_formatted.json
25 +> — une seule requête pour la liste complète, avec TOUS les champs :
26 +> prix, km, VIN, stock, transmission, carburant, motricité, carrosserie,
27 +> couleurs, portes, passagers, moteur, options, photos (cdn.drivegood.com),
28 +> description. Aucune page détail nécessaire.
29 +>
30 +> Filtres de sécurité : vehicle_type_id == 1 (automobile), post_status
31 +> publish/published, condition != NEW, deleted_at vide.
32 +
33 +## Complétude des champs (annonces actives, N = 109)
34 +
35 +| Champ | % rempli |
36 +|---|---|
37 +| Marque | 100.0 % |
38 +| Modèle | 100.0 % |
39 +| Année | 100.0 % |
40 +| Kilométrage | 100.0 % |
41 +| Prix | 100.0 % |
42 +| Carburant | 100.0 % |
43 +| Boîte (transmission) | 100.0 % |
44 +| VIN | 100.0 % |
45 +| Photos | 100.0 % |
46 +| Carfax | 100.0 % |
47 +| GPS (lat/lng) | 100.0 % |
48 +
49 +## Sources membres (BD live)
50 +
51 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
52 +|---|---|---|---|---|---|---|---|
53 +| `classeauto` | Classe Auto | Montréal | Montréal | 109 | 0 | 2026-08-18 02:17 | OK (138 trouvés) |
54 +
55 +## Erreurs de synchronisation récentes
56 +
57 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/clubautozone.md +51 −0
@@ -0,0 +1,51 @@
1 +# Module `clubautozone` — WordPress Convertus
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/clubautozone.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 47
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : API JSON interne, endpoint JSON
12 +- **Plafonds / cache** : aucun
13 +- **Classes** : `ClubAutoZone` → `clubautozone`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/clubautozone.py : Club Auto Zone (Longueuil) — WordPress sur la
18 +> plateforme Convertus (thème « achilles » + plugin convertus-vms).
19 +>
20 +> Stratégie : la page inventaire est une app Vue qui charge les véhicules
21 +> depuis l'API VMS (vms.prod.convertus.rocks) VIA le proxy PHP du site :
22 +> /wp-content/plugins/convertus-vms/include/php/ajax-vehicles.php
23 +> ?endpoint=<URL VMS encodée>&action=vms_data
24 +> (l'API VMS directe répond 403 ; le proxy du site est la voie officielle).
25 +> Réponse JSON riche : prix, km, VIN, moteur, couleurs, URL VDP… 30/page.
26 +
27 +## Complétude des champs (annonces actives, N = 47)
28 +
29 +| Champ | % rempli |
30 +|---|---|
31 +| Marque | 100.0 % |
32 +| Modèle | 100.0 % |
33 +| Année | 100.0 % |
34 +| Kilométrage | 100.0 % |
35 +| Prix | 100.0 % |
36 +| Carburant | 100.0 % |
37 +| Boîte (transmission) | 100.0 % |
38 +| VIN | 100.0 % |
39 +| Photos | 100.0 % |
40 +| Carfax | 0.0 % |
41 +| GPS (lat/lng) | 100.0 % |
42 +
43 +## Sources membres (BD live)
44 +
45 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
46 +|---|---|---|---|---|---|---|---|
47 +| `clubautozone` | Club Auto Zone | Longueuil | Montérégie | 47 | 0 | 2026-08-18 02:17 | OK (47 trouvés) |
48 +
49 +## Erreurs de synchronisation récentes
50 +
51 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/convertus_fc.md +54 −0
@@ -0,0 +1,54 @@
1 +# Module `convertus_fc` — WordPress Convertus VMS
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/convertus_fc.py`
8 +- **Sources membres** : 3
9 +- **Annonces actives (BD)** : 296
10 +- **Backend de fetch** : Firecrawl (contournement Cloudflare / rendu JS)
11 +- **Mécanique détectée** : API JSON interne
12 +- **Plafonds / cache** : aucun
13 +- **Classes** : `BernieresAuto` → `bernieresauto` ; `AutoFlash` → `autoflash` ; `ComplexeAutoPlus` → `complexeautoplus`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/convertus_fc.py : concessionnaires WordPress « Convertus »
18 +> (thème achilles) protégés par Cloudflare — accès via Firecrawl.
19 +>
20 +> Même API VMS que clubautozone.py (proxy officiel du site
21 +> ajax-vehicles.php -> vms.prod.convertus.rocks), mais chaque appel passe
22 +> par Firecrawl pour franchir Cloudflare. Le JSON revient enveloppé dans
23 +> un <body> HTML — on l'extrait puis on réutilise le parseur VMS.
24 +
25 +## Complétude des champs (annonces actives, N = 296)
26 +
27 +| Champ | % rempli |
28 +|---|---|
29 +| Marque | 99.7 % |
30 +| Modèle | 100.0 % |
31 +| Année | 100.0 % |
32 +| Kilométrage | 100.0 % |
33 +| Prix | 100.0 % |
34 +| Carburant | 100.0 % |
35 +| Boîte (transmission) | 100.0 % |
36 +| VIN | 99.3 % |
37 +| Photos | 100.0 % |
38 +| Carfax | 0.0 % |
39 +| GPS (lat/lng) | 100.0 % |
40 +
41 +## Sources membres (BD live)
42 +
43 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
44 +|---|---|---|---|---|---|---|---|
45 +| `autoflash` | AutoFlash | Saint-Hubert | Montérégie | 137 | 0 | 2026-08-18 02:17 | OK (137 trouvés) |
46 +| `bernieresauto` | Bernières Auto | Saint-Nicolas | Chaudière-Appalaches | 60 | 0 | 2026-08-18 02:17 | OK (60 trouvés) |
47 +| `complexeautoplus` | Complexe Auto Plus | Saint-Jérôme | Laurentides | 99 | 0 | 2026-08-18 02:17 | OK (99 trouvés) |
48 +
49 +## Erreurs de synchronisation récentes (sync_log, ok = 0)
50 +
51 +| Source | Quand | Message |
52 +|---|---|---|
53 +| `complexeautoplus` | 2026-08-12 08:59 | inventoryId introuvable |
54 +| `autoflash` | 2026-08-12 08:59 | inventoryId introuvable |
added docs/connecteurs/d2c_dealers.md +141 −0
@@ -0,0 +1,141 @@
1 +# Module `d2c_dealers` — D2C Media
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/d2c_dealers.py`
8 +- **Sources membres** : 66
9 +- **Annonces actives (BD)** : 5229
10 +- **Backend de fetch** : requests direct — Firecrawl par source au besoin (`use_firecrawl`, sites derrière Cloudflare)
11 +- **Mécanique détectée** : sitemap, JSON-LD schema.org, endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `GirardAutos` → `girardautos` ; `ForceOccasion` → `forceoccasion` ; `GervaisAuto` → `gervaisauto` ; `EquipeFormule` → `equipeformule` ; `AutosEvasion` → `autosevasion` ; `MFerlandAuto` → `mferlandauto` … (+60)
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/d2c_dealers.py : connecteurs des concessionnaires sur plateforme
18 +> D2C Media (le fournisseur de sites le plus répandu chez les marchands
19 +> d'occasion au Québec).
20 +>
21 +> Stratégie : le sitemap (/fr/sitemap.xml) recense chaque page véhicule
22 +> (…-id123456.html). Chaque page détail expose un JSON-LD schema.org
23 +> complet (@type Vehicle/Car) : VIN, kilométrage, transmission, carburant,
24 +> carrosserie, couleurs, prix, photos. Les pages détail sont mises en cache
25 +> (clé hebdomadaire) : seuls les nouveaux véhicules — et une revalidation
26 +> par semaine pour les prix — génèrent de vraies requêtes.
27 +>
28 +> Enrichissement (clé de cache v3) — en plus du JSON-LD (qui ne liste que
29 +> 3 photos, parfois avec des ids corrompus — bug D2C) :
30 +> - galerie COMPLÈTE : les URLs imagescdn.d2cmedia.ca/<hash>/<dealer>/<id>/
31 +> <n>/… présentes dans le HTML (préférence à la variante « cb » grand
32 +> format, sinon « mb »/« s8 »), triées par index de photo ;
33 +> - endpoint JSON par véhicule /js/json/<id>.json (celui que le JS du site
34 +> appelle pour révéler la section « Options ») : optionsTextFR (liste
35 +> d'équipements en français), moteur + cylindre, carprooflink (rapport
36 +> Carfax direct quand le concessionnaire l'expose) ;
37 +> - repli équipements : titres des topFeatures/safetyFeatures du blob
38 +> window.__vdpJSON embarqué dans la page.
39 +>
40 +> Le lastmod du sitemap est bumpé quotidiennement par D2C (inutilisable
41 +> comme clé de cache) — d'où la clé temporelle hebdomadaire.
42 +
43 +## Complétude des champs (annonces actives, N = 5 229)
44 +
45 +| Champ | % rempli |
46 +|---|---|
47 +| Marque | 100.0 % |
48 +| Modèle | 100.0 % |
49 +| Année | 100.0 % |
50 +| Kilométrage | 100.0 % |
51 +| Prix | 99.6 % |
52 +| Carburant | 99.9 % |
53 +| Boîte (transmission) | 99.8 % |
54 +| VIN | 99.3 % |
55 +| Photos | 99.5 % |
56 +| Carfax | 16.1 % |
57 +| GPS (lat/lng) | 100.0 % |
58 +
59 +## Sources membres (BD live)
60 +
61 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
62 +|---|---|---|---|---|---|---|---|
63 +| `abitibiautocredit` | Abitibi Auto Crédit | Rouyn-Noranda | Abitibi-Témiscamingue | 91 | 85 | 2026-08-18 03:05 | OK (89 trouvés) |
64 +| `almahonda` | Alma Honda | Alma | Saguenay–Lac-Saint-Jean | 40 | 0 | 2026-08-17 23:35 | OK (40 trouvés) |
65 +| `autoquebeclevis` | AutoQuébec Occasion Lévis | Lévis | Chaudière-Appalaches | 77 | 0 | 2026-08-18 02:59 | OK (76 trouvés) |
66 +| `autoquebectm` | AutoQuébec Occasion Thetford Mines | Thetford Mines | Chaudière-Appalaches | 35 | 0 | 2026-08-18 03:01 | OK (35 trouvés) |
67 +| `autosevasion` | Autos Évasion | Sherbrooke | Estrie | 51 | 0 | 2026-08-18 02:46 | OK (50 trouvés) |
68 +| `autosoccasionld` | Autos Occasion LD | Lévis | Chaudière-Appalaches | 158 | 0 | 2026-08-18 02:53 | OK (158 trouvés) |
69 +| `autosthubert` | Auto St-Hubert | Saint-Hubert | Montérégie | 143 | 0 | 2026-08-18 03:22 | OK (138 trouvés) |
70 +| `autovilleneuve` | Automobile Villeneuve Amqui | Amqui | Bas-Saint-Laurent | 5 | 0 | 2026-08-17 23:35 | OK (5 trouvés) |
71 +| `berniercrepeau` | Bernier Crépeau | Trois-Rivières | Mauricie | 31 | 0 | 2026-08-17 23:34 | OK (31 trouvés) |
72 +| `charlesbourgtoyota` | Charlesbourg Toyota | Québec | Capitale-Nationale | 97 | 0 | 2026-08-17 23:35 | OK (97 trouvés) |
73 +| `charlevoixtoyota` | Charlevoix Toyota | La Malbaie | Capitale-Nationale | 50 | 0 | 2026-08-17 23:35 | OK (50 trouvés) |
74 +| `chomedeytoyota` | Chomedey Toyota Laval | Laval | Laval | 59 | 0 | 2026-08-17 23:34 | OK (59 trouvés) |
75 +| `drummondvilleford` | Drummondville Ford | Drummondville | Centre-du-Québec | 52 | 0 | 2026-08-17 23:34 | OK (52 trouvés) |
76 +| `drummondvillevw` | Drummondville Volkswagen | Drummondville | Centre-du-Québec | 80 | 0 | 2026-08-17 23:34 | OK (80 trouvés) |
77 +| `dubechrysler` | Dubé Chrysler | Rivière-du-Loup | Bas-Saint-Laurent | 162 | 0 | 2026-08-17 23:34 | OK (162 trouvés) |
78 +| `ducloslongueuil` | Duclos Longueuil Chrysler | Longueuil | Montérégie | 80 | 0 | 2026-08-17 23:34 | OK (80 trouvés) |
79 +| `dupontautomobile` | Dupont Automobile | Alma | Saguenay–Lac-Saint-Jean | 56 | 0 | 2026-08-17 23:35 | OK (56 trouvés) |
80 +| `dynastiehyundai` | Dynastie Hyundai | Rouyn-Noranda | Abitibi-Témiscamingue | 34 | 33 | 2026-08-17 23:34 | OK (34 trouvés) |
81 +| `equipeformule` | Équipe Formule | Rimouski | Bas-Saint-Laurent | 71 | 0 | 2026-08-18 02:44 | OK (69 trouvés) |
82 +| `fichaultkia` | Fichault Kia | Châteauguay | Montérégie | 35 | 0 | 2026-08-17 23:34 | OK (35 trouvés) |
83 +| `forceoccasion` | Force Occasion | Québec | Capitale-Nationale | 505 | 0 | 2026-08-18 02:20 | OK (490 trouvés) |
84 +| `fordthetford` | Ford Thetford | Thetford Mines | Chaudière-Appalaches | 33 | 0 | 2026-08-17 23:34 | OK (33 trouvés) |
85 +| `gaspesiehyundai` | Gaspésie Hyundai | Bonaventure | Gaspésie–Îles-de-la-Madeleine | 33 | 30 | 2026-08-17 23:34 | OK (33 trouvés) |
86 +| `gaspetoyota` | Gaspé Toyota | Gaspé | Gaspésie–Îles-de-la-Madeleine | 12 | 0 | 2026-08-17 23:34 | OK (12 trouvés) |
87 +| `gervaisauto` | Gervais Auto | Shawinigan | Mauricie | 559 | 0 | 2026-08-18 02:41 | OK (548 trouvés) |
88 +| `girardautos` | Girard Autos | Trois-Rivières | Mauricie | 20 | 0 | 2026-08-18 02:17 | OK (20 trouvés) |
89 +| `granbytoyota` | Granby Toyota | Granby | Montérégie | 20 | 0 | 2026-08-17 23:34 | OK (20 trouvés) |
90 +| `grandportage` | Groupe Grand-Portage | Rivière-du-Loup | Bas-Saint-Laurent | 112 | 0 | 2026-08-17 23:34 | OK (112 trouvés) |
91 +| `groupemotion` | Groupe Motion | Longueuil | Montérégie | 69 | 0 | 2026-08-17 23:34 | OK (69 trouvés) |
92 +| `groupepaquin` | Groupe Paquin | Rouyn-Noranda | Abitibi-Témiscamingue | 50 | 0 | 2026-08-17 23:34 | OK (50 trouvés) |
93 +| `hondacharlesbourg` | Honda Charlesbourg | Québec | Capitale-Nationale | 14 | 0 | 2026-08-17 23:35 | OK (14 trouvés) |
94 +| `hondacharlevoix` | Honda Charlevoix | La Malbaie | Capitale-Nationale | 35 | 0 | 2026-08-17 23:35 | OK (35 trouvés) |
95 +| `hondanewrichmond` | Honda New Richmond | New Richmond | Gaspésie–Îles-de-la-Madeleine | 60 | 0 | 2026-08-17 23:35 | OK (60 trouvés) |
96 +| `hullhyundai` | Hull Hyundai | Gatineau | Outaouais | 97 | 0 | 2026-08-17 23:34 | OK (97 trouvés) |
97 +| `hyundaibeauce` | Hyundai Beauce | Saint-Georges | Chaudière-Appalaches | 31 | 0 | 2026-08-17 23:35 | OK (31 trouvés) |
98 +| `hyundaicharlevoix` | Hyundai Charlevoix | Baie-Saint-Paul | Capitale-Nationale | 22 | 0 | 2026-08-17 23:35 | OK (22 trouvés) |
99 +| `hyundaidrummondville` | Hyundai Drummondville | Drummondville | Centre-du-Québec | 89 | 0 | 2026-08-17 23:35 | OK (89 trouvés) |
100 +| `hyundailanaudiere` | Hyundai Lanaudière | Joliette | Lanaudière | 60 | 0 | 2026-08-17 23:35 | OK (60 trouvés) |
101 +| `hyundailongueuil` | Hyundai Longueuil | Longueuil | Montérégie | 16 | 0 | 2026-08-17 23:35 | OK (16 trouvés) |
102 +| `hyundaistjerome` | Hyundai St-Jérôme | Mirabel | Laurentides | 115 | 0 | 2026-08-17 23:35 | OK (115 trouvés) |
103 +| `jeandumas` | Jean Dumas Multiconcessionnaire | Alma | Saguenay–Lac-Saint-Jean | 105 | 105 | 2026-08-17 23:35 | OK (105 trouvés) |
104 +| `jeandumasfordbc` | Jean Dumas Ford Baie-Comeau | Baie-Comeau | Côte-Nord | 105 | 0 | 2026-08-17 23:35 | OK (105 trouvés) |
105 +| `jeandumashondabc` | Jean Dumas Honda Baie-Comeau | Baie-Comeau | Côte-Nord | 105 | 105 | 2026-08-17 23:35 | OK (105 trouvés) |
106 +| `joliettemitsubishi` | Joliette Mitsubishi | Joliette | Lanaudière | 68 | 0 | 2026-08-17 23:35 | OK (68 trouvés) |
107 +| `kiabeauport` | Kia Beauport | Québec | Capitale-Nationale | 72 | 0 | 2026-08-17 23:35 | OK (72 trouvés) |
108 +| `kiajoliette` | Kia Joliette | Joliette | Lanaudière | 58 | 0 | 2026-08-17 23:35 | OK (58 trouvés) |
109 +| `lamihonda` | L'Ami Honda | Rouyn-Noranda | Abitibi-Témiscamingue | 91 | 0 | 2026-08-17 23:35 | OK (91 trouvés) |
110 +| `leoautomobile` | Léo Automobile | Chicoutimi | Saguenay–Lac-Saint-Jean | 62 | 0 | 2026-08-17 23:35 | OK (62 trouvés) |
111 +| `levisautos` | Lévis Autos | Lévis | Chaudière-Appalaches | 91 | 0 | 2026-08-18 02:56 | OK (83 trouvés) |
112 +| `levistoyota` | Lévis Toyota | Lévis | Chaudière-Appalaches | 45 | 0 | 2026-08-17 23:35 | OK (45 trouvés) |
113 +| `longueuilhonda` | Longueuil Honda | Longueuil | Montérégie | 44 | 0 | 2026-08-17 23:35 | OK (44 trouvés) |
114 +| `mferlandauto` | M. Ferland Auto | Sherbrooke | Estrie | 14 | 0 | 2026-08-18 02:47 | OK (13 trouvés) |
115 +| `nicoloccasion` | Nicol Occasion | La Sarre | Abitibi-Témiscamingue | 57 | 0 | 2026-08-18 03:07 | OK (57 trouvés) |
116 +| `olivierchryslerbc` | Olivier Chrysler Baie-Comeau | Baie-Comeau | Côte-Nord | 39 | 0 | 2026-08-17 23:35 | OK (39 trouvés) |
117 +| `olivierhyundaibc` | Olivier Hyundai Baie-Comeau | Baie-Comeau | Côte-Nord | 20 | 0 | 2026-08-17 23:35 | OK (20 trouvés) |
118 +| `olivieroccasionseptiles` | Olivier Occasion Sept-Îles | Sept-Îles | Côte-Nord | 88 | 0 | 2026-08-17 23:35 | OK (88 trouvés) |
119 +| `poirieroccasion` | Poirier Occasion | Val-d'Or | Abitibi-Témiscamingue | 231 | 0 | 2026-08-18 03:16 | OK (230 trouvés) |
120 +| `sherbrookeautooccasion` | Sherbrooke Auto Occasion | Sherbrooke | Estrie | 91 | 0 | 2026-08-17 23:34 | OK (91 trouvés) |
121 +| `stgeorgesgm` | St-Georges Chevrolet Buick GMC | Saint-Georges | Chaudière-Appalaches | 29 | 0 | 2026-08-17 23:35 | OK (29 trouvés) |
122 +| `stjeromemitsubishi` | St-Jérôme Mitsubishi | Saint-Jérôme | Laurentides | 129 | 0 | 2026-08-17 23:35 | OK (129 trouvés) |
123 +| `subaruvictoriaville` | Subaru Victoriaville | Victoriaville | Centre-du-Québec | 43 | 0 | 2026-08-17 23:35 | OK (43 trouvés) |
124 +| `toyotabdc` | Toyota Baie des Chaleurs | Caplan | Gaspésie–Îles-de-la-Madeleine | 39 | 3 | 2026-08-17 23:35 | OK (39 trouvés) |
125 +| `troisriviereshonda` | Trois-Rivières Honda | Trois-Rivières | Mauricie | 76 | 0 | 2026-08-17 23:35 | OK (76 trouvés) |
126 +| `trtoyota` | Trois-Rivières Toyota | Trois-Rivières | Mauricie | 58 | 0 | 2026-08-17 23:35 | OK (58 trouvés) |
127 +| `vaudreuilvw` | Vaudreuil Volkswagen | Vaudreuil-Dorion | Montérégie | 40 | 0 | 2026-08-17 23:35 | OK (40 trouvés) |
128 +| `vwsherbrooke` | VW Sherbrooke | Sherbrooke | Estrie | 70 | 0 | 2026-08-17 23:35 | OK (70 trouvés) |
129 +
130 +## Erreurs de synchronisation récentes (sync_log, ok = 0)
131 +
132 +| Source | Quand | Message |
133 +|---|---|---|
134 +| `hondacharlevoix` | 2026-08-16 19:00 | HTTPSConnectionPool(host='www.hondacharlevoix.com', port=443): Max retries exceeded with url: /fr/sitemap.xml (Caused by SSLError(SSLCertVerificationError(1, '[ |
135 +| `fordthetford` | 2026-08-16 18:59 | HTTPSConnectionPool(host='www.fordthetford.com', port=443): Max retries exceeded with url: /fr/sitemap.xml (Caused by SSLError(SSLCertVerificationError(1, '[SSL |
136 +| `fordthetford` | 2026-08-16 16:36 | HTTPSConnectionPool(host='www.fordthetford.com', port=443): Max retries exceeded with url: /fr/sitemap.xml (Caused by SSLError(SSLCertVerificationError(1, '[SSL |
137 +| `hondacharlevoix` | 2026-08-16 09:24 | HTTPSConnectionPool(host='www.hondacharlevoix.com', port=443): Max retries exceeded with url: /fr/sitemap.xml (Caused by SSLError(SSLCertVerificationError(1, '[ |
138 +| `fordthetford` | 2026-08-16 09:24 | HTTPSConnectionPool(host='www.fordthetford.com', port=443): Max retries exceeded with url: /fr/sitemap.xml (Caused by SSLError(SSLCertVerificationError(1, '[SSL |
139 +| `fordthetford` | 2026-08-16 02:13 | HTTPSConnectionPool(host='www.fordthetford.com', port=443): Max retries exceeded with url: /fr/sitemap.xml (Caused by SSLError(SSLCertVerificationError(1, '[SSL |
140 +| `poirieroccasion` | 2026-08-12 08:46 | 404 Client Error: Not Found for url: https://www.poirieroccasion.com/occasion/Hyundai-Palisade-2021-id12939722.html |
141 +| `equipeformule` | 2026-08-12 08:37 | ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) |
added docs/connecteurs/desmeules.md +62 −0
@@ -0,0 +1,62 @@
1 +# Module `desmeules` — ColdFusion maison + AutoJini
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/desmeules.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 243
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : flux RSS, microdata schema.org
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `DesmeulesChrysler` → `desmeules`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/desmeules.py : connecteur Desmeules Chrysler (desmeules.ca),
18 +> gros concessionnaire Chrysler/Dodge/Jeep/RAM de Laval — ~220 véhicules
19 +> d'occasion.
20 +>
21 +> Plateforme : ColdFusion maison + inventaire AutoJini (photos
22 +> images.autojini.net). La page occasion expose un flux RSS complet :
23 +> /fr/vehicules-doccasion/?fuseaction=inventory.feedRSS&ajaxCall=1
24 +> -> un <item> par véhicule : titre (année marque modèle + prix), lien
25 +> détail (…-v<id>.html), no de stock, VIN, photo, longue description.
26 +>
27 +> La page détail complète : kilométrage (detailsMileageData), moteur,
28 +> transmission/entraînement (microdata) et galerie photos. Elle porte aussi
29 +> la liste d'équipements AutoJini (« Équipement standard », divs .column :
30 +> h3 catégorie + ul d'items) dont la section « Transmission & Moteur »
31 +> contient le carburant (« Essence », « Plug-in électric / gas »…) et la
32 +> motricité (« Traction Intégrale », « Quatre roues motrices »…), ainsi
33 +> qu'une boîte « Catégorie » (Car/VUS/SUV/Truck) pour la carrosserie.
34 +> Ces pages sont mises en cache BD à vie (clé stable — les specs ne
35 +> changent pas ; le prix frais vient du RSS). AUTOKA_MAX_DETAILS (env)
36 +> plafonne les vraies requêtes détail par synchronisation.
37 +
38 +## Complétude des champs (annonces actives, N = 243)
39 +
40 +| Champ | % rempli |
41 +|---|---|
42 +| Marque | 99.2 % |
43 +| Modèle | 100.0 % |
44 +| Année | 100.0 % |
45 +| Kilométrage | 100.0 % |
46 +| Prix | 98.4 % |
47 +| Carburant | 83.1 % |
48 +| Boîte (transmission) | 98.4 % |
49 +| VIN | 99.6 % |
50 +| Photos | 100.0 % |
51 +| Carfax | 0.0 % |
52 +| GPS (lat/lng) | 100.0 % |
53 +
54 +## Sources membres (BD live)
55 +
56 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
57 +|---|---|---|---|---|---|---|---|
58 +| `desmeules` | Desmeules Chrysler | Laval | Laval | 243 | 0 | 2026-08-17 23:35 | OK (243 trouvés) |
59 +
60 +## Erreurs de synchronisation récentes
61 +
62 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/dupontford.md +55 −0
@@ -0,0 +1,55 @@
1 +# Module `dupontford` — WordPress Leadbox lbx-egypt
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/dupontford.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 65
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, endpoint JSON
12 +- **Plafonds / cache** : cache détail BD (detail_cache)
13 +- **Classes** : `DupontDupontFord` → `dupontdupontford`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/dupontford.py : connecteur Dupont & Dupont Ford
18 +> (dupontdupontford.com), concessionnaire Ford de Gatineau.
19 +>
20 +> Plateforme : WordPress + thème Leadbox « lbx-egypt » (SPA Vue pour
21 +> l'inventaire). Le SPA charge un export JSON statique complet :
22 +> /wp-content/uploads/data/inventory.json -> {"vehicles": [...]} où chaque
23 +> véhicule est COMPLET : condition (New/Used), année, marque, modèle,
24 +> version, prix, km, VIN, stock, transmission, rouage, carburant,
25 +> carrosserie, moteur, couleur, photo, description. UNE seule requête pour
26 +> tout l'inventaire — on filtre condition == Used (voitures seulement).
27 +>
28 +> URL détail reconstruite comme dans le sitemap inventory.xml :
29 +> /vue/used-<année>-<marque>-<modèle>-<id>/.
30 +
31 +## Complétude des champs (annonces actives, N = 65)
32 +
33 +| Champ | % rempli |
34 +|---|---|
35 +| Marque | 100.0 % |
36 +| Modèle | 100.0 % |
37 +| Année | 100.0 % |
38 +| Kilométrage | 100.0 % |
39 +| Prix | 98.5 % |
40 +| Carburant | 100.0 % |
41 +| Boîte (transmission) | 100.0 % |
42 +| VIN | 100.0 % |
43 +| Photos | 92.3 % |
44 +| Carfax | 0.0 % |
45 +| GPS (lat/lng) | 100.0 % |
46 +
47 +## Sources membres (BD live)
48 +
49 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
50 +|---|---|---|---|---|---|---|---|
51 +| `dupontdupontford` | Dupont & Dupont Ford | Gatineau | Outaouais | 65 | 0 | 2026-08-17 23:35 | OK (65 trouvés) |
52 +
53 +## Erreurs de synchronisation récentes
54 +
55 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/gatsby_dealers.md +66 −0
@@ -0,0 +1,66 @@
1 +# Module `gatsby_dealers` — Gatsby autoroot.io / EvalAuto
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/gatsby_dealers.py`
8 +- **Sources membres** : 6
9 +- **Annonces actives (BD)** : 191
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, GraphQL, AWS AppSync, page-data Gatsby, endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, AUTOKA_MAX_PAGES
13 +- **Classes** : `KiaGranby` → `kiagranby` ; `KiaDrummondville` → `kiadrummondville` ; `MazdaDeSherbrooke` → `mazdadesherbrooke` ; `MitsubishiDrummondville` → `mitsubishidrummondville` ; `NissanDrummondville` → `nissandrummondville` ; `NissanVictoriaville` → `nissanvictoriaville`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/gatsby_dealers.py : connecteurs des concessionnaires de marque
18 +> sur la plateforme Gatsby « autoroot.io » (inventaire EvalAuto — Groupe
19 +> Beaucage : Kia Granby/Drummondville, Mazda Sherbrooke, Mitsubishi et
20 +> Nissan Drummondville, Nissan Victoriaville).
21 +>
22 +> Même plateforme que megacentredeliquidation (voir megacentre.py) : chaque
23 +> véhicule expose /page-data/auto-usage/<slug>/page-data.json -> `usedCar`
24 +> complet. MAIS contrairement au Méga Centre, le sitemap de ces sites ne
25 +> référence pas les pages véhicule individuelles — seulement les pages
26 +> catégorie. L'énumération passe donc par l'API AWS AppSync que le site
27 +> utilise lui-même côté client : le endpoint GraphQL et la clé x-api-key
28 +> sont publiés dans siteParameters du page-data de la page liste
29 +> (/page-data/auto-usage/page-data.json). La requête
30 +> getUsedCarSearchByRelevanceMultiTable, filtrée par nameDealer, renvoie
31 +> 30 items/page + nextFilter (curseur) -> tous les slugs.
32 +>
33 +> Le reste (cache hebdo des page-data détail, plafond AUTOKA_MAX_DETAILS,
34 +> usedCar -> Vehicle) est hérité de MegaCentreDeLiquidation.
35 +> AUTOKA_MAX_PAGES (env) limite la pagination AppSync pour les tests.
36 +
37 +## Complétude des champs (annonces actives, N = 191)
38 +
39 +| Champ | % rempli |
40 +|---|---|
41 +| Marque | 100.0 % |
42 +| Modèle | 100.0 % |
43 +| Année | 100.0 % |
44 +| Kilométrage | 100.0 % |
45 +| Prix | 100.0 % |
46 +| Carburant | 100.0 % |
47 +| Boîte (transmission) | 100.0 % |
48 +| VIN | 100.0 % |
49 +| Photos | 100.0 % |
50 +| Carfax | 51.3 % |
51 +| GPS (lat/lng) | 100.0 % |
52 +
53 +## Sources membres (BD live)
54 +
55 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
56 +|---|---|---|---|---|---|---|---|
57 +| `kiadrummondville` | Kia Drummondville | Drummondville | Centre-du-Québec | 22 | 0 | 2026-08-17 23:35 | OK (22 trouvés) |
58 +| `kiagranby` | Kia de Granby | Granby | Montérégie | 19 | 0 | 2026-08-17 23:35 | OK (19 trouvés) |
59 +| `mazdadesherbrooke` | Mazda de Sherbrooke | Sherbrooke | Estrie | 49 | 0 | 2026-08-17 23:35 | OK (49 trouvés) |
60 +| `mitsubishidrummondville` | Mitsubishi Drummondville | Drummondville | Centre-du-Québec | 14 | 0 | 2026-08-17 23:35 | OK (14 trouvés) |
61 +| `nissandrummondville` | Nissan Drummondville | Drummondville | Centre-du-Québec | 44 | 0 | 2026-08-17 23:35 | OK (44 trouvés) |
62 +| `nissanvictoriaville` | Nissan de Victoriaville | Victoriaville | Centre-du-Québec | 43 | 0 | 2026-08-17 23:35 | OK (43 trouvés) |
63 +
64 +## Erreurs de synchronisation récentes
65 +
66 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/hgregoire.md +72 −0
@@ -0,0 +1,72 @@
1 +# Module `hgregoire` — Site custom
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/hgregoire.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 1672
10 +- **Backend de fetch** : Scrapfly
11 +- **Mécanique détectée** : blob JSON data-class
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, AUTOKA_MAX_PAGES, cache détail BD (detail_cache)
13 +- **Classes** : `HGregoire` → `hgregoire`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/hgregoire.py : connecteur HGrégoire (hgregoire.com), la plus
18 +> grosse chaîne de mégacentres d'occasion au Québec (St-Léonard, Laval,
19 +> St-Eustache, Saguenay/Chicoutimi, Carbonear/Gaspésie, etc.).
20 +>
21 +> Stratégie : la page de résultats /auto-usage?page=N est rendue côté
22 +> serveur (WordPress custom) et embarque, pour CHAQUE carte véhicule, un
23 +> <script type="application/json" data-class="Vehicle"> complet :
24 +> Id, année/marque/modèle/version, prix (CAD), odomètre, VIN, no de stock,
25 +> transmission, carburant, traction, carrosserie, couleurs, moteur,
26 +> consommation, photo principale, Permalink ET la succursale du véhicule
27 +> (FullLocation.city + province). 24 véhicules par page, ~74 pages —
28 +> AUCUNE page détail nécessaire : ~75 requêtes pour tout l'inventaire.
29 +>
30 +> Seules les succursales du QUÉBEC sont conservées (FullLocation.province
31 +> == "QC") — le groupe opère aussi aux États-Unis (hgreg.com) et un
32 +> véhicule hors-Québec serait exclu par ce garde-fou.
33 +>
34 +> robots.txt demande Crawl-delay: 10 → request_delay élevé (sync complet
35 +> ≈ 12 min, acceptable pour une synchronisation quotidienne).
36 +> AUTOKA_MAX_PAGES (env) limite le nombre de pages pour les tests.
37 +>
38 +> ENRICHISSEMENT DÉTAIL (galerie + équipements) : la carte liste n'a qu'UNE
39 +> photo et quelques équipements ; la page détail expose la galerie complète
40 +> (~25 photos) et l'onglet « Équipements » (~40 items). Avec Crawl-delay: 10
41 +> un crawl direct des ~1 700 fiches prendrait ~4,7 h → les pages détail
42 +> passent par SCRAPFLY (requêtes gérées par leur infra, non soumises au
43 +> crawl-delay de notre IP). Cache BD à vie (clé stable « v1 » — la galerie
44 +> et les équipements ne changent pas), plafond AUTOKA_MAX_DETAILS (défaut
45 +> 300/sync) : l'inventaire complet s'enrichit en ~6 synchronisations.
46 +> Le véhicule est toujours émis avec les données liste même sans détail.
47 +
48 +## Complétude des champs (annonces actives, N = 1 672)
49 +
50 +| Champ | % rempli |
51 +|---|---|
52 +| Marque | 100.0 % |
53 +| Modèle | 100.0 % |
54 +| Année | 100.0 % |
55 +| Kilométrage | 100.0 % |
56 +| Prix | 100.0 % |
57 +| Carburant | 100.0 % |
58 +| Boîte (transmission) | 100.0 % |
59 +| VIN | 100.0 % |
60 +| Photos | 100.0 % |
61 +| Carfax | 0.0 % |
62 +| GPS (lat/lng) | 100.0 % |
63 +
64 +## Sources membres (BD live)
65 +
66 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
67 +|---|---|---|---|---|---|---|---|
68 +| `hgregoire` | HGrégoire | St-Léonard | Montréal | 1672 | 2 | 2026-08-17 23:48 | OK (1672 trouvés) |
69 +
70 +## Erreurs de synchronisation récentes
71 +
72 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/jlkauto.md +50 −0
@@ -0,0 +1,50 @@
1 +# Module `jlkauto` — EDealer
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/jlkauto.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 68
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, JSON-LD schema.org
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `JLKAuto` → `jlkauto`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/jlkauto.py : JLK Auto (Montréal) — plateforme EDealer
18 +> (edealer.ca ; WordPress + inventaire EDealer, CDN media.edealer.ca).
19 +>
20 +> Stratégie : le sitemap Yoast `/inventory-listing-sitemap.xml` recense les
21 +> pages véhicule (…-<token>vdp/) en FR et EN. Chaque page détail (VDP)
22 +> expose un JSON-LD schema.org @graph avec un nœud @type [Product, Car]
23 +> complet : prix, VIN, km, transmission, carrosserie, couleurs, moteur.
24 +> Pages détail mises en cache BD (clé hebdomadaire), comme les sites D2C.
25 +
26 +## Complétude des champs (annonces actives, N = 68)
27 +
28 +| Champ | % rempli |
29 +|---|---|
30 +| Marque | 100.0 % |
31 +| Modèle | 100.0 % |
32 +| Année | 100.0 % |
33 +| Kilométrage | 98.5 % |
34 +| Prix | 100.0 % |
35 +| Carburant | 100.0 % |
36 +| Boîte (transmission) | 100.0 % |
37 +| VIN | 100.0 % |
38 +| Photos | 100.0 % |
39 +| Carfax | 0.0 % |
40 +| GPS (lat/lng) | 100.0 % |
41 +
42 +## Sources membres (BD live)
43 +
44 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
45 +|---|---|---|---|---|---|---|---|
46 +| `jlkauto` | JLK Auto | Montréal | Montréal | 68 | 0 | 2026-08-17 23:48 | OK (68 trouvés) |
47 +
48 +## Erreurs de synchronisation récentes
49 +
50 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/kijiji.md +61 −0
@@ -0,0 +1,61 @@
1 +# Module `kijiji` — Next.js/Apollo — le SRP embarque les AutosListing complets dans __NEXT_DATA__
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/kijiji.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 3002
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : __NEXT_DATA__
12 +- **Plafonds / cache** : aucun
13 +- **Classes** : `KijijiParticuliers` → `kijiji`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/kijiji.py : annonces de PARTICULIERS — Kijiji (kijiji.ca)
18 +>
19 +> Note : Kijiji Autos (kijijiautos.ca, plateforme MoVe/m.mobile.de) n'existe
20 +> plus — le domaine ne résout plus (SERVFAIL, constaté 2026-08-18) ; les
21 +> annonces ont été rapatriées sur kijiji.ca. On cible donc la catégorie
22 +> « Autos et camions » (c174) du Québec (l9001), filtrée vendeur particulier
23 +> (?for-sale-by=ownr) pour ne pas dupliquer l'inventaire des concessionnaires
24 +> déjà couverts par les autres connecteurs.
25 +>
26 +> Stratégie : les pages liste (SRP) de kijiji.ca (Next.js) embarquent le
27 +> cache Apollo complet dans <script id="__NEXT_DATA__"> — chaque annonce y
28 +> est un objet AutosListing structuré : marque/modèle/année/km canoniques,
29 +> prix (en cents), carburant/boîte/rouage/carrosserie, couleurs, portes,
30 +> places, VIN (quand le vendeur l'a saisi), lien Carfax, photos CDN et
31 +> surtout la géolocalisation exacte (lat/lng + adresse). Aucune page détail
32 +> n'est nécessaire : tout est dans la liste — 40 annonces/requête.
33 +>
34 +> Pagination : /b-autos-camions/quebec/page-N/c174l9001?for-sale-by=ownr
35 +> jusqu'à totalCount (bornée par MAX_PAGES par politesse).
36 +
37 +## Complétude des champs (annonces actives, N = 3 002)
38 +
39 +| Champ | % rempli |
40 +|---|---|
41 +| Marque | 100.0 % |
42 +| Modèle | 100.0 % |
43 +| Année | 99.6 % |
44 +| Kilométrage | 100.0 % |
45 +| Prix | 94.4 % |
46 +| Carburant | 62.9 % |
47 +| Boîte (transmission) | 64.5 % |
48 +| VIN | 22.0 % |
49 +| Photos | 99.6 % |
50 +| Carfax | 2.2 % |
51 +| GPS (lat/lng) | 100.0 % |
52 +
53 +## Sources membres (BD live)
54 +
55 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
56 +|---|---|---|---|---|---|---|---|
57 +| `kijiji` | Kijiji (particuliers) | — | — | 3002 | 10 | 2026-08-18 02:09 | OK (3002 trouvés) |
58 +
59 +## Erreurs de synchronisation récentes
60 +
61 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/leprixdugros.md +71 −0
@@ -0,0 +1,71 @@
1 +# Module `leprixdugros` — WordPress Stereodev
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/leprixdugros.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 886
10 +- **Backend de fetch** : Scrapfly
11 +- **Mécanique détectée** : endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, AUTOKA_MAX_PAGES, cache détail BD (detail_cache)
13 +- **Classes** : `LePrixDuGros` → `leprixdugros`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/leprixdugros.py : connecteur Le Prix du Gros (leprixdugros.com),
18 +> groupe Mauricie / Centre-du-Québec (Kia, Nissan, Hyundai, Mazda + méga
19 +> centre d'occasion) — Trois-Rivières, Shawinigan, Donnacona, Lévis,
20 +> Québec, Laval, Sherbrooke, Joliette. INVENTAIRE OCCASION UNIQUEMENT.
21 +>
22 +> Plateforme : WordPress custom (thème Stereodev « lpdg-2022 »). La page
23 +> liste expose un endpoint JSON paginé non documenté (celui du filtre Vue) :
24 +> /inventaire/occasion/?output=json&pg=N -> {items(36/page), total, page}.
25 +> Chaque item : année/marque/modèle/version, km, VIN, prix, rabais, stock,
26 +> photo, permalien. ~37 pages pour ~1 300 véhicules d'occasion.
27 +>
28 +> La page détail (permalien) complète : moteur, rouage, transmission,
29 +> passagers, couleurs, photos ET la concession où se trouve le véhicule
30 +> (bloc « c-single-car-map-location » : nom + ville). Ces pages sont mises
31 +> en cache BD à vie (clé stable — les specs ne changent pas ; le prix et le
32 +> km frais viennent de la liste). AUTOKA_MAX_DETAILS (env) plafonne les
33 +> vraies requêtes détail par sync ; AUTOKA_MAX_PAGES limite la pagination.
34 +>
35 +> NOTE : les pages détail n'ont NI description NI liste d'équipements par
36 +> véhicule (les blocs « cards » sont du boilerplate : inspection 150 points,
37 +> reconditionnement) — rien à extraire de plus que les specs/ville/photos.
38 +> Le site est parfois lent (timeouts ponctuels) : chaque page détail tente
39 +> d'abord un GET direct, puis bascule sur Scrapfly en cas d'échec ; le
40 +> try/except par annonce garantit l'émission avec les données liste.
41 +> Carburant : la source ne l'affiche jamais ; en plus des jetons explicites
42 +> (hybride/EV/diesel), un moteur « N cylindres X.XL » sans indice électrifié
43 +> => Essence (sauf modèles hybrides « sans badge » connus, ex. Prius).
44 +
45 +## Complétude des champs (annonces actives, N = 886)
46 +
47 +| Champ | % rempli |
48 +|---|---|
49 +| Marque | 100.0 % |
50 +| Modèle | 100.0 % |
51 +| Année | 100.0 % |
52 +| Kilométrage | 100.0 % |
53 +| Prix | 99.9 % |
54 +| Carburant | 97.4 % |
55 +| Boîte (transmission) | 100.0 % |
56 +| VIN | 100.0 % |
57 +| Photos | 100.0 % |
58 +| Carfax | 0.0 % |
59 +| GPS (lat/lng) | 42.0 % |
60 +
61 +## Sources membres (BD live)
62 +
63 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
64 +|---|---|---|---|---|---|---|---|
65 +| `leprixdugros` | Le Prix du Gros | Trois-Rivières | Mauricie | 886 | 653 | 2026-08-18 01:44 | OK (107 trouvés) |
66 +
67 +## Erreurs de synchronisation récentes (sync_log, ok = 0)
68 +
69 +| Source | Quand | Message |
70 +|---|---|---|
71 +| `leprixdugros` | 2026-08-12 08:47 | HTTPSConnectionPool(host='www.leprixdugros.com', port=443): Read timed out. (read timeout=30) |
added docs/connecteurs/magnetis_dealers.md +62 −0
@@ -0,0 +1,62 @@
1 +# Module `magnetis_dealers` — WordPress magnetis-dealer / SyncAuto
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/magnetis_dealers.py`
8 +- **Sources membres** : 4
9 +- **Annonces actives (BD)** : 423
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, JSON-LD schema.org, blob JSON data-class
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `BaieComeauToyota` → `baiecomeautoyota` ; `SherbrookeToyota` → `sherbrooketoyota` ; `StGeorgesNissan` → `stgnissan` ; `LussierChevrolet` → `lussierchevrolet`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/magnetis_dealers.py : connecteurs des concessionnaires sur la
18 +> plateforme WordPress « magnetis-dealer » (agence Magnetis, inventaire
19 +> SyncAuto — photos syncauto-XX.s3.ca-central-1.amazonaws.com).
20 +>
21 +> Stratégie : le sitemap /inventory-sitemap.xml recense chaque page
22 +> véhicule /inventaire/occasion/<année>/<marque>/<modèle>/<id> (versions FR
23 +> et EN ; on ne garde que les FR, occasion seulement — le neuf vit sous
24 +> /inventaire/neuf/). Chaque page détail embarque :
25 +> - <script data-class="Vehicle"> : JSON complet (marque, modèle, année,
26 +> version, km, prix, transmission, rouage, carburant, carrosserie,
27 +> portes, passagers, couleur, no stock ET la concession réelle du
28 +> véhicule avec sa ville — certains sites du réseau affichent
29 +> l'inventaire de concessions sœurs) ;
30 +> - des JSON-LD schema.org @type Vehicle (le bon = productID == id) :
31 +> VIN, photos, description, vendeur.
32 +> Pages détail en cache BD (clé hebdomadaire) ; AUTOKA_MAX_DETAILS (env)
33 +> plafonne les vraies requêtes détail par synchronisation.
34 +
35 +## Complétude des champs (annonces actives, N = 423)
36 +
37 +| Champ | % rempli |
38 +|---|---|
39 +| Marque | 100.0 % |
40 +| Modèle | 100.0 % |
41 +| Année | 99.8 % |
42 +| Kilométrage | 98.3 % |
43 +| Prix | 100.0 % |
44 +| Carburant | 94.3 % |
45 +| Boîte (transmission) | 88.2 % |
46 +| VIN | 2.4 % |
47 +| Photos | 2.1 % |
48 +| Carfax | 0.0 % |
49 +| GPS (lat/lng) | 100.0 % |
50 +
51 +## Sources membres (BD live)
52 +
53 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
54 +|---|---|---|---|---|---|---|---|
55 +| `baiecomeautoyota` | Baie-Comeau Toyota | Baie-Comeau | Côte-Nord | 247 | 0 | 2026-08-18 01:43 | OK (10 trouvés) |
56 +| `lussierchevrolet` | Lussier Chevrolet Buick GMC | Saint-Hyacinthe | Montérégie | 83 | 0 | 2026-08-17 23:49 | OK (83 trouvés) |
57 +| `sherbrooketoyota` | Sherbrooke Toyota | Sherbrooke | Estrie | 63 | 0 | 2026-08-17 23:49 | OK (63 trouvés) |
58 +| `stgnissan` | St-Georges Nissan | Saint-Georges | Chaudière-Appalaches | 30 | 0 | 2026-08-17 23:49 | OK (30 trouvés) |
59 +
60 +## Erreurs de synchronisation récentes
61 +
62 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/megacentre.md +60 −0
@@ -0,0 +1,60 @@
1 +# Module `megacentre` — Gatsby / EvalAuto
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/megacentre.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 455
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, page-data Gatsby, endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `MegaCentreDeLiquidation` → `megacentredeliquidation`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/megacentre.py : connecteur Méga Centre de liquidation
18 +> (megacentredeliquidation.com), place de marché d'occasion du Groupe
19 +> Laplante — Québec, Trois-Rivières, Rimouski, Matane, Mont-Joli, Amqui,
20 +> Rawdon (Lanaudière), etc.
21 +>
22 +> Plateforme : Gatsby (site statique sur Fastly), inventaire EvalAuto.
23 +> Le sitemap (/sitemap-index.xml -> /sitemap-0.xml) recense chaque page
24 +> véhicule /auto-usage/<marque-modele-annee-stock>/. Pour chaque slug, le
25 +> JSON Gatsby /page-data/auto-usage/<slug>/page-data.json expose l'objet
26 +> `usedCar` complet : prix, odomètre, NIV, stock, transmission, rouage,
27 +> carburant, carrosserie, couleurs, moteur, portes, places, options,
28 +> description, photos, CarProof ET la concession réelle du véhicule
29 +> (nameDealer + cityDealer — la ville par véhicule).
30 +>
31 +> Les page-data sont mises en cache BD (clé hebdomadaire, même logique que
32 +> les connecteurs D2C) : seuls les nouveaux véhicules et la revalidation
33 +> hebdomadaire génèrent de vraies requêtes. AUTOKA_MAX_DETAILS (env)
34 +> plafonne les vraies requêtes détail par synchronisation.
35 +
36 +## Complétude des champs (annonces actives, N = 455)
37 +
38 +| Champ | % rempli |
39 +|---|---|
40 +| Marque | 100.0 % |
41 +| Modèle | 100.0 % |
42 +| Année | 100.0 % |
43 +| Kilométrage | 100.0 % |
44 +| Prix | 100.0 % |
45 +| Carburant | 99.3 % |
46 +| Boîte (transmission) | 97.4 % |
47 +| VIN | 100.0 % |
48 +| Photos | 99.1 % |
49 +| Carfax | 69.2 % |
50 +| GPS (lat/lng) | 100.0 % |
51 +
52 +## Sources membres (BD live)
53 +
54 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
55 +|---|---|---|---|---|---|---|---|
56 +| `megacentredeliquidation` | Méga Centre de liquidation | Mont-Joli | Bas-Saint-Laurent | 455 | 451 | 2026-08-17 23:35 | OK (455 trouvés) |
57 +
58 +## Erreurs de synchronisation récentes
59 +
60 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/montjolichrysler.md +53 −0
@@ -0,0 +1,53 @@
1 +# Module `montjolichrysler` — Next.js RSC autoroot.io / EvalAuto
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/montjolichrysler.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 414
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : flux RSC Next.js
12 +- **Plafonds / cache** : aucun
13 +- **Classes** : `MontJoliChrysler` → `montjolichrysler`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/montjolichrysler.py : connecteur Chrysler Mont-Joli
18 +> (montjolichrysler.com), concessionnaire Chrysler/Dodge/Jeep/RAM de
19 +> Mont-Joli (Bas-Saint-Laurent, près de Rimouski et Matane).
20 +>
21 +> Plateforme : Next.js App Router (autoroot.io), inventaire EvalAuto —
22 +> même moteur qu'Occasion Beaucage / Ste-Foy Chrysler : les pages liste
23 +> /auto-usage/<n>/ embarquent dans leur flux RSC (self.__next_f.push)
24 +> l'objet {"vehicles":[...],"count":N} complet (prix, km, VIN, stock,
25 +> transmission, carburant, carrosserie, couleurs, photos,
26 +> display_dealer_name / display_city). On réutilise OccasionBeaucage,
27 +> seuls l'URL et les libellés changent.
28 +
29 +## Complétude des champs (annonces actives, N = 414)
30 +
31 +| Champ | % rempli |
32 +|---|---|
33 +| Marque | 100.0 % |
34 +| Modèle | 100.0 % |
35 +| Année | 100.0 % |
36 +| Kilométrage | 100.0 % |
37 +| Prix | 100.0 % |
38 +| Carburant | 99.8 % |
39 +| Boîte (transmission) | 99.8 % |
40 +| VIN | 100.0 % |
41 +| Photos | 100.0 % |
42 +| Carfax | 75.1 % |
43 +| GPS (lat/lng) | 100.0 % |
44 +
45 +## Sources membres (BD live)
46 +
47 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
48 +|---|---|---|---|---|---|---|---|
49 +| `montjolichrysler` | Chrysler Mont-Joli | Mont-Joli | Bas-Saint-Laurent | 414 | 382 | 2026-08-17 23:50 | OK (414 trouvés) |
50 +
51 +## Erreurs de synchronisation récentes
52 +
53 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/moto_dealers.md +90 −0
@@ -0,0 +1,90 @@
1 +# Module `moto_dealers` — PowerGo
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/moto_dealers.py`
8 +- **Sources membres** : 13
9 +- **Annonces actives (BD)** : 630
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, JSON-LD schema.org, endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, AUTOKA_MAX_PAGES, cache détail BD (detail_cache)
13 +- **Classes** : `MathiasSports` → `mathiassports` ; `SMSport` → `smsport` ; `MotosIllimitees` → `motosillimitees` ; `RMMotosport` → `rmmotosport` ; `GLSport` → `glsport` ; `ExcelMoto` → `excelmoto` … (+7)
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/moto_dealers.py : verticale MOTOS & SCOOTERS usagés — connecteurs
18 +> des concessionnaires de motocyclettes/scooters du Québec.
19 +>
20 +> Chaque véhicule émis porte kind="moto" ou kind="scooter" (jamais "auto").
21 +> Les motoneiges, VTT, côte-à-côte, motomarines, bateaux, VR et vélos sont
22 +> systématiquement EXCLUS. Les marques moto (Harley-Davidson, Indian, KTM,
23 +> Vespa…) ne sont pas dans normalize.MAKES : make est TOUJOURS rempli
24 +> explicitement depuis la source (JSON inventaire ou brand JSON-LD), on ne
25 +> compte jamais sur split_title().
26 +>
27 +> Plateformes rencontrées dans cette verticale :
28 +>
29 +> 1. PowerGo (powergo.ca) — de très loin la plus répandue chez les
30 +> concessionnaires de sports motorisés au Québec (l'équivalent moto de
31 +> D2C Media côté autos). Sites Next.js ; l'inventaire COMPLET (neuf +
32 +> usagé, tous types) est publié dans un JSON public :
33 +> <base>/data/vehicles-inventory-fr-items.json
34 +> → type, category, conditionCode (new/used), make, model, year, prix,
35 +> usage (km), stock, URL de la page détail, 1re photo (gabarit CDN).
36 +> Chaque page détail expose en plus un JSON-LD schema.org @type Vehicle
37 +> (parfois dans un @graph) : galerie complète, description, couleur,
38 +> kilométrage… Pages détail en cache BD, clé = prix+km du listing (donc
39 +> revalidation automatique quand le prix ou le km change).
40 +> NB : les sites PowerGo « ancien gabarit » (premonthd.com, lavalmoto.com,
41 +> motojmf.com, motopro.ca…) n'exposent PAS ce JSON (listing 100 % JS).
42 +>
43 +> 2. Magento/Traction (Moto Ducharme) — listing HTML server-rendered
44 +> par catégorie (/fr/vehicules-d-occasion/motocyclettes), pages détail
45 +> avec JSON-LD @type Product + table de spécifications (Kilométrage,
46 +> Couleur…) + galerie JSON Magento.
47 +>
48 +> 3. D2C Media — aucun des concessionnaires moto candidats sondés n'y est
49 +> (PowerGo domine cette verticale), mais la base D2CMotoConnector est
50 +> prête : mêmes mécanismes que D2CConnector (sitemap /fr/sitemap.xml +
51 +> JSON-LD des pages /occasion/…-idNNN.html), avec un filtre de segments
52 +> INVERSÉ (inclut motos/scooters, exclut le reste) et kind rempli.
53 +
54 +## Complétude des champs (annonces actives, N = 630)
55 +
56 +| Champ | % rempli |
57 +|---|---|
58 +| Marque | 100.0 % |
59 +| Modèle | 100.0 % |
60 +| Année | 99.7 % |
61 +| Kilométrage | 93.5 % |
62 +| Prix | 98.7 % |
63 +| Carburant | 60.3 % |
64 +| Boîte (transmission) | 0.6 % |
65 +| VIN | 6.2 % |
66 +| Photos | 100.0 % |
67 +| Carfax | 0.0 % |
68 +| GPS (lat/lng) | 100.0 % |
69 +
70 +## Sources membres (BD live)
71 +
72 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
73 +|---|---|---|---|---|---|---|---|
74 +| `excelmoto` | Excel Moto | Montréal | Montréal | 8 | 0 | 2026-08-17 23:50 | OK (8 trouvés) |
75 +| `gabrielharleydavidson` | Gabriel Harley-Davidson Montréal | Montréal | Montréal | 26 | 0 | 2026-08-17 23:50 | OK (26 trouvés) |
76 +| `glsport` | GL Sport | Saint-Gervais | Chaudière-Appalaches | 14 | 0 | 2026-08-17 23:50 | OK (14 trouvés) |
77 +| `groupecontant` | Groupe Contant | Repentigny | Lanaudière | 46 | 0 | 2026-08-17 23:50 | OK (46 trouvés) |
78 +| `groupeimperium` | Groupe Imperium | Chicoutimi | Saguenay–Lac-Saint-Jean | 22 | 0 | 2026-08-17 23:50 | OK (22 trouvés) |
79 +| `mathiassports` | Mathias Sports | Saint-Mathias-sur-Richelieu | Montérégie | 103 | 0 | 2026-08-18 01:45 | OK (103 trouvés) |
80 +| `mecamoto` | Mecamoto | Montréal | Montréal | 14 | 0 | 2026-08-17 23:50 | OK (14 trouvés) |
81 +| `motoducharme` | Moto Ducharme | Joliette | Lanaudière | 14 | 0 | 2026-08-17 23:50 | OK (14 trouvés) |
82 +| `motosillimitees` | Motos Illimitées | Terrebonne | Lanaudière | 276 | 0 | 2026-08-18 01:42 | OK (276 trouvés) |
83 +| `motosthibaulttr` | Motos Thibault Trois-Rivières | Trois-Rivières | Mauricie | 11 | 0 | 2026-08-17 23:50 | OK (11 trouvés) |
84 +| `rmmotosport` | RM Motosport | Victoriaville | Centre-du-Québec | 9 | 0 | 2026-08-17 23:50 | OK (9 trouvés) |
85 +| `smsport` | SM Sport | Québec | Capitale-Nationale | 48 | 0 | 2026-08-17 23:50 | OK (48 trouvés) |
86 +| `stjeromeharleydavidson` | St-Jérôme Harley-Davidson | Saint-Jérôme | Laurentides | 39 | 0 | 2026-08-17 23:50 | OK (39 trouvés) |
87 +
88 +## Erreurs de synchronisation récentes
89 +
90 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/occasionbeaucage.md +68 −0
@@ -0,0 +1,68 @@
1 +# Module `occasionbeaucage` — Next.js Autoroot / EvalAuto
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/occasionbeaucage.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 1226
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : flux RSC Next.js, endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, AUTOKA_MAX_PAGES, cache détail BD (detail_cache)
13 +- **Classes** : `OccasionBeaucage` → `occasionbeaucage`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/occasionbeaucage.py : connecteur Occasion Beaucage
18 +> (occasionbeaucage.com), groupe de mégacentres d'occasion de l'Estrie /
19 +> Centre-du-Québec / Montérégie (Sherbrooke, Magog, Granby, Drummondville,
20 +> Victoriaville, Saint-Hyacinthe, Cowansville) — ~1 200 véhicules.
21 +>
22 +> Plateforme : Next.js App Router (autoroot.io) sur Vercel, inventaire
23 +> EvalAuto. Chaque page liste /auto-usage/<n>/ (24 véhicules/page) embarque
24 +> dans son flux RSC (self.__next_f.push) un objet
25 +> {"vehicles":[...],"count":N,"page":n} où chaque véhicule est COMPLET :
26 +> prix, km, VIN, stock, transmission, carburant, carrosserie, couleurs,
27 +> moteur, portes, places, carfax, photos ET la concession du véhicule
28 +> (display_dealer_name / display_city). AUCUNE page détail nécessaire :
29 +> ~52 requêtes pour tout l'inventaire, ville exacte par véhicule.
30 +>
31 +> Les refs de flux («$313») pointant vers d'autres lignes RSC (les listes
32 +> de photos) sont résolues localement. AUTOKA_MAX_PAGES (env) limite la
33 +> pagination pour les tests.
34 +>
35 +> Enrichissement détail : la description complète et la liste d'équipements
36 +> ne vivent PAS dans le flux liste — seulement dans le flux RSC de la page
37 +> détail /auto-usage/<slug>/, sous forme de refs ($21…) vers des lignes
38 +> longues «T<hex>,» (longueur en OCTETS UTF-8) : description = HTML brut,
39 +> options = JSON {"fr": "équip1|équip2|…"}. Ces payloads sont mis en cache
40 +> BD à clé stable (les équipements ne changent pas ; le prix frais vient de
41 +> la liste) et plafonnés par AUTOKA_MAX_DETAILS / max_details par sync —
42 +> l'inventaire complet se couvre en quelques synchronisations.
43 +
44 +## Complétude des champs (annonces actives, N = 1 226)
45 +
46 +| Champ | % rempli |
47 +|---|---|
48 +| Marque | 100.0 % |
49 +| Modèle | 100.0 % |
50 +| Année | 100.0 % |
51 +| Kilométrage | 100.0 % |
52 +| Prix | 100.0 % |
53 +| Carburant | 98.5 % |
54 +| Boîte (transmission) | 100.0 % |
55 +| VIN | 100.0 % |
56 +| Photos | 100.0 % |
57 +| Carfax | 54.8 % |
58 +| GPS (lat/lng) | 100.0 % |
59 +
60 +## Sources membres (BD live)
61 +
62 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
63 +|---|---|---|---|---|---|---|---|
64 +| `occasionbeaucage` | Occasion Beaucage | Sherbrooke | Estrie | 1226 | 192 | 2026-08-17 23:50 | OK (1226 trouvés) |
65 +
66 +## Erreurs de synchronisation récentes
67 +
68 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/occasioncharlevoix.md +59 −0
@@ -0,0 +1,59 @@
1 +# Module `occasioncharlevoix` — OctoberCMS thème nerd2 / NerdAuto
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/occasioncharlevoix.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 30
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : parsing HTML
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS
13 +- **Classes** : `OccasionCharlevoix` → `occasioncharlevoix`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/occasioncharlevoix.py : connecteur Occasion Charlevoix
18 +> (occasioncharlevoix.com), regroupement de concessionnaires d'occasion de
19 +> Baie-Saint-Paul (Charlevoix, Capitale-Nationale) — ~30 véhicules.
20 +>
21 +> Plateforme : OctoberCMS, thème « nerd2 » + plugins nerd/inventory
22 +> (plateforme québécoise NerdAuto). La page liste /fr/inventaire/occasion
23 +> est ENTIÈREMENT rendue côté serveur : chaque carte (div.vrp4-card)
24 +> contient marque, modèle, version, année, no de stock, kilométrage, photos
25 +> (carrousel) et un bloc « Autoverify » (div.av-srp-ecomm) avec VIN et prix
26 +> réel (data-av-price — le prix affiché en gros est un paiement périodique).
27 +>
28 +> La page détail complète (cache BD, clé statique v1) : transmission,
29 +> cylindrée, motricité, couleurs, catégorie, lien Carfax.
30 +
31 +## Complétude des champs (annonces actives, N = 30)
32 +
33 +| Champ | % rempli |
34 +|---|---|
35 +| Marque | 100.0 % |
36 +| Modèle | 100.0 % |
37 +| Année | 100.0 % |
38 +| Kilométrage | 100.0 % |
39 +| Prix | 96.7 % |
40 +| Carburant | 0.0 % |
41 +| Boîte (transmission) | 100.0 % |
42 +| VIN | 100.0 % |
43 +| Photos | 100.0 % |
44 +| Carfax | 56.7 % |
45 +| GPS (lat/lng) | 100.0 % |
46 +
47 +## Sources membres (BD live)
48 +
49 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
50 +|---|---|---|---|---|---|---|---|
51 +| `occasioncharlevoix` | Occasion Charlevoix | Baie-Saint-Paul | Capitale-Nationale | 30 | 9 | 2026-08-18 01:44 | OK (30 trouvés) |
52 +
53 +## Erreurs de synchronisation récentes (sync_log, ok = 0)
54 +
55 +| Source | Quand | Message |
56 +|---|---|---|
57 +| `occasioncharlevoix` | 2026-08-16 00:03 | HTTPSConnectionPool(host='www.occasioncharlevoix.com', port=443): Read timed out. (read timeout=30) |
58 +| `occasioncharlevoix` | 2026-08-14 23:58 | HTTPSConnectionPool(host='www.occasioncharlevoix.com', port=443): Read timed out. (read timeout=30) |
59 +| `occasioncharlevoix` | 2026-08-13 00:24 | HTTPSConnectionPool(host='www.occasioncharlevoix.com', port=443): Read timed out. (read timeout=30) |
added docs/connecteurs/okaze.md +50 −0
@@ -0,0 +1,50 @@
1 +# Module `okaze` — Webflow CMS
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/okaze.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 50
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : —
12 +- **Plafonds / cache** : aucun
13 +- **Classes** : `Okaze` → `okaze`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/okaze.py : OKAZE (Saguenay) — site Webflow (CMS w-dyn-list).
18 +>
19 +> Stratégie : la page /inventaire est rendue côté serveur avec TOUTES les
20 +> annonces (pas de pagination). Chaque carte embarque un <script> inline qui
21 +> pose des attributs data-* dont `data-search` : une chaîne CSV complète —
22 +> nom, année, carrosserie, catégorie, couleur ext., couleur int., marque,
23 +> modèle, moteur, portes, km, prix, motricité, transmission, carburant.
24 +> On parse ces cartes en HTML brut (regex) : une seule requête par sync.
25 +
26 +## Complétude des champs (annonces actives, N = 50)
27 +
28 +| Champ | % rempli |
29 +|---|---|
30 +| Marque | 100.0 % |
31 +| Modèle | 100.0 % |
32 +| Année | 100.0 % |
33 +| Kilométrage | 100.0 % |
34 +| Prix | 100.0 % |
35 +| Carburant | 100.0 % |
36 +| Boîte (transmission) | 100.0 % |
37 +| VIN | 0.0 % |
38 +| Photos | 98.0 % |
39 +| Carfax | 0.0 % |
40 +| GPS (lat/lng) | 100.0 % |
41 +
42 +## Sources membres (BD live)
43 +
44 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
45 +|---|---|---|---|---|---|---|---|
46 +| `okaze` | OKAZE | Saguenay | Saguenay–Lac-Saint-Jean | 50 | 0 | 2026-08-17 23:50 | OK (50 trouvés) |
47 +
48 +## Erreurs de synchronisation récentes
49 +
50 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/ototr.md +51 −0
@@ -0,0 +1,51 @@
1 +# Module `ototr` — WordPress thème Motors/STM
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/ototr.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 4
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, JSON-LD schema.org, parsing HTML
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `OtoTroisRivieres` → `ototroisrivieres`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/ototr.py : OTO Trois-Rivières — WordPress, thème « Motors »
18 +> (stm_vehicles_listing). Pas d'API REST exposée ni de JSON-LD.
19 +>
20 +> Stratégie : le sitemap natif WP `/wp-sitemap-posts-listings-1.xml` recense
21 +> les annonces (/listings/<slug>/). Chaque page détail est parsée en HTML
22 +> (BeautifulSoup) : h1 = titre, .single-regular-price = prix, tableau
23 +> .single-car-data = fiche technique (Odomètre, Carburant, Transmission,
24 +> Propulsion, Carrosserie, Moteur, Couleurs…). Pages détail en cache BD
25 +> (clé hebdomadaire).
26 +
27 +## Complétude des champs (annonces actives, N = 4)
28 +
29 +| Champ | % rempli |
30 +|---|---|
31 +| Marque | 100.0 % |
32 +| Modèle | 100.0 % |
33 +| Année | 75.0 % |
34 +| Kilométrage | 100.0 % |
35 +| Prix | 100.0 % |
36 +| Carburant | 100.0 % |
37 +| Boîte (transmission) | 100.0 % |
38 +| VIN | 0.0 % |
39 +| Photos | 100.0 % |
40 +| Carfax | 0.0 % |
41 +| GPS (lat/lng) | 100.0 % |
42 +
43 +## Sources membres (BD live)
44 +
45 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
46 +|---|---|---|---|---|---|---|---|
47 +| `ototroisrivieres` | OTO Trois-Rivières | Trois-Rivières | Mauricie | 4 | 0 | 2026-08-17 23:50 | OK (4 trouvés) |
48 +
49 +## Erreurs de synchronisation récentes
50 +
51 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/sm360_dealers.md +84 −0
@@ -0,0 +1,84 @@
1 +# Module `sm360_dealers` — sm360
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/sm360_dealers.py`
8 +- **Sources membres** : 15
9 +- **Annonces actives (BD)** : 1434
10 +- **Backend de fetch** : requests direct — Firecrawl par source au besoin (`use_firecrawl`, sites derrière Cloudflare)
11 +- **Mécanique détectée** : sitemap, JSON-LD schema.org, GraphQL, flux RSS, API JSON interne, endpoint JSON
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `ToutesLesMarques` → `touteslesmarques` ; `StJeromeAutoDepot` → `stjeromeautodepot` ; `LamontagneAuto` → `lamontagneauto` ; `Spinelli` → `spinelli` ; `AutoDesjardins` → `autodesjardins` ; `LallierHondaHull` → `lallierhondahull` … (+9)
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/sm360_dealers.py : connecteurs des concessionnaires sur plateforme
18 +> SM360 / 360.agency (fournisseur de sites très répandu chez les
19 +> concessionnaires franchisés au Québec).
20 +>
21 +> Stratégie : le sitemap (/fr/sitemap-xml) recense chaque page véhicule
22 +> d'occasion (/fr/inventaire-occasion/<marque>/<modèle>/<slug>-id<digits>).
23 +> Chaque page détail est server-rendered et expose :
24 +> 1. un JSON-LD schema.org (@type Car) : prix, km, VIN, transmission,
25 +> carrosserie, couleurs, portes/places, moteur, succursale vendeuse ;
26 +> 2. un dataLayer JS : stockNo, isNew/isDemo, catégorie de véhicule,
27 +> carburant, succursale (utile pour les groupes multi-succursales) ;
28 +> 3. la galerie photo complète (img.sm360.ca/…/images/inventory/…) ;
29 +> 4. le lien Carfax le cas échéant.
30 +> Les pages détail sont mises en cache BD (clé hebdomadaire) : seuls les
31 +> nouveaux véhicules — et une revalidation par semaine pour les prix —
32 +> génèrent de vraies requêtes.
33 +>
34 +> En complément, l'API GraphQL publique que le site utilise lui-même
35 +> (webauto-supplier-api.sm360.ca — celle des widgets VDP) donne pour chaque
36 +> id : la liste d'équipements (options.labels), la galerie complète
37 +> (multimedia.pictures — indispensable pour les gabarits dont la galerie
38 +> n'est PAS server-rendered : touteslesmarques, spinelli, rivesudchrysler,
39 +> toyotagatineau) et une description/tagline de repli. Un POST par véhicule,
40 +> mis en cache avec le même payload hebdomadaire.
41 +>
42 +> Le listing lui-même est un widget JS (GraphQL webauto-supplier-api) —
43 +> inutile ici, le sitemap suffit. robots.txt : Allow /*?page=* et /*/api/*,
44 +> Crawl-delay 10 → délai généreux + cache détail.
45 +
46 +## Complétude des champs (annonces actives, N = 1 434)
47 +
48 +| Champ | % rempli |
49 +|---|---|
50 +| Marque | 99.3 % |
51 +| Modèle | 100.0 % |
52 +| Année | 100.0 % |
53 +| Kilométrage | 99.5 % |
54 +| Prix | 99.2 % |
55 +| Carburant | 95.2 % |
56 +| Boîte (transmission) | 91.2 % |
57 +| VIN | 99.4 % |
58 +| Photos | 93.5 % |
59 +| Carfax | 6.6 % |
60 +| GPS (lat/lng) | 100.0 % |
61 +
62 +## Sources membres (BD live)
63 +
64 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
65 +|---|---|---|---|---|---|---|---|
66 +| `autodesjardins` | Automobiles Desjardins | Québec | Capitale-Nationale | 101 | 0 | 2026-08-17 23:51 | OK (100 trouvés) |
67 +| `baiecomeaugm` | Baie-Comeau Chevrolet Buick GMC | Baie-Comeau | Côte-Nord | 107 | 37 | 2026-08-17 23:51 | OK (100 trouvés) |
68 +| `kiamatane` | Kia Matane | Matane | Bas-Saint-Laurent | 40 | 1 | 2026-08-17 23:52 | OK (40 trouvés) |
69 +| `lallierhondahull` | Lallier Honda Hull | Gatineau | Outaouais | 62 | 0 | 2026-08-17 23:51 | OK (61 trouvés) |
70 +| `lamontagneauto` | Lamontagne Auto | Rimouski | Bas-Saint-Laurent | 13 | 0 | 2026-08-17 23:51 | OK (13 trouvés) |
71 +| `marquisautomobiles` | Marquis Automobiles | Matane | Bas-Saint-Laurent | 35 | 0 | 2026-08-17 23:52 | OK (35 trouvés) |
72 +| `rivesudchrysler` | Rive-Sud Chrysler | Brossard | Montérégie | 19 | 0 | 2026-08-17 23:51 | OK (19 trouvés) |
73 +| `septilesgm` | Sept-Îles Chevrolet Buick GMC | Sept-Îles | Côte-Nord | 102 | 13 | 2026-08-17 23:51 | OK (100 trouvés) |
74 +| `septileshonda` | Sept-Îles Honda | Sept-Îles | Côte-Nord | 12 | 0 | 2026-08-17 23:51 | OK (12 trouvés) |
75 +| `spinelli` | Groupe Spinelli | Montréal | Montréal | 100 | 0 | 2026-08-17 23:51 | OK (100 trouvés) |
76 +| `stjeromeautodepot` | St-Jérôme Auto Dépôt | Saint-Jérôme | Laurentides | 312 | 0 | 2026-08-18 01:41 | OK (10 trouvés) |
77 +| `touteslesmarques` | Toutes les marques | Chicoutimi | Saguenay–Lac-Saint-Jean | 243 | 169 | 2026-08-17 23:51 | OK (240 trouvés) |
78 +| `toyotagatineau` | Toyota Gatineau | Gatineau | Outaouais | 101 | 0 | 2026-08-17 23:51 | OK (100 trouvés) |
79 +| `villeneuveford` | Villeneuve Ford | Matane | Bas-Saint-Laurent | 72 | 0 | 2026-08-17 23:52 | OK (72 trouvés) |
80 +| `volvosaintleonard` | Volvo Cars Saint-Léonard | Montréal | Montréal | 115 | 0 | 2026-08-17 23:52 | OK (115 trouvés) |
81 +
82 +## Erreurs de synchronisation récentes
83 +
84 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/stefoychrysler.md +53 −0
@@ -0,0 +1,53 @@
1 +# Module `stefoychrysler` — Next.js RSC autoroot.io / EvalAuto
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/stefoychrysler.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 414
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : flux RSC Next.js
12 +- **Plafonds / cache** : aucun
13 +- **Classes** : `SteFoyChrysler` → `stefoychrysler`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/stefoychrysler.py : connecteur Ste-Foy Chrysler
18 +> (ste-foychrysler.com), gros concessionnaire Chrysler/Dodge/Jeep/RAM de
19 +> Québec (arrondissement Sainte-Foy) — ~400+ véhicules d'occasion.
20 +>
21 +> Plateforme : Next.js App Router (autoroot.io), inventaire EvalAuto —
22 +> exactement la même que Occasion Beaucage : chaque page liste
23 +> /auto-usage/<n>/ embarque dans son flux RSC (self.__next_f.push) l'objet
24 +> {"vehicles":[...],"count":N} avec tous les champs par véhicule (prix, km,
25 +> VIN, stock, transmission, carburant, carrosserie, couleurs, photos,
26 +> display_dealer_name / display_city). On réutilise donc OccasionBeaucage
27 +> telle quelle, seuls l'URL et les libellés changent.
28 +
29 +## Complétude des champs (annonces actives, N = 414)
30 +
31 +| Champ | % rempli |
32 +|---|---|
33 +| Marque | 100.0 % |
34 +| Modèle | 100.0 % |
35 +| Année | 100.0 % |
36 +| Kilométrage | 100.0 % |
37 +| Prix | 100.0 % |
38 +| Carburant | 99.8 % |
39 +| Boîte (transmission) | 99.8 % |
40 +| VIN | 100.0 % |
41 +| Photos | 100.0 % |
42 +| Carfax | 75.1 % |
43 +| GPS (lat/lng) | 100.0 % |
44 +
45 +## Sources membres (BD live)
46 +
47 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
48 +|---|---|---|---|---|---|---|---|
49 +| `stefoychrysler` | Ste-Foy Chrysler | Québec | Capitale-Nationale | 414 | 35 | 2026-08-17 23:52 | OK (414 trouvés) |
50 +
51 +## Erreurs de synchronisation récentes
52 +
53 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/transverse-dealers.md +29 −0
@@ -0,0 +1,29 @@
1 +# Transverse — Coordonnées des concessionnaires
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py`._
4 +
5 +## Mécanique (`autoka/dealers.py`)
6 +
7 +> dealers.py : coordonnées des concessionnaires (adresse, téléphone, GPS)
8 +>
9 +> 1 source = 1 site de concessionnaire (sauf portails/marketplaces) : on
10 +> visite UNE page par site (l'accueil suffit — l'adresse et le téléphone
11 +> sont dans l'en-tête/le pied de page, et la plupart des plateformes (D2C,
12 +> SM360, Convertus…) émettent un JSON-LD AutoDealer/LocalBusiness complet).
13 +> Extraction : JSON-LD d'abord (address/telephone/geo), replis regex
14 +> (lien tel:, adresse avec code postal canadien). GPS par défaut : centre
15 +> de la ville de la source (data/villes_gps.json).
16 +>
17 +> Budget : ~138 requêtes UNE fois (cache en base — on ne re-visite que les
18 +> sources absentes de la table), throttle 1 s.
19 +>
20 +> One-shot : python3 -m autoka.dealers [--refresh]
21 +
22 +## État live (table `dealers`)
23 +
24 +- **Concessionnaires en base** : 138
25 +- **Avec téléphone** : 135 (98 %)
26 +- **Avec adresse** : 115 (83 %)
27 +- **Avec GPS (lat/lng)** : 138 (100 %)
28 +
29 +Crawl « une page par site » (accueil : JSON-LD AutoDealer/LocalBusiness, replis regex `tel:` + code postal canadien) ; GPS de repli = centre-ville de la source (`data/villes_gps.json`). One-shot : `python3 -m autoka.dealers [--refresh]`.
added docs/connecteurs/transverse-dedup-vin.md +53 −0
@@ -0,0 +1,53 @@
1 +# Transverse — Dédoublonnage VIN inter-sources
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py`._
4 +
5 +## Mécanique (`autoka/dedup.py`)
6 +
7 +> dedup.py : dédoublonnage inter-sources par VIN
8 +>
9 +> Le même véhicule apparaît souvent chez plusieurs sources : le site du
10 +> concessionnaire ET le portail de son groupe (Le Prix du Gros ↔ HGrégoire,
11 +> Méga Centre ↔ concessions Laplante, Toutes les marques ↔ GM Côte-Nord…),
12 +> voire une petite annonce Kijiji. Le VIN (17 caractères, unique au monde)
13 +> est la clé de blocage parfaite : on ne regroupe QUE sur VIN identique et
14 +> valide — dédoublonnage volontairement conservateur, zéro faux positif.
15 +>
16 +> Pour chaque groupe de doublons on élit une annonce CANONIQUE :
17 +> autorité (concessionnaire direct > portail/regroupeur > petites
18 +> annonces) puis complétude de la fiche, puis ancienneté (first_seen).
19 +> La canonique garde la liste des autres offres dans `dup_sources` (JSON) ;
20 +> les doublons pointent vers elle via `dup_of` (uid canonique). Les
21 +> endpoints de liste filtrent `dup_of IS NULL` — les fiches détail restent
22 +> toutes accessibles par uid.
23 +>
24 +> `recompute()` repart de zéro à chaque appel (idempotent) : appelé à la fin
25 +> de chaque cycle d'ingestion (ingest.run) et disponible en one-shot :
26 +> python3 -m autoka.dedup
27 +
28 +## État live
29 +
30 +- **Annonces en base** : 23110
31 +- **Annonces masquées (`dup_of` non nul)** : 2315
32 +- **Annonces canoniques avec doublons** : 1729
33 +- **Autorité** : concessionnaire direct > portail/regroupeur > petites annonces ; puis complétude de la fiche, puis ancienneté (`first_seen`).
34 +- Les listes filtrent `dup_of IS NULL` ; les fiches détail restent accessibles par uid.
35 +
36 +## Sources les plus masquées
37 +
38 +| Source | Annonces masquées |
39 +|---|---|
40 +| `leprixdugros` | 653 |
41 +| `megacentredeliquidation` | 451 |
42 +| `montjolichrysler` | 382 |
43 +| `occasionbeaucage` | 192 |
44 +| `touteslesmarques` | 169 |
45 +| `jeandumas` | 105 |
46 +| `jeandumashondabc` | 105 |
47 +| `abitibiautocredit` | 85 |
48 +| `baiecomeaugm` | 37 |
49 +| `stefoychrysler` | 35 |
50 +| `dynastiehyundai` | 33 |
51 +| `gaspesiehyundai` | 30 |
52 +
53 +Recalcul one-shot : `python3 -m autoka.dedup` (idempotent, relancé à la fin de chaque cycle d'ingestion).
added docs/connecteurs/transverse-rappels-tc.md +44 −0
@@ -0,0 +1,44 @@
1 +# Transverse — Rappels de sécurité Transports Canada
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py`._
4 +
5 +## Mécanique (`autoka/recalls.py`)
6 +
7 +> recalls.py : rappels de sécurité — Base de données des rappels de véhicules
8 +> de Transports Canada (données ouvertes, gratuit)
9 +>
10 +> Source : dump mensuel complet CSV du jeu de données « Vehicle Recalls
11 +> Database » (ouvert.canada.ca, jeu 1ec92326-47ef-4110-b7ca-959fab03f96d) :
12 +> https://opendatatc.tc.canada.ca/vrdb_full_monthly.csv (~200 Mo)
13 +> 1 ligne = 1 rappel × marque × modèle × année-modèle. L'API REST officielle
14 +> (tc.api.canada.ca) exige une clé délivrée manuellement — le CSV ouvert est
15 +> la voie sans clé, rafraîchi mensuellement par TC.
16 +>
17 +> Table `recalls` (make/model/year normalisés en MAJUSCULES sans accents) +
18 +> croisement par (make, model, year) avec les annonces : le modèle TC est
19 +> souvent plus court que le nôtre (« CIVIC » vs « Civic Sport Touring ») —
20 +> on matche si l'un préfixe l'autre au premier mot près, année exacte.
21 +>
22 +> Peuplement one-shot / mensuel : python3 -m autoka.recalls [--limit-years N]
23 +
24 +## État live
25 +
26 +- **Rappels distincts (`recall_number`)** : 16969
27 +- **Lignes en base (rappel × marque × modèle × année)** : 109186
28 +- **Années-modèles couvertes** : 1980–2028
29 +- **Source** : CSV mensuel complet des données ouvertes TC (`opendatatc.tc.canada.ca/vrdb_full_monthly.csv`, sans clé API).
30 +
31 +## Répartition par catégorie TC
32 +
33 +| Catégorie | Rappels distincts |
34 +|---|---|
35 +| Car | 4204 |
36 +| SUV | 2507 |
37 +| Truck - Med. & H.D. | 2324 |
38 +| Light Truck & Van | 1651 |
39 +| Motorhome | 1411 |
40 +| RV Trailer | 1176 |
41 +| Motorcycle | 1008 |
42 +| Bus | 964 |
43 +
44 +Peuplement one-shot / mensuel : `python3 -m autoka.recalls [--limit-years N]`.
added docs/connecteurs/transverse-villes-gps.md +9 −0
@@ -0,0 +1,9 @@
1 +# Transverse — Référentiel GPS des villes (`data/villes_gps.json`)
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py`._
4 +
5 +- **Villes référencées** : 216
6 +- **Format** : `"ville en minuscules sans accents" → [lat, lng]` (centres-villes du Québec).
7 +- **Usages** : GPS de repli des concessionnaires (`autoka/dealers.py`) et géolocalisation des annonces par la ville de leur source (les annonces Kijiji portent leur propre lat/lng exact).
8 +
9 +Extrait : acton vale, ahuntsic, alma, amos, amqui, anjou, asbestos, aylmer, baie-comeau, baie-d'urfe, baie-saint-paul, beaconsfield…
added docs/connecteurs/vvu_dealers.md +57 −0
@@ -0,0 +1,57 @@
1 +# Module `vvu_dealers` — ADWS
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/vvu_dealers.py`
8 +- **Sources membres** : 4
9 +- **Annonces actives (BD)** : 183
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : API JSON interne, endpoint JSON
12 +- **Plafonds / cache** : aucun
13 +- **Classes** : `AutoGlobalMTL` → `autoglobalmtl` ; `GroupeAutomobile` → `groupeautomobile` ; `SummumAuto` → `summumauto` ; `Comme1Neuf` → `occasionvilledequebec`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/vvu_dealers.py : connecteurs des concessionnaires indépendants sur
18 +> la plateforme ADWS (adws.ca) — sites Next.js au titre commun « Vente de
19 +> Véhicules Usagés - Voitures d'Occasion de Qualité » (d'où « VVU »).
20 +>
21 +> Stratégie : chaque site expose une API JSON interne `/api/inventory`
22 +> (paginée : ?page=N&limit=M) qui retourne TOUTES les données véhicule
23 +> (prix, km, VIN, moteur, couleurs, équipements FR, photos…). Une ou deux
24 +> requêtes suffisent par sync — aucune page détail à visiter.
25 +>
26 +> L'URL de la page détail se reconstruit depuis le slug
27 +> `<make>-<model>-<year>-<_id>` ; le préfixe varie selon la version du
28 +> gabarit ADWS déployée (`/fr/vehicle/…` ou `/fr/occasion/…`).
29 +
30 +## Complétude des champs (annonces actives, N = 183)
31 +
32 +| Champ | % rempli |
33 +|---|---|
34 +| Marque | 100.0 % |
35 +| Modèle | 100.0 % |
36 +| Année | 99.5 % |
37 +| Kilométrage | 100.0 % |
38 +| Prix | 100.0 % |
39 +| Carburant | 99.5 % |
40 +| Boîte (transmission) | 100.0 % |
41 +| VIN | 96.7 % |
42 +| Photos | 97.8 % |
43 +| Carfax | 0.0 % |
44 +| GPS (lat/lng) | 100.0 % |
45 +
46 +## Sources membres (BD live)
47 +
48 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
49 +|---|---|---|---|---|---|---|---|
50 +| `autoglobalmtl` | Auto Global MTL | Montréal | Montréal | 30 | 0 | 2026-08-17 23:52 | OK (30 trouvés) |
51 +| `groupeautomobile` | Le Groupe Automobile Laval | Laval | Laval | 24 | 0 | 2026-08-17 23:52 | OK (24 trouvés) |
52 +| `occasionvilledequebec` | Comme1Neuf | Château-Richer | Capitale-Nationale | 77 | 0 | 2026-08-17 23:52 | OK (77 trouvés) |
53 +| `summumauto` | Summum Auto | Laval | Laval | 52 | 0 | 2026-08-17 23:52 | OK (52 trouvés) |
54 +
55 +## Erreurs de synchronisation récentes
56 +
57 +Aucune erreur dans le sync_log pour les sources de ce module.
added docs/connecteurs/yannicklaberge.md +51 −0
@@ -0,0 +1,51 @@
1 +# Module `yannicklaberge` — WordPress AMVOQ theme_central
2 +
3 +_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._
4 +
5 +## Vue d'ensemble
6 +
7 +- **Fichier** : `autoka/connectors/yannicklaberge.py`
8 +- **Sources membres** : 1
9 +- **Annonces actives (BD)** : 17
10 +- **Backend de fetch** : requests direct (aucun anti-bot)
11 +- **Mécanique détectée** : sitemap, JSON-LD schema.org
12 +- **Plafonds / cache** : AUTOKA_MAX_DETAILS, cache détail BD (detail_cache)
13 +- **Classes** : `YannickLaberge` → `automobilesyannicklaberge`
14 +
15 +## Mécanique (en-tête du module)
16 +
17 +> connectors/yannicklaberge.py : Automobiles Yannick Laberge (Beauport) —
18 +> WordPress sur la plateforme AMVOQ (thème « theme_central », inventaire
19 +> autousagee.ca, images image.autousagee.ca). API REST verrouillée (401).
20 +>
21 +> Stratégie : le sitemap Yoast `/vehicules-sitemap.xml` recense les annonces
22 +> (/vehicule-usage/<slug>/<id>/). Chaque page détail expose un JSON-LD
23 +> schema.org @type Vehicle : prix, VIN, km, transmission, carburant,
24 +> couleur intérieure, description. Galerie complétée par les URLs
25 +> image.autousagee.ca de la page. Pages détail en cache BD (clé hebdo).
26 +
27 +## Complétude des champs (annonces actives, N = 17)
28 +
29 +| Champ | % rempli |
30 +|---|---|
31 +| Marque | 100.0 % |
32 +| Modèle | 100.0 % |
33 +| Année | 100.0 % |
34 +| Kilométrage | 100.0 % |
35 +| Prix | 100.0 % |
36 +| Carburant | 100.0 % |
37 +| Boîte (transmission) | 100.0 % |
38 +| VIN | 100.0 % |
39 +| Photos | 100.0 % |
40 +| Carfax | 0.0 % |
41 +| GPS (lat/lng) | 100.0 % |
42 +
43 +## Sources membres (BD live)
44 +
45 +| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |
46 +|---|---|---|---|---|---|---|---|
47 +| `automobilesyannicklaberge` | Automobiles Yannick Laberge | Beauport | Capitale-Nationale | 17 | 0 | 2026-08-17 23:52 | OK (17 trouvés) |
48 +
49 +## Erreurs de synchronisation récentes
50 +
51 +Aucune erreur dans le sync_log pour les sources de ce module.
added scripts/gen_connector_docs.py +439 −0
@@ -0,0 +1,439 @@
1 +#!/usr/bin/env python3
2 +# -----------------------------------------------------------------------------
3 +# Auto-Ka — Agrégateur de voitures usagées à vendre (province de Québec)
4 +# Auteur : Simon-Pierre Boucher — contact@spboucher.ai
5 +# scripts/gen_connector_docs.py : documentation standardisée des connecteurs
6 +#
7 +# Génère docs/connecteurs/ (INDEX.md + une fiche par MODULE connecteur +
8 +# fiches transverses) en croisant :
9 +# 1. data/sources.json — registre des sources (139 sources) ;
10 +# 2. le code des connecteurs — en-tête « mécanique » de chaque module,
11 +# backend de fetch, plafonds env (AUTOKA_*), classes exposées ;
12 +# 3. la BD live data/autoka.db — volumétrie, complétude par champ,
13 +# dernier sync et erreurs récentes (sync_log), doublons VIN, rappels
14 +# Transports Canada, coordonnées concessionnaires.
15 +#
16 +# Rejouable à volonté (BD ouverte en lecture seule, docs régénérés) :
17 +# .venv/bin/python3 scripts/gen_connector_docs.py
18 +# -----------------------------------------------------------------------------
19 +from __future__ import annotations
20 +
21 +import datetime
22 +import json
23 +import re
24 +import sqlite3
25 +import sys
26 +from collections import OrderedDict
27 +from pathlib import Path
28 +
29 +ROOT = Path(__file__).resolve().parent.parent
30 +sys.path.insert(0, str(ROOT))
31 +
32 +DB_PATH = ROOT / "data" / "autoka.db"
33 +SOURCES_PATH = ROOT / "data" / "sources.json"
34 +VILLES_PATH = ROOT / "data" / "villes_gps.json"
35 +CONNECTORS_DIR = ROOT / "autoka" / "connectors"
36 +OUT_DIR = ROOT / "docs" / "connecteurs"
37 +
38 +# Champs de complétude (annonces actives) : libellé -> expression SQL "rempli"
39 +FIELDS = OrderedDict([
40 + ("Marque", "make IS NOT NULL AND make != ''"),
41 + ("Modèle", "model IS NOT NULL AND model != ''"),
42 + ("Année", "year IS NOT NULL"),
43 + ("Kilométrage", "mileage_km IS NOT NULL"),
44 + ("Prix", "price IS NOT NULL"),
45 + ("Carburant", "fuel IS NOT NULL AND fuel != ''"),
46 + ("Boîte (transmission)", "transmission IS NOT NULL AND transmission != ''"),
47 + ("VIN", "vin IS NOT NULL AND vin != ''"),
48 + ("Photos", "images IS NOT NULL AND images NOT IN ('', '[]')"),
49 + ("Carfax", "carfax_url IS NOT NULL AND carfax_url != ''"),
50 + ("GPS (lat/lng)", "lat IS NOT NULL AND lng IS NOT NULL"),
51 +])
52 +
53 +# Historique des vagues d'enrichissement (source de vérité : git log)
54 +HISTORIQUE = """\
55 +## Historique des vagues (2026-08-18)
56 +
57 +| Commit | Contenu |
58 +|---|---|
59 +| `2a35ac2` | Enrichissement connecteurs : Carfax, détails AED/LPDG, verticale moto, photos Magnetis, GPS concessionnaires |
60 +| `bbc070b` | Vague 2 : dédup VIN inter-sources, Kijiji particuliers, rappels Transports Canada, coordonnées concessionnaires |
61 +"""
62 +
63 +
64 +# --------------------------------------------------------------------------- #
65 +# Introspection du code
66 +# --------------------------------------------------------------------------- #
67 +
68 +def module_header(path: Path, marker: str) -> str:
69 + """En-tête « mécanique » d'un module : bloc de commentaires du haut du
70 + fichier, à partir de la ligne `# <marker>` (ex. connectors/x.py :) jusqu'à
71 + la ligne de tirets fermante. Rendu en bloc de citation Markdown."""
72 + lines = []
73 + started = False
74 + for raw in path.read_text(encoding="utf-8").splitlines():
75 + if not raw.startswith("#"):
76 + break
77 + body = raw.lstrip("#").strip()
78 + if not started:
79 + if body.startswith(marker):
80 + started = True
81 + lines.append(body)
82 + continue
83 + if set(body) <= {"-"} and len(body) > 10: # ligne de tirets finale
84 + break
85 + lines.append(body)
86 + if not lines:
87 + return "_(pas d'en-tête trouvé)_"
88 + return "\n".join("> " + (l if l else "") for l in lines)
89 +
90 +
91 +def detect_backend(src: str) -> str:
92 + low = src.lower()
93 + if "use_firecrawl" in low:
94 + return ("requests direct — Firecrawl par source au besoin "
95 + "(`use_firecrawl`, sites derrière Cloudflare)")
96 + if "firecrawl" in low:
97 + return "Firecrawl (contournement Cloudflare / rendu JS)"
98 + if "scrapfly" in low:
99 + return "Scrapfly"
100 + return "requests direct (aucun anti-bot)"
101 +
102 +
103 +def detect_mechanics(src: str) -> str:
104 + low = src.lower()
105 + found = []
106 + for needle, label in [
107 + ("sitemap", "sitemap"),
108 + ("json-ld", "JSON-LD schema.org"),
109 + ("__next_f", "flux RSC Next.js"),
110 + ("__next_data__", "__NEXT_DATA__"),
111 + ("graphql", "GraphQL"),
112 + ("appsync", "AWS AppSync"),
113 + ("page-data.json", "page-data Gatsby"),
114 + ("rss", "flux RSS"),
115 + ("microdata", "microdata schema.org"),
116 + ("itemprop", "microdata schema.org"),
117 + ("beautifulsoup", "parsing HTML"),
118 + ("data-class=", "blob JSON data-class"),
119 + ("/api/", "API JSON interne"),
120 + (".json", "endpoint JSON"),
121 + ]:
122 + if needle in low and label not in found:
123 + found.append(label)
124 + return ", ".join(found) if found else "—"
125 +
126 +
127 +def detect_caps(src: str) -> str:
128 + caps = sorted(set(re.findall(r"AUTOKA_[A-Z_]+", src)))
129 + caps = [c for c in caps if c not in ("AUTOKA_",)]
130 + if "detail_cache" in src or "cache_get" in src or "cached" in src.lower():
131 + caps.append("cache détail BD (detail_cache)")
132 + return ", ".join(caps) if caps else "aucun"
133 +
134 +
135 +def module_classes(mod_name: str) -> list[str]:
136 + """Classes concrètes (source_id non vide) déclarées par le module."""
137 + import autoka.connectors as reg
138 + out = []
139 + for sid, cls in reg.CONNECTORS.items():
140 + if cls.__module__.rsplit(".", 1)[-1] == mod_name:
141 + out.append(f"`{cls.__name__}` → `{sid}`")
142 + return out
143 +
144 +
145 +# --------------------------------------------------------------------------- #
146 +# BD live
147 +# --------------------------------------------------------------------------- #
148 +
149 +def q1(db, sql, args=()):
150 + return db.execute(sql, args).fetchone()
151 +
152 +
153 +def completeness(db, source_ids: list[str]) -> tuple[int, OrderedDict]:
154 + ph = ",".join("?" * len(source_ids))
155 + parts = ", ".join(f"SUM(CASE WHEN {expr} THEN 1 ELSE 0 END)"
156 + for expr in FIELDS.values())
157 + row = q1(db, f"SELECT COUNT(*), {parts} FROM vehicles "
158 + f"WHERE active = 1 AND source IN ({ph})", source_ids)
159 + n = row[0] or 0
160 + out = OrderedDict()
161 + for (label, _), filled in zip(FIELDS.items(), row[1:]):
162 + out[label] = (100.0 * (filled or 0) / n) if n else 0.0
163 + return n, out
164 +
165 +
166 +def source_stats(db, sid: str) -> dict:
167 + tot, act, dups = q1(db, "SELECT COUNT(*), SUM(active), "
168 + "SUM(dup_of IS NOT NULL) FROM vehicles "
169 + "WHERE source = ?", (sid,))
170 + last = q1(db, "SELECT ts, ok, found, added, updated, removed, message "
171 + "FROM sync_log WHERE source = ? ORDER BY ts DESC LIMIT 1",
172 + (sid,))
173 + errs = q1(db, "SELECT COUNT(*) FROM (SELECT ok FROM sync_log "
174 + "WHERE source = ? ORDER BY ts DESC LIMIT 10) WHERE ok = 0",
175 + (sid,))[0]
176 + return {"total": tot or 0, "active": act or 0, "dups": dups or 0,
177 + "last": last, "errs10": errs}
178 +
179 +
180 +def fmt_ts(ts) -> str:
181 + if not ts:
182 + return "—"
183 + return datetime.datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M")
184 +
185 +
186 +def sync_cell(st: dict) -> tuple[str, str]:
187 + last = st["last"]
188 + if not last:
189 + return "jamais", "—"
190 + ts, ok, found, *_ = last
191 + flag = "OK" if ok else "ERREUR"
192 + return fmt_ts(ts), f"{flag} ({found or 0} trouvés)"
193 +
194 +
195 +def recent_errors(db, source_ids: list[str], limit=8) -> list[tuple]:
196 + ph = ",".join("?" * len(source_ids))
197 + return db.execute(
198 + f"SELECT source, ts, message FROM sync_log "
199 + f"WHERE ok = 0 AND source IN ({ph}) ORDER BY ts DESC LIMIT ?",
200 + (*source_ids, limit)).fetchall()
201 +
202 +
203 +# --------------------------------------------------------------------------- #
204 +# Rendu des fiches
205 +# --------------------------------------------------------------------------- #
206 +
207 +def render_completeness(n: int, comp: OrderedDict) -> list[str]:
208 + n_fmt = f"{n:,}".replace(",", " ")
209 + out = [f"## Complétude des champs (annonces actives, N = {n_fmt})",
210 + "", "| Champ | % rempli |", "|---|---|"]
211 + for label, pct in comp.items():
212 + out.append(f"| {label} | {pct:.1f} % |")
213 + out.append("")
214 + return out
215 +
216 +
217 +def render_module_fiche(db, mod: str, members: list[dict]) -> str:
218 + path = CONNECTORS_DIR / f"{mod}.py"
219 + src = path.read_text(encoding="utf-8")
220 + sids = [s["id"] for s in members]
221 + n, comp = completeness(db, sids)
222 + active_total = 0
223 +
224 + rows = []
225 + for s in sorted(members, key=lambda x: x["id"]):
226 + st = source_stats(db, s["id"])
227 + active_total += st["active"]
228 + when, status = sync_cell(st)
229 + rows.append(f"| `{s['id']}` | {s.get('name', '')} | "
230 + f"{s.get('city', '') or '—'} | {s.get('region', '') or '—'} | "
231 + f"{st['active']} | {st['dups']} | {when} | {status} |")
232 +
233 + from collections import Counter
234 + plat_counts = Counter(s.get("platform", "").split(" (")[0].strip()
235 + for s in members if s.get("platform"))
236 + plat = plat_counts.most_common(1)[0][0] if plat_counts else mod
237 + lines = [
238 + f"# Module `{mod}` — {plat}",
239 + "",
240 + f"_Généré automatiquement par `scripts/gen_connector_docs.py` — ne pas éditer à la main._",
241 + "",
242 + "## Vue d'ensemble",
243 + "",
244 + f"- **Fichier** : `autoka/connectors/{mod}.py`",
245 + f"- **Sources membres** : {len(members)}",
246 + f"- **Annonces actives (BD)** : {active_total}",
247 + f"- **Backend de fetch** : {detect_backend(src)}",
248 + f"- **Mécanique détectée** : {detect_mechanics(src)}",
249 + f"- **Plafonds / cache** : {detect_caps(src)}",
250 + ]
251 + classes = module_classes(mod)
252 + if classes:
253 + lines.append(f"- **Classes** : {' ; '.join(classes[:6])}"
254 + + (f" … (+{len(classes) - 6})" if len(classes) > 6 else ""))
255 + lines += ["", "## Mécanique (en-tête du module)", "",
256 + module_header(path, f"connectors/{mod}.py"), ""]
257 + lines += render_completeness(n, comp)
258 + lines += ["## Sources membres (BD live)", "",
259 + "| Source | Nom | Ville | Région | Actives | Masquées (dup VIN) | Dernier sync | Statut |",
260 + "|---|---|---|---|---|---|---|---|"] + rows + [""]
261 +
262 + errs = recent_errors(db, sids)
263 + if errs:
264 + lines += ["## Erreurs de synchronisation récentes (sync_log, ok = 0)", "",
265 + "| Source | Quand | Message |", "|---|---|---|"]
266 + for sid, ts, msg in errs:
267 + msg = (msg or "").replace("|", "\\|")[:160]
268 + lines.append(f"| `{sid}` | {fmt_ts(ts)} | {msg} |")
269 + lines.append("")
270 + else:
271 + lines += ["## Erreurs de synchronisation récentes", "",
272 + "Aucune erreur dans le sync_log pour les sources de ce module.", ""]
273 + return "\n".join(lines)
274 +
275 +
276 +def render_transverse_dedup(db) -> str:
277 + total, masked = q1(db, "SELECT COUNT(*), SUM(dup_of IS NOT NULL) FROM vehicles")
278 + groups = q1(db, "SELECT COUNT(DISTINCT dup_of) FROM vehicles "
279 + "WHERE dup_of IS NOT NULL")[0]
280 + top = db.execute(
281 + "SELECT source, COUNT(*) c FROM vehicles WHERE dup_of IS NOT NULL "
282 + "GROUP BY source ORDER BY c DESC LIMIT 12").fetchall()
283 + lines = ["# Transverse — Dédoublonnage VIN inter-sources", "",
284 + "_Généré automatiquement par `scripts/gen_connector_docs.py`._", "",
285 + "## Mécanique (`autoka/dedup.py`)", "",
286 + module_header(ROOT / "autoka" / "dedup.py", "dedup.py"), "",
287 + "## État live", "",
288 + f"- **Annonces en base** : {total}",
289 + f"- **Annonces masquées (`dup_of` non nul)** : {masked}",
290 + f"- **Annonces canoniques avec doublons** : {groups}",
291 + "- **Autorité** : concessionnaire direct > portail/regroupeur > petites annonces ;"
292 + " puis complétude de la fiche, puis ancienneté (`first_seen`).",
293 + "- Les listes filtrent `dup_of IS NULL` ; les fiches détail restent accessibles par uid.",
294 + "", "## Sources les plus masquées", "",
295 + "| Source | Annonces masquées |", "|---|---|"]
296 + lines += [f"| `{s}` | {c} |" for s, c in top]
297 + lines += ["", "Recalcul one-shot : `python3 -m autoka.dedup` (idempotent,"
298 + " relancé à la fin de chaque cycle d'ingestion).", ""]
299 + return "\n".join(lines)
300 +
301 +
302 +def render_transverse_recalls(db) -> str:
303 + rows, nums = q1(db, "SELECT COUNT(*), COUNT(DISTINCT recall_number) FROM recalls")
304 + y0, y1 = q1(db, "SELECT MIN(year), MAX(year) FROM recalls WHERE year > 1900")
305 + cats = db.execute("SELECT category, COUNT(DISTINCT recall_number) c "
306 + "FROM recalls GROUP BY category ORDER BY c DESC LIMIT 8").fetchall()
307 + lines = ["# Transverse — Rappels de sécurité Transports Canada", "",
308 + "_Généré automatiquement par `scripts/gen_connector_docs.py`._", "",
309 + "## Mécanique (`autoka/recalls.py`)", "",
310 + module_header(ROOT / "autoka" / "recalls.py", "recalls.py"), "",
311 + "## État live", "",
312 + f"- **Rappels distincts (`recall_number`)** : {nums}",
313 + f"- **Lignes en base (rappel × marque × modèle × année)** : {rows}",
314 + f"- **Années-modèles couvertes** : {y0}–{y1}",
315 + "- **Source** : CSV mensuel complet des données ouvertes TC"
316 + " (`opendatatc.tc.canada.ca/vrdb_full_monthly.csv`, sans clé API).",
317 + "", "## Répartition par catégorie TC", "",
318 + "| Catégorie | Rappels distincts |", "|---|---|"]
319 + lines += [f"| {c or '—'} | {n} |" for c, n in cats]
320 + lines += ["", "Peuplement one-shot / mensuel : `python3 -m autoka.recalls"
321 + " [--limit-years N]`.", ""]
322 + return "\n".join(lines)
323 +
324 +
325 +def render_transverse_dealers(db) -> str:
326 + tot, ph, ad, gps = q1(db, "SELECT COUNT(*), "
327 + "SUM(phone IS NOT NULL AND phone != ''), "
328 + "SUM(address IS NOT NULL AND address != ''), "
329 + "SUM(lat IS NOT NULL AND lng IS NOT NULL) FROM dealers")
330 + lines = ["# Transverse — Coordonnées des concessionnaires", "",
331 + "_Généré automatiquement par `scripts/gen_connector_docs.py`._", "",
332 + "## Mécanique (`autoka/dealers.py`)", "",
333 + module_header(ROOT / "autoka" / "dealers.py", "dealers.py"), "",
334 + "## État live (table `dealers`)", "",
335 + f"- **Concessionnaires en base** : {tot}",
336 + f"- **Avec téléphone** : {ph} ({100.0 * ph / tot:.0f} %)",
337 + f"- **Avec adresse** : {ad} ({100.0 * ad / tot:.0f} %)",
338 + f"- **Avec GPS (lat/lng)** : {gps} ({100.0 * gps / tot:.0f} %)",
339 + "",
340 + "Crawl « une page par site » (accueil : JSON-LD AutoDealer/LocalBusiness,"
341 + " replis regex `tel:` + code postal canadien) ; GPS de repli = centre-ville"
342 + " de la source (`data/villes_gps.json`). One-shot :"
343 + " `python3 -m autoka.dealers [--refresh]`.", ""]
344 + return "\n".join(lines)
345 +
346 +
347 +def render_transverse_villes() -> str:
348 + villes = json.loads(VILLES_PATH.read_text(encoding="utf-8"))
349 + sample = ", ".join(sorted(villes)[:12])
350 + lines = ["# Transverse — Référentiel GPS des villes (`data/villes_gps.json`)", "",
351 + "_Généré automatiquement par `scripts/gen_connector_docs.py`._", "",
352 + f"- **Villes référencées** : {len(villes)}",
353 + "- **Format** : `\"ville en minuscules sans accents\" → [lat, lng]`"
354 + " (centres-villes du Québec).",
355 + "- **Usages** : GPS de repli des concessionnaires (`autoka/dealers.py`)"
356 + " et géolocalisation des annonces par la ville de leur source"
357 + " (les annonces Kijiji portent leur propre lat/lng exact).",
358 + "", f"Extrait : {sample}…", ""]
359 + return "\n".join(lines)
360 +
361 +
362 +# --------------------------------------------------------------------------- #
363 +# INDEX
364 +# --------------------------------------------------------------------------- #
365 +
366 +def render_index(db, groups: OrderedDict, sources: list[dict]) -> str:
367 + total, active, masked = q1(db, "SELECT COUNT(*), SUM(active), "
368 + "SUM(dup_of IS NOT NULL) FROM vehicles")
369 + kinds = dict(db.execute("SELECT kind, COUNT(*) FROM vehicles "
370 + "WHERE active = 1 GROUP BY kind").fetchall())
371 + recall_n = q1(db, "SELECT COUNT(DISTINCT recall_number) FROM recalls")[0]
372 + dealers_n = q1(db, "SELECT COUNT(*) FROM dealers")[0]
373 + now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
374 +
375 + lines = ["# Auto-Ka — Documentation des connecteurs", "",
376 + f"_Générée le {now} par `scripts/gen_connector_docs.py`"
377 + " (rejouable : `.venv/bin/python3 scripts/gen_connector_docs.py`)._", "",
378 + "## Vue d'ensemble", "",
379 + f"- **Sources** : {len(sources)} (registre `data/sources.json`)",
380 + f"- **Modules connecteurs** : {len(groups)} (`autoka/connectors/`)",
381 + f"- **Annonces en base** : {total} — dont {active} actives"
382 + f" ({kinds.get('auto', 0)} autos, {kinds.get('moto', 0)} motos,"
383 + f" {kinds.get('scooter', 0)} scooters)",
384 + f"- **Doublons VIN masqués** : {masked} (voir [dédup VIN](transverse-dedup-vin.md))",
385 + f"- **Rappels Transports Canada** : {recall_n} rappels distincts"
386 + " (voir [rappels TC](transverse-rappels-tc.md))",
387 + f"- **Concessionnaires géolocalisés** : {dealers_n}"
388 + " (voir [dealers](transverse-dealers.md))",
389 + "", "## Fiches par module connecteur", "",
390 + "| Module | Fiche | Sources | Annonces actives | Backend |",
391 + "|---|---|---|---|---|"]
392 + for mod, members in groups.items():
393 + sids = [s["id"] for s in members]
394 + ph_ = ",".join("?" * len(sids))
395 + act = q1(db, f"SELECT COALESCE(SUM(active), 0) FROM vehicles "
396 + f"WHERE source IN ({ph_})", sids)[0]
397 + src = (CONNECTORS_DIR / f"{mod}.py").read_text(encoding="utf-8")
398 + backend = detect_backend(src).split(" (")[0]
399 + lines.append(f"| `{mod}` | [{mod}.md]({mod}.md) | {len(members)} | {act} | {backend} |")
400 +
401 + lines += ["", "## Fiches transverses", "",
402 + "| Sujet | Fiche |", "|---|---|",
403 + "| Dédoublonnage VIN inter-sources | [transverse-dedup-vin.md](transverse-dedup-vin.md) |",
404 + "| Rappels Transports Canada | [transverse-rappels-tc.md](transverse-rappels-tc.md) |",
405 + "| Coordonnées des concessionnaires | [transverse-dealers.md](transverse-dealers.md) |",
406 + "| Référentiel GPS des villes | [transverse-villes-gps.md](transverse-villes-gps.md) |",
407 + "", HISTORIQUE]
408 + return "\n".join(lines)
409 +
410 +
411 +# --------------------------------------------------------------------------- #
412 +
413 +def main() -> None:
414 + sources = json.loads(SOURCES_PATH.read_text(encoding="utf-8"))["sources"]
415 + groups: OrderedDict[str, list] = OrderedDict()
416 + for s in sources:
417 + groups.setdefault(s["connector"], []).append(s)
418 + # modules multi-sources d'abord (par taille), uniques ensuite (alpha)
419 + groups = OrderedDict(sorted(groups.items(),
420 + key=lambda kv: (-len(kv[1]), kv[0])))
421 +
422 + db = sqlite3.connect(f"file:{DB_PATH}?mode=ro", uri=True)
423 + OUT_DIR.mkdir(parents=True, exist_ok=True)
424 +
425 + for mod, members in groups.items():
426 + (OUT_DIR / f"{mod}.md").write_text(
427 + render_module_fiche(db, mod, members), encoding="utf-8")
428 + print(f" fiche {mod}.md ({len(members)} source(s))")
429 +
430 + (OUT_DIR / "transverse-dedup-vin.md").write_text(render_transverse_dedup(db), encoding="utf-8")
431 + (OUT_DIR / "transverse-rappels-tc.md").write_text(render_transverse_recalls(db), encoding="utf-8")
432 + (OUT_DIR / "transverse-dealers.md").write_text(render_transverse_dealers(db), encoding="utf-8")
433 + (OUT_DIR / "transverse-villes-gps.md").write_text(render_transverse_villes(), encoding="utf-8")
434 + (OUT_DIR / "INDEX.md").write_text(render_index(db, groups, sources), encoding="utf-8")
435 + print(f"OK — {len(groups)} fiches module + 4 transverses + INDEX.md dans {OUT_DIR}")
436 +
437 +
438 +if __name__ == "__main__":
439 + main()
440