# ============================================================================== # Author: Simon-Pierre Boucher # File: scripts/backfill_images.py # Desc: Rattrapage ponctuel — photos des restos site-resto captés AVANT # l'extraction d'images du connecteur (2026-08-23) : re-visite la page # d'accueil du site de chaque fiche site-resto sans images (et de sa # fiche OSM jumelle) et pose jusqu'à 6 photos via # SiteRestoConnector._extract_images. Idempotent : ne touche que les # fiches où images est vide. # Usage : .venv/bin/python scripts/backfill_images.py [max_sites] # ============================================================================== from __future__ import annotations import json import sys from concurrent.futures import ThreadPoolExecutor sys.path.insert(0, ".") from restoka import db # noqa: E402 from restoka.connectors.siteresto import SiteRestoConnector, _domain # noqa: E402 MAX = int(sys.argv[1]) if len(sys.argv) > 1 else 400 WORKERS = 6 con = db.connect() rows = con.execute( """SELECT uid, external_id, name, website, url FROM restaurants WHERE source='site-resto' AND active=1 AND (images IS NULL OR images='' OR images='[]') LIMIT ?""", (MAX,)).fetchall() print(f"{len(rows)} fiches site-resto sans images à rattraper") def _one(row): worker = SiteRestoConnector() site = (row["website"] or "").strip() if not site: # la fiche site-resto garde le site dans la fiche OSM jumelle ; url = # page du menu, son domaine suffit pour retrouver l'accueil site = "https://" + _domain(row["url"] or "") if not site.startswith("http"): site = "https://" + site try: html = worker._get_html(site) imgs = worker._extract_images(html, site) return row["uid"], row["external_id"], imgs except Exception as exc: print(f" {row['name']}: erreur {exc}", file=sys.stderr) return row["uid"], row["external_id"], [] done = with_img = 0 with ThreadPoolExecutor(max_workers=WORKERS) as pool: for uid, ext_id, imgs in pool.map(_one, rows): done += 1 if not imgs: continue blob = json.dumps(imgs) # fiche site-resto + fiche OSM jumelle (même external_id), si vides for target in (uid, f"osm:{ext_id.split(':', 1)[-1]}", f"osm:{ext_id}"): con.execute( "UPDATE restaurants SET images=? WHERE uid=? AND" " (images IS NULL OR images='' OR images='[]')", (blob, target)) con.commit() with_img += 1 if with_img % 25 == 0: print(f" {with_img}/{done} fiches avec photos…") print(f"terminé : {with_img}/{done} fiches enrichies de photos")