SPB Git forge

spb/rent-ka

Public
8commits 1branches 0releases
7.4 MBsize
maindefault branch
19 days agolast push
Python 68.8% TypeScript 18.6% CSS 8.7% JavaScript 3.3% HTML 0.6%
2.7 KB · 76 lines python
Raw Blame History
1# -----------------------------------------------------------------------------2# Rent-Ka — Rental listings aggregator (Canada, outside Québec)3# Author: Simon-Pierre Boucher — contact@spboucher.ai4# hubfav.py : favoris unifiés « Mon univers Ka » — chaque ♥ ajouté/retiré sur5#   Rent-Ka est poussé au hub Groupe KA (magasin central des favoris du6#   groupe), signé HMAC du secret SSO partagé. Poussée en arrière-plan7#   (thread), jamais bloquante : un échec réseau n'affecte pas le ♥ local.8#   Config .env : KA_SSO_SECRET, KA_HUB_URL (optionnel).9# -----------------------------------------------------------------------------10from __future__ import annotations1112import hashlib13import hmac14import os15import threading16import time1718import requests1920CLIENT_ID = "rent-ka"21KA_HUB_URL = os.environ.get("KA_HUB_URL", "https://www.groupe-ka.com").rstrip("/")222324def _sig(ka_id: str, ts: int) -> str | None:25    secret = os.environ.get("KA_SSO_SECRET")26    if not secret:27        return None28    return hmac.new(secret.encode(),29                    f"{CLIENT_ID}.{ka_id}.{ts}".encode(),30                    hashlib.sha256).hexdigest()313233def _push(ka_id: str, action: str, item: dict) -> None:34    ts = int(time.time())35    sig = _sig(ka_id, ts)36    if not sig:37        return38    try:39        requests.post(f"{KA_HUB_URL}/api/sso/favorites", timeout=6, json={40            "client_id": CLIENT_ID, "ka_id": ka_id,41            "ts": str(ts), "sig": sig,42            "action": action, "item": item,43        })44    except Exception:45        pass    # best-effort : le favori local reste la référence d'affichage464748def push_favorite(ka_id: str | None, action: str, item: dict) -> None:49    """Pousse un ♥ (action « add » ou « remove ») au hub, sans bloquer."""50    if not ka_id or not str(ka_id).startswith("ka-"):51        return    # compte legacy non relié au hub52    threading.Thread(target=_push, args=(ka_id, action, item),53                     daemon=True).start()545556def listing_item(row) -> dict:57    """Transforme une ligne `listings` en item de favori pour le hub."""58    import json as _json59    d = dict(row)60    try:61        images = _json.loads(d.get("images") or "[]")62    except Exception:63        images = []64    title = d.get("title") or d.get("address") or "Logement"65    bits = [b for b in [d.get("unit_type"), d.get("sector") or d.get("city")]66            if b]67    return {68        "item_id": d["uid"],69        "title": str(title)[:200],70        "subtitle": " · ".join(str(b) for b in bits)[:200],71        "price_label": (d.get("price_label")72                        or (f"{int(d['price'])} $/mois" if d.get("price") else ""))[:60],73        "image_url": (images[0] if images else "")[:500],74        "url": f"https://www.rent-ka.com/listing/{d['uid']}",75    }76