From dac36592eb5d797d942c5e43af98a92f4321db21 Mon Sep 17 00:00:00 2001 From: para <157126561+mdegallaix@users.noreply.github.com> Date: Sat, 26 Sep 2026 00:05:52 +0200 Subject: [PATCH] Fetch full event detail: batch listing omits text_fr/attachments for events Found by testing: unlike news items, the agenda @results batch listing always returns text_fr and items (attachments) as null for events - only description_fr (short teaser) was ever available from it. The site itself works around this by firing a second request per event (@results?UID=&fullobjects=1) when you open one; we now do the same, with a per-UID cache since a recurring event shares one UID across all its occurrences. Co-Authored-By: Claude Sonnet 5 --- php/agenda.php | 27 ++++++++++++++++++++++++++- silly_rss.py | 26 +++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/php/agenda.php b/php/agenda.php index 4b01d88..d9907dd 100644 --- a/php/agenda.php +++ b/php/agenda.php @@ -25,6 +25,30 @@ function fetch_all_events(): array return $items; } +/** + * Contrairement aux actualites, l'API renvoie text_fr/items (texte complet + * et pieces jointes) a null dans la liste paginee des evenements - il faut + * une requete par UID pour les recuperer (c'est ce que fait le site + * lui-meme quand on ouvre un evenement). Un evenement recurrent partage un + * seul UID sur toutes ses occurrences, donc un cache statique evite de + * refaire la requete pour chaque occurrence. + */ +function fetch_event_detail(string $uid): ?array +{ + static $cache = []; + if (array_key_exists($uid, $cache)) { + return $cache[$uid]; + } + try { + $url = EVENTS_API . '?UID=' . rawurlencode($uid) . '&fullobjects=1'; + $data = json_decode(http_get($url), true); + $cache[$uid] = $data['items'][0] ?? null; + } catch (Throwable $e) { + $cache[$uid] = null; + } + return $cache[$uid]; +} + function format_event_meta(array $item): string { $parts = []; @@ -54,8 +78,9 @@ function build_events_feed(): string $title = $item['title_fr'] ?? $item['title'] ?? '(sans titre)'; $uid = $item['UID'] ?? $id; $meta = format_event_meta($item); + $detail = fetch_event_detail($uid); $description = ($meta !== '' ? '

' . htmlspecialchars($meta, ENT_QUOTES, 'UTF-8') . '

' : '') - . full_body_html($item, $title); + . full_body_html($detail ?? $item, $title); // Un evenement recurrent partage le meme UID sur toutes ses // occurrences (memes UID, dates differentes) : on suffixe le guid // avec la date de debut pour rester unique par occurrence, comme diff --git a/silly_rss.py b/silly_rss.py index a4273d8..3b43a8b 100644 --- a/silly_rss.py +++ b/silly_rss.py @@ -157,6 +157,29 @@ def build_news_items() -> list[str]: return entries +_event_detail_cache: dict[str, dict | None] = {} + + +def fetch_event_detail(uid: str) -> dict | None: + """ + Contrairement aux actualites, l'API renvoie text_fr/items (texte complet + et pieces jointes) a null dans la liste paginee des evenements - il faut + une requete par UID pour les recuperer (c'est ce que fait le site + lui-meme quand on ouvre un evenement). Un evenement recurrent partage un + seul UID sur toutes ses occurrences, d'ou le cache pour eviter de + refaire la requete pour chaque occurrence. + """ + if uid in _event_detail_cache: + return _event_detail_cache[uid] + try: + data = fetch_json(f"{EVENTS_API}?UID={uid}&fullobjects=1") + detail = (data.get("items") or [None])[0] + except Exception: + detail = None + _event_detail_cache[uid] = detail + return detail + + def format_event_meta(item: dict) -> str: parts = [] start = parse_dt(item.get("start")) @@ -183,7 +206,8 @@ def build_event_items() -> list[str]: guid = item.get("UID") or event_id link = f"{SITE}/agenda/{slugify(title)}?u={guid}" meta = format_event_meta(item) - description = (f"

{html.escape(meta)}

" if meta else "") + full_body_html(item, title) + detail = fetch_event_detail(guid) or item + description = (f"

{html.escape(meta)}

" if meta else "") + full_body_html(detail, title) pub_dt = parse_dt(item.get("created") or item.get("start")) # Un evenement recurrent partage le meme UID sur toutes ses # occurrences : on suffixe le guid avec la date de debut pour