From e26193dc3c799e89034d361679347603ab47a276 Mon Sep 17 00:00:00 2001 From: Nathan Panchout Date: Fri, 6 Feb 2026 17:39:08 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(back)=20extract=20ICS=20URL=20propert?= =?UTF-8?q?y=20and=20display=20in=20invitation=20emails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add visio conference URL support to invitation emails: - Add url field to EventDetails dataclass - Extract URL property in ICalendarParser.parse() - Fix extract_property regex to preserve full URLs (was truncating https:// by splitting on colon) - Add conditional visio section to all 8 email templates (invitation, update, cancel, reply — HTML and text) Co-Authored-By: Claude Opus 4.6 --- .../core/services/calendar_invitation_service.py | 14 +++++--------- .../core/templates/emails/calendar_invitation.html | 6 ++++++ .../core/templates/emails/calendar_invitation.txt | 1 + .../emails/calendar_invitation_cancel.html | 6 ++++++ .../emails/calendar_invitation_cancel.txt | 1 + .../emails/calendar_invitation_reply.html | 6 ++++++ .../templates/emails/calendar_invitation_reply.txt | 2 +- .../emails/calendar_invitation_update.html | 6 ++++++ .../emails/calendar_invitation_update.txt | 1 + 9 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/backend/core/services/calendar_invitation_service.py b/src/backend/core/services/calendar_invitation_service.py index 4d3e42c..7cde276 100644 --- a/src/backend/core/services/calendar_invitation_service.py +++ b/src/backend/core/services/calendar_invitation_service.py @@ -50,6 +50,7 @@ class EventDetails: summary: str description: Optional[str] location: Optional[str] + url: Optional[str] dtstart: datetime dtend: Optional[datetime] organizer_email: str @@ -95,17 +96,10 @@ class ICalendarParser: # Handle multi-line values (lines starting with space/tab are continuations) icalendar = re.sub(r"\r?\n[ \t]", "", icalendar) - pattern = rf"^{property_name}[;:](.+)$" + pattern = rf"^{property_name}(;[^:]*)?:(.+)$" match = re.search(pattern, icalendar, re.MULTILINE | re.IGNORECASE) if match: - value = match.group(1) - # Remove parameters (everything before the last colon if there are parameters) - if ";" in property_name or ":" not in value: - return value.strip() - # Handle properties with parameters like ORGANIZER;CN=Name:mailto:email - if ":" in value: - return value.split(":")[-1].strip() - return value.strip() + return match.group(2).strip() return None @staticmethod @@ -205,6 +199,7 @@ class ICalendarParser: summary = cls.extract_property(vevent_block, "SUMMARY") or "(Sans titre)" description = cls.extract_property(vevent_block, "DESCRIPTION") location = cls.extract_property(vevent_block, "LOCATION") + url = cls.extract_property(vevent_block, "URL") # Parse dates with timezone support - from VEVENT block only dtstart_raw, dtstart_params = cls.extract_property_with_params( @@ -265,6 +260,7 @@ class ICalendarParser: summary=summary, description=description, location=location, + url=url, dtstart=dtstart, dtend=dtend, organizer_email=organizer_email, diff --git a/src/backend/core/templates/emails/calendar_invitation.html b/src/backend/core/templates/emails/calendar_invitation.html index b4e0b9b..45e193e 100644 --- a/src/backend/core/templates/emails/calendar_invitation.html +++ b/src/backend/core/templates/emails/calendar_invitation.html @@ -119,6 +119,12 @@ {{ event.location }} {% endif %} + {% if event.url %} + + Visio + {{ event.url }} + + {% endif %} Organisateur {{ organizer_display }} <{{ event.organizer_email }}> diff --git a/src/backend/core/templates/emails/calendar_invitation.txt b/src/backend/core/templates/emails/calendar_invitation.txt index 90a81ed..fcac7bb 100644 --- a/src/backend/core/templates/emails/calendar_invitation.txt +++ b/src/backend/core/templates/emails/calendar_invitation.txt @@ -6,6 +6,7 @@ Détails de l'événement Titre : {{ event.summary }} Quand : {{ start_date }} {{ time_str }}{% if start_date != end_date %} - {{ end_date }}{% endif %} {% if event.location %}Lieu : {{ event.location }} +{% endif %}{% if event.url %}Visio : {{ event.url }} {% endif %}Organisateur : {{ organizer_display }} <{{ event.organizer_email }}> {% if event.description %} diff --git a/src/backend/core/templates/emails/calendar_invitation_cancel.html b/src/backend/core/templates/emails/calendar_invitation_cancel.html index 42c759a..42a05e5 100644 --- a/src/backend/core/templates/emails/calendar_invitation_cancel.html +++ b/src/backend/core/templates/emails/calendar_invitation_cancel.html @@ -114,6 +114,12 @@ {{ event.location }} {% endif %} + {% if event.url %} + + Visio + {{ event.url }} + + {% endif %} Organisateur {{ organizer_display }} <{{ event.organizer_email }}> diff --git a/src/backend/core/templates/emails/calendar_invitation_cancel.txt b/src/backend/core/templates/emails/calendar_invitation_cancel.txt index 8f479ec..ac4bada 100644 --- a/src/backend/core/templates/emails/calendar_invitation_cancel.txt +++ b/src/backend/core/templates/emails/calendar_invitation_cancel.txt @@ -6,6 +6,7 @@ Détails de l'événement annulé Titre : {{ event.summary }} Était prévu le : {{ start_date }} {{ time_str }}{% if start_date != end_date %} - {{ end_date }}{% endif %} {% if event.location %}Lieu : {{ event.location }} +{% endif %}{% if event.url %}Visio : {{ event.url }} {% endif %}Organisateur : {{ organizer_display }} <{{ event.organizer_email }}> Cet événement a été annulé. Vous pouvez le supprimer de votre calendrier en ouvrant le fichier .ics en pièce jointe. diff --git a/src/backend/core/templates/emails/calendar_invitation_reply.html b/src/backend/core/templates/emails/calendar_invitation_reply.html index 3ccf54d..09aa9e4 100644 --- a/src/backend/core/templates/emails/calendar_invitation_reply.html +++ b/src/backend/core/templates/emails/calendar_invitation_reply.html @@ -101,6 +101,12 @@ {{ event.location }} {% endif %} + {% if event.url %} + + Visio + {{ event.url }} + + {% endif %} Participant {{ attendee_display }} <{{ event.attendee_email }}> diff --git a/src/backend/core/templates/emails/calendar_invitation_reply.txt b/src/backend/core/templates/emails/calendar_invitation_reply.txt index 694a9c0..93dd626 100644 --- a/src/backend/core/templates/emails/calendar_invitation_reply.txt +++ b/src/backend/core/templates/emails/calendar_invitation_reply.txt @@ -6,8 +6,8 @@ Détails de l'événement Titre : {{ event.summary }} Quand : {{ start_date }} {{ time_str }}{% if start_date != end_date %} - {{ end_date }}{% endif %} {% if event.location %}Lieu : {{ event.location }} +{% endif %}{% if event.url %}Visio : {{ event.url }} {% endif %} - La réponse du participant a été enregistrée dans le fichier .ics en pièce jointe. --- diff --git a/src/backend/core/templates/emails/calendar_invitation_update.html b/src/backend/core/templates/emails/calendar_invitation_update.html index 944c69c..d4dd8ab 100644 --- a/src/backend/core/templates/emails/calendar_invitation_update.html +++ b/src/backend/core/templates/emails/calendar_invitation_update.html @@ -124,6 +124,12 @@ {{ event.location }} {% endif %} + {% if event.url %} + + Visio + {{ event.url }} + + {% endif %} Organisateur {{ organizer_display }} <{{ event.organizer_email }}> diff --git a/src/backend/core/templates/emails/calendar_invitation_update.txt b/src/backend/core/templates/emails/calendar_invitation_update.txt index 4a24e55..64abb75 100644 --- a/src/backend/core/templates/emails/calendar_invitation_update.txt +++ b/src/backend/core/templates/emails/calendar_invitation_update.txt @@ -6,6 +6,7 @@ Détails de l'événement mis à jour Titre : {{ event.summary }} Quand : {{ start_date }} {{ time_str }}{% if start_date != end_date %} - {{ end_date }}{% endif %} {% if event.location %}Lieu : {{ event.location }} +{% endif %}{% if event.url %}Visio : {{ event.url }} {% endif %}Organisateur : {{ organizer_display }} <{{ event.organizer_email }}> {% if event.description %}