From 2cbcff0757611143e8a8647a4f8e8198c0a58783 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Fri, 28 Aug 2026 10:30:00 +0100 Subject: [PATCH] Handle OSMCal events without locations --- check.py | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/check.py b/check.py index dd9d236..c0cef20 100755 --- a/check.py +++ b/check.py @@ -3,9 +3,11 @@ import email.message import email.utils +from urllib.parse import urlparse import smtplib import sys +import typing import requests import simplejson.errors @@ -15,7 +17,32 @@ SMTP_HOST = "4angle.com" URL = "https://osmcal.org/api/v2/events/?in=France" -SEEN_EVENT_IDS = {4064} +SEEN_EVENT_IDS = {4064, 4606, 4641} + + +def get_event_id(event: dict[str, typing.Any]) -> int | None: + """Extract the numeric event ID from API data.""" + if "id" in event: + return typing.cast(int, event["id"]) + + path_parts = [part for part in urlparse(event["url"]).path.split("/") if part] + if len(path_parts) >= 2 and path_parts[-2] == "event": + try: + return int(path_parts[-1]) + except ValueError: + return None + + return None + + +def get_detailed_location(event: dict[str, typing.Any]) -> str: + """Return an event's detailed location, or an empty string if absent.""" + location = event.get("location") + if not isinstance(location, dict): + return "" + + detailed = location.get("detailed") + return detailed if isinstance(detailed, str) else "" def send_mail(subject: str, body: str) -> None: @@ -44,16 +71,28 @@ def check_for_paris_events() -> None: print(r.text) raise - paris_events = [ + all_paris_events = [ event for event in events - if event["url"] != "https://osmcal.org/event/4064/" - and "paris" in event["location"]["detailed"].lower() + if "paris" in get_detailed_location(event).lower() + ] + seen_paris_events = [ + event for event in all_paris_events if get_event_id(event) in SEEN_EVENT_IDS + ] + paris_events = [ + event for event in all_paris_events if get_event_id(event) not in SEEN_EVENT_IDS ] if not paris_events: if sys.stdin.isatty(): - print(f"{len(events)} events found, none in Paris.") + total_events = len(events) + seen_count = len(seen_paris_events) + paris_label = "Paris event" if seen_count == 1 else "Paris events" + print( + f"{total_events} events found in France; " + + f"{seen_count} {paris_label} already seen; " + + "no new Paris events." + ) return subject = "Upcoming Paris OSM Hack Weekend Found!" @@ -63,7 +102,7 @@ def check_for_paris_events() -> None: body += ( f"{event['name']} - {event['url']}\n" + f"Date: {event['date']['human']}\n" - + f"Location: {event['location']['detailed']}\n\n" + + f"Location: {get_detailed_location(event)}\n\n" ) send_mail(subject, body)