Apply same link/content fixes to the Python variant
Mirrors the fixes made to the PHP feeds: correct link format (/actualites|agenda/<slug>?u=<UID> instead of the wrong ?news=/?event=), and full rich-text body + attachment links instead of the short teaser only. Keeps both implementations in sync even though only the PHP one is currently deployed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+44
-13
@@ -14,6 +14,7 @@ import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import unicodedata
|
||||
from datetime import datetime, timezone
|
||||
from email.utils import format_datetime
|
||||
from xml.sax.saxutils import escape
|
||||
@@ -36,9 +37,6 @@ MAX_PAGES = 2 # jusqu'a 40 items par flux
|
||||
NEWS_API = f"{SITE}/actualites/@results"
|
||||
EVENTS_API = f"{SITE}/agenda/@results"
|
||||
|
||||
NEWS_LINK_TMPL = f"{SITE}/actualites?news={{id}}"
|
||||
EVENT_LINK_TMPL = f"{SITE}/agenda?event={{id}}"
|
||||
|
||||
|
||||
def fetch_json(url: str) -> dict:
|
||||
result = subprocess.run(
|
||||
@@ -72,6 +70,42 @@ def strip_html(text: str | None) -> str:
|
||||
return re.sub(r"\s+", " ", text).strip()
|
||||
|
||||
|
||||
def slugify(text: str) -> str:
|
||||
"""
|
||||
Reproduit le slug d'URL genere par le site (cosmetique : le routeur JS
|
||||
de silly.be lit en realite le parametre `u` pour savoir quel item
|
||||
afficher, pas ce segment de chemin - mais autant coller a l'URL
|
||||
"officielle" telle qu'on la voit dans la barre d'adresse).
|
||||
"""
|
||||
ascii_text = unicodedata.normalize("NFKD", text).encode("ascii", "ignore").decode("ascii")
|
||||
ascii_text = ascii_text.lower()
|
||||
ascii_text = re.sub(r"[^a-z0-9]+", "-", ascii_text)
|
||||
return ascii_text.strip("-")
|
||||
|
||||
|
||||
def attachments_html(item: dict) -> str:
|
||||
"""HTML des liens vers les pieces jointes (PDF, etc.) d'un item."""
|
||||
parts = []
|
||||
for sub in item.get("items") or []:
|
||||
file_info = sub.get("file") or {}
|
||||
url = file_info.get("download") or sub.get("targetUrl")
|
||||
if not url:
|
||||
continue
|
||||
label = sub.get("title") or url.rsplit("/", 1)[-1]
|
||||
parts.append(f'<p><a href="{html.escape(url)}">{html.escape(label)}</a></p>')
|
||||
return "".join(parts)
|
||||
|
||||
|
||||
def full_body_html(item: dict) -> str:
|
||||
"""Corps HTML complet (texte riche + pieces jointes), repli sur le resume court."""
|
||||
text_fr = item.get("text_fr")
|
||||
body = (text_fr.get("data") or "").strip() if isinstance(text_fr, dict) else ""
|
||||
if not body:
|
||||
summary = strip_html(item.get("description_fr") or item.get("description"))
|
||||
body = f"<p>{html.escape(summary)}</p>" if summary else ""
|
||||
return body + attachments_html(item)
|
||||
|
||||
|
||||
def parse_dt(value: str | None) -> datetime | None:
|
||||
if not value:
|
||||
return None
|
||||
@@ -91,13 +125,11 @@ def build_news_items() -> list[str]:
|
||||
entries = []
|
||||
for item in fetch_all_items(NEWS_API):
|
||||
item_id = item.get("id", "")
|
||||
link = NEWS_LINK_TMPL.format(id=item_id)
|
||||
title = item.get("title_fr") or item.get("title") or "(sans titre)"
|
||||
summary = strip_html(item.get("description_fr") or item.get("description"))
|
||||
body = strip_html(item.get("text_fr", {}).get("data") if isinstance(item.get("text_fr"), dict) else None)
|
||||
description = summary or body
|
||||
pub_dt = parse_dt(item.get("effective") or item.get("created"))
|
||||
guid = item.get("UID") or item_id
|
||||
link = f"{SITE}/actualites/{slugify(title)}?u={guid}"
|
||||
description = full_body_html(item)
|
||||
pub_dt = parse_dt(item.get("effective") or item.get("created"))
|
||||
entries.append(
|
||||
" <item>\n"
|
||||
f" <title>{escape(title)}</title>\n"
|
||||
@@ -132,13 +164,12 @@ def build_event_items() -> list[str]:
|
||||
entries = []
|
||||
for item in fetch_all_items(EVENTS_API):
|
||||
event_id = item.get("@id", "").rstrip("/").split("/")[-1]
|
||||
link = EVENT_LINK_TMPL.format(id=event_id)
|
||||
title = item.get("title_fr") or item.get("title") or "(sans titre)"
|
||||
summary = strip_html(item.get("description_fr") or item.get("description"))
|
||||
meta = format_event_meta(item)
|
||||
description = " | ".join(p for p in (meta, summary) if p)
|
||||
pub_dt = parse_dt(item.get("created") or item.get("start"))
|
||||
guid = item.get("UID") or event_id
|
||||
link = f"{SITE}/agenda/{slugify(title)}?u={guid}"
|
||||
meta = format_event_meta(item)
|
||||
description = (f"<p>{html.escape(meta)}</p>" if meta else "") + full_body_html(item)
|
||||
pub_dt = parse_dt(item.get("created") or item.get("start"))
|
||||
entries.append(
|
||||
" <item>\n"
|
||||
f" <title>{escape(title)}</title>\n"
|
||||
|
||||
Reference in New Issue
Block a user