SPB Git forge

spb/job-ka

Public
227commits 1branches 0releases
37.7 MBsize
maindefault branch
28 min agolast push
HTML 82.1% Python 14.6% TypeScript 1.9% CSS 1% JavaScript 0.5%

Qualité lieux : rejet des villes canadiennes/monde hors Québec + bâtiments McGill mappés vers Montréal

- normalize.py : _NON_QC_CITIES (villes CA hors QC + grandes villes monde) —
  parse_location ne prend plus ces libellés pour des villes et
  is_quebec_location les rejette explicitement ; purge BD : 127 offres
  actives hors-QC désactivées (Toronto 50, etc.)
- mcgill.py : les lieux Workday de McGill sont des bâtiments (Bronfman
  Building, Currie Gymnasium…) -> ville forcée Montréal (Outaouais ->
  Gatineau) ; 182 offres corrigées en BD

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

2 changed files +44 −2

modified jobka/connectors/mcgill.py +13 −1
@@ -6,7 +6,8 @@
6 6 # Rôle : Connecteur Université McGill (Montréal) — Workday mcgill.wd3,
7 7 # site « McGill_Careers ». Tous les postes sont au Québec (campus) :
8 8 # les lieux sont des bâtiments, pas des villes -> quebec_only=False
9 −# Créé : 2026-08-17 Modifié : 2026-08-17
9 +# et ville forcée à Montréal (Gatineau pour le campus Outaouais)
10 +# Créé : 2026-08-17 Modifié : 2026-08-18
10 11 # =============================================================================
11 12 from .workday import WorkdayConnector
12 13
@@ -18,3 +19,14 @@ class McgillConnector(WorkdayConnector):
18 19 HOST = "wd3"
19 20 SITE = "McGill_Careers"
20 21 quebec_only = False # campus montréalais : lieux = noms de bâtiments
22 +
23 + def fetch(self):
24 + """Les « lieux » Workday de McGill sont des bâtiments (« Bronfman
25 + Building », « Currie Gymnasium »…) que le parseur prendrait pour des
26 + villes : on force la ville réelle du campus."""
27 + jobs = super().fetch()
28 + for j in jobs:
29 + label = (j.location_label or j.city or "").lower()
30 + j.city = "Gatineau" if "outaouais" in label else "Montréal"
31 + j.region = "Québec"
32 + return jobs
modified jobka/normalize.py +31 −1
@@ -5,7 +5,7 @@
5 5 # Fichier : jobka/normalize.py
6 6 # Rôle : Normalisation commune des offres (salaires, dates, mode/type
7 7 # d'emploi, lieu, catégorie) — jamais de valeur inventée
8 −# Créé : 2026-08-17 Modifié : 2026-08-17
8 +# Créé : 2026-08-17 Modifié : 2026-08-18
9 9 # =============================================================================
10 10 """Couche de normalisation commune appelée par JobPosting.finalize().
11 11
@@ -358,6 +358,33 @@ _QC_MARKERS = re.compile(
358 358 r"\bqc\b|\bquebec\b|\bqu[e]bec, canada\b|province de quebec", re.I)
359 359 _POSTAL_RE = re.compile(r"\b([GHJ]\d[A-Z])\s*(\d[A-Z]\d)\b", re.I) # G/H/J = Québec
360 360
361 +# Villes canadiennes hors Québec (et grandes villes étrangères) fréquentes
362 +# dans les flux pancanadiens/mondiaux — jamais des villes d'offres
363 +# québécoises : à rejeter lors du parsing de lieu (clés sans accents).
364 +_NON_QC_CITIES = frozenset({
365 + "toronto", "ottawa", "vancouver", "calgary", "edmonton", "winnipeg",
366 + "mississauga", "brampton", "hamilton", "kitchener", "waterloo", "halifax",
367 + "dartmouth", "victoria", "saskatoon", "regina", "st. john's", "st johns",
368 + "saint john", "fredericton", "moncton", "charlottetown", "london",
369 + "markham", "vaughan", "richmond hill", "oakville", "burlington", "oshawa",
370 + "whitby", "ajax", "pickering", "guelph", "kingston", "barrie",
371 + "kelowna", "kamloops", "nanaimo", "abbotsford", "surrey", "burnaby",
372 + "coquitlam", "langley", "north york", "scarborough", "etobicoke",
373 + "north vancouver", "milton", "cambridge", "st. catharines",
374 + "niagara falls", "thunder bay", "sudbury", "greater sudbury",
375 + "sault ste. marie", "red deer", "lethbridge", "medicine hat",
376 + "grande prairie", "fort mcmurray", "yellowknife", "whitehorse", "iqaluit",
377 + "can", "canada", "ontario", "alberta", "british columbia", "manitoba",
378 + "saskatchewan", "nova scotia", "new brunswick",
379 + "new york", "new york city", "san francisco", "boston", "chicago",
380 + "seattle", "austin", "denver", "los angeles", "miami", "atlanta",
381 + "dallas", "houston", "philadelphia", "washington", "phoenix", "portland",
382 + "paris", "londres", "amsterdam", "berlin", "munich", "dublin", "madrid",
383 + "barcelona", "barcelone", "lisbon", "lisbonne", "sydney", "melbourne",
384 + "singapore", "singapour", "tokyo", "bangalore", "bengaluru", "mumbai",
385 + "mexico city", "sao paulo", "bogota", "buenos aires",
386 +})
387 +
361 388
362 389 def canonical_city(raw: str) -> str:
363 390 """Canonicalise un nom de ville (« Montreal » -> « Montréal »,
@@ -403,6 +430,7 @@ def parse_location(raw: str) -> dict:
403 430 seg_key = _key(seg)
404 431 if (seg and len(seg) <= 40 and re.search(r"[a-z]", seg_key)
405 432 and len(seg.split()) <= 3
433 + and seg_key not in _NON_QC_CITIES
406 434 and not re.search(
407 435 r"remote|teletravail|canada|multiple|various|partout|"
408 436 r"\d+\s+locations?|\d+\s+lieux|caisse|succursale|"
@@ -416,6 +444,8 @@ def is_quebec_location(raw: str) -> bool:
416 444 key = _key(clean_text(raw))
417 445 if not key:
418 446 return False
447 + if key in _NON_QC_CITIES: # libellé = ville canadienne/monde hors QC
448 + return False
419 449 if _QC_MARKERS.search(key):
420 450 return True
421 451 m = _POSTAL_RE.search(raw)
422 452