# Sorti·Ka ### Toutes les sorties et tous les événements du Québec. Un seul endroit. **[www.sorti-ka.com](https://www.sorti-ka.com)** ![Python](https://img.shields.io/badge/Python-3.14-141814?style=for-the-badge&logo=python&logoColor=d9f26b) ![FastAPI](https://img.shields.io/badge/FastAPI-API_+_SSR-141814?style=for-the-badge&logo=fastapi&logoColor=d9f26b) ![SQLite](https://img.shields.io/badge/SQLite-storage-141814?style=for-the-badge&logo=sqlite&logoColor=d9f26b) ![Frontend](https://img.shields.io/badge/Frontend-SPA_sans_build-141814?style=for-the-badge&logo=html5&logoColor=d9f26b) ![Événements](https://img.shields.io/badge/%C3%A9v%C3%A9nements_actifs-15_231-1c5c41?style=flat-square) ![À venir](https://img.shields.io/badge/%C3%A0_venir-11_559-1c5c41?style=flat-square) ![Gratuits](https://img.shields.io/badge/gratuits-3_159-1c5c41?style=flat-square) ![Connecteurs](https://img.shields.io/badge/connecteurs_actifs-8-1c5c41?style=flat-square) ![Régions](https://img.shields.io/badge/r%C3%A9gions-17%2F17-1c5c41?style=flat-square) ![Villes](https://img.shields.io/badge/villes-428-1c5c41?style=flat-square) ![Tests](https://img.shields.io/badge/tests-19_pass-1c5c41?style=flat-square) *Agrégateur indépendant de sorties & événements — concerts, festivals, spectacles, expositions, sport, famille — dans les 17 régions administratives du Québec, avec dates, lieux, gratuité, fiche par événement et lien direct vers la billetterie ou la source originale. Mise à jour horaire, automatiquement.* Page d'accueil Sorti-Ka
--- ## Pourquoi Sorti·Ka ? Trouver quoi faire au Québec, c'est ouvrir dix sites : les billetteries ne montrent que leurs propres spectacles, les calendriers municipaux que leur ville, les sites touristiques que leurs membres. **Sorti·Ka retourne le problème** : un connecteur dédié par source visite chaque calendrier, normalise chaque événement vers un schéma unique, déduplique les doublons inter-sources et détecte les changements en continu. Sorti·Ka n'est pas une billetterie : c'est un **index fidèle**. Aucun prix inventé, aucune date devinée — chaque fiche est attribuée à sa source et renvoie vers la fiche originale pour les billets. Membre de la famille **·Ka** ([Lou·Ka](https://www.lou-ka.com), Immo·Ka, Auto·Ka, Food·Ka, Fabri·Ka, Resto·Ka), architecture calquée sur le patron de référence Lou·Ka. ## Visite guidée | | | |:---:|:---:| | **Recherche filtrée** — région, catégorie, période, gratuité, texte libre | **Fiche par événement** — dates, lieu, prix, carte, similaires, SSR + JSON-LD | | Accueil | Fiche événement | ## L'architecture en 30 secondes ``` connecteurs (1 module / source) normalisation (Event) SQLite (diff + grâce) sortika/connectors/*.py → schema.py + normalize.py → db.py ▲ auto-découverts + regions.py (MAMH) │ │ ▼ watcher horaire (PM2) frontend SPA + fiches ← API FastAPI + SSR SEO ingest.py watch frontend/index.html web.py + seo.py ``` | Couche | Rôle | Fichiers | |---|---|---| | **Connecteurs** | 1 module Python par source : API JSON internes (Algolia evenko, Tourinsoft, CKAN), listes HTML, Scrapfly (Cloudflare), caches incrémentaux | `sortika/connectors/*.py` | | **Schéma** | `Event` standardisé : titre, catégories canoniques, lieu, ville, **région (17)**, lat/lng, dates ISO, gratuité/prix avec `price_label` source | `sortika/schema.py` | | **Normalisation** | dates FR/ISO, prix, catégories (14), villes, entités HTML | `sortika/normalize.py` | | **Régions** | Répertoire des municipalités MAMH : 1 250 villes + arrondissements + alias, homonymes résolus par population | `sortika/regions.py` + `data/villes_regions.json` | | **Persistance** | upsert par hash de contenu, délai de grâce 2 syncs, alerte de dérive, historique de syncs | `sortika/db.py` | | **Dédup** | empreinte titre + ville + date : un même concert publié par 3 sources = **une carte**, la fiche la plus riche gagne | `schema.dedup_key()` + `web.py` | | **API + SSR** | recherche/filtres JSON, fiches `/evenement/{uid}` servies avec `` unique + **JSON-LD Event**, robots, sitemaps | `sortika/web.py` + `sortika/seo.py` | | **Frontend** | SPA sans build, routeur History API, design system **Groupe KA « éditorial sharp »** | `frontend/index.html` | ## Les 8 connecteurs actifs | Source | Type / accès | Extraction | Volume | |---|---|---|---| | **Le point de vente** | billetterie QC — robots `Allow: *` | listes HTML paginées (~65 pages) | ~2 500 concerts, humour, théâtre — toute la province | | **SIT Québec** (Ministère du Tourisme) | données ouvertes CC 4.0 | API JSON Tourinsoft | ~1 600 événements touristiques, toutes les régions | | **Ville de Montréal** | données ouvertes CC BY 4.0 | API CKAN datastore | ~5 600 événements municipaux | | **evenko** | promoteur — robots `Allow: /api/search*` | proxy Algolia percé (`body=base64({params:[q,opts],lang})`) | ~460 grands concerts (Centre Bell, Place Bell, MTELUS…) | | **La Vitrine** | Content-Signal `search=yes, use=reference` | sitemap + fiches HTML (dates de tournée dédupliquées par id de représentation), cache incrémental | ~5 100 représentations | | **Atuvu.ca** | Cloudflare → **Scrapfly**, robots `Allow: /` | sitemaps lastmod + fiches, cache incrémental plafonné | rattrapage progressif | | **Ville de Sherbrooke** | calendrier municipal public | JSON embarqué `TRANSFER_CACHE` — 1 requête | ~270 événements avec images et gratuité | | **Ville de Laval** | données ouvertes CC 4.0 | JSON officiel | ~290 activités | Sources écartées après vérification (jeux périmés) : Longueuil (2017), Saguenay (2022), Repentigny (2021) — consignées au registre `data/sources.json` avec leur statut. ## Démarrage rapide ```bash python3 -m venv .venv && .venv/bin/pip install -r requirements.txt .venv/bin/python -m pytest tests/ -q # 19 tests (fixtures réelles, zéro réseau) .venv/bin/python run.py sync # ingestion des 8 sources .venv/bin/python run.py web --port 8120 # API + frontend + SSR .venv/bin/python run.py watch --interval 3600 # boucle d'ingestion horaire ``` Secrets : `SCRAPFLY_API_KEY` dans `.env` (requis seulement pour Atuvu). ## API | Route | Description | |---|---| | `GET /api/events` | recherche — `q`, `region`, `city`, `category`, `free`, `from`, `to`, `sort`, pagination ; dédupliquée inter-sources | | `GET /api/events/{uid}` | fiche complète d'un événement | | `GET /api/stats` | volumes par région et par catégorie | | `GET /api/sources` | registre des sources + événements actifs + dernière synchro | | `GET /evenement/{uid}` | fiche HTML SSR (title/og/canonical + **JSON-LD Event**) | | `GET /sitemap.xml` · `/robots.txt` | référencement | | `GET /docs` | Swagger | ## Production Nœud **M3U96a** (MacLustr) — PM2 : `sorti-ka-web` (uvicorn :8120), `sorti-ka-sync` (watch **horaire** — mise à jour continue), `sorti-ka-ngrok` (`www.sorti-ka.com`). Registre : `~/Desktop/cluster-skill/cluster-deployments.json`. ## Principes 1. **Index fidèle** — rien d'inventé : prix et dates viennent de la source, avec `price_label` original conservé et attribution systématique. 2. **Sources légitimes d'abord** — données ouvertes officielles et sites au robots.txt permissif ; CGU/licences consignées en tête de chaque connecteur. 3. **Travail de moine** — un connecteur robuste à la fois, testé sur fixtures réelles, avec alerte de dérive quand une source casse. 4. **Cohérence ·Ka** — architecture Lou·Ka, design system Groupe KA. --- © 2026 Sorti·Ka — Simon-Pierre Boucher \