From a84fe846fed489078af45636adbafe022af238b3 Mon Sep 17 00:00:00 2001 From: Daniel Grams Date: Sun, 2 Apr 2023 14:11:20 +0200 Subject: [PATCH 1/2] Bugfix iCalendar Recurrency Rule #400 --- project/services/event.py | 28 +++++++++++++++++++----- project/static/vue/organizer/read.vue.js | 2 +- tests/services/test_event.py | 5 ++++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/project/services/event.py b/project/services/event.py index a47b61f..8f5143f 100644 --- a/project/services/event.py +++ b/project/services/event.py @@ -5,6 +5,7 @@ import icalendar from dateutil.relativedelta import relativedelta from flask import url_for from flask_babelex import format_date, format_time, gettext +from icalendar.prop import vDDDLists from sqlalchemy import and_, case, func, or_ from sqlalchemy.orm import aliased, contains_eager, defaultload, joinedload, lazyload from sqlalchemy.sql import extract @@ -530,9 +531,23 @@ def populate_ical_event_with_datish( ical_event.add("dtstart", start) if recurrence_rule: - ical_event.add( - "rrule", icalendar.vRecur.from_ical(recurrence_rule.replace("RRULE:", "")) - ) + recc_lines = recurrence_rule.splitlines() + + for recc_line in recc_lines: + recc_line_parts = recc_line.split(":", 1) + + if len(recc_line_parts) != 2: + continue + + recc_key, recc_value = recc_line_parts + recc_key_lower = recc_key.lower() + + if recc_key_lower == "rrule": + ical_event.add("rrule", icalendar.vRecur.from_ical(recc_value)) + elif recc_key_lower == "exdate": + ical_event.add("exdate", vDDDLists.from_ical(recc_value)) + elif recc_key_lower == "rdate": + ical_event.add("rdate", vDDDLists.from_ical(recc_value)) if datish.end and datish.end > datish.start: end = datish.end.astimezone(berlin_tz) @@ -576,8 +591,11 @@ def create_ical_events_for_event(event: Event) -> list: # list[icalendar.Event] result = list() for date_definition in event.date_definitions: - ical_event = create_ical_event_for_date_definition(date_definition) - result.append(ical_event) + try: + ical_event = create_ical_event_for_date_definition(date_definition) + result.append(ical_event) + except Exception as e: # pragma: no cover + app.logger.exception(e) return result diff --git a/project/static/vue/organizer/read.vue.js b/project/static/vue/organizer/read.vue.js index 9a10107..05d8e88 100644 --- a/project/static/vue/organizer/read.vue.js +++ b/project/static/vue/organizer/read.vue.js @@ -43,7 +43,7 @@ const OrganizerRead = { - + {{ $t("shared.models.event.listName") }} diff --git a/tests/services/test_event.py b/tests/services/test_event.py index 533a53b..18f8865 100644 --- a/tests/services/test_event.py +++ b/tests/services/test_event.py @@ -273,7 +273,10 @@ def test_get_events_fulltext( def test_create_ical_events_for_event(client, app, db, utils, seeder): user_id, admin_unit_id = seeder.setup_base() - event_id = seeder.create_event(admin_unit_id) + event_id = seeder.create_event( + admin_unit_id, + recurrence_rule="RRULE:FREQ=DAILY;COUNT=10\nEXDATE:20300102T000000,20300104T000000\nRDATE:20300103T000000,20300105T000000", + ) with app.app_context(): from project.models import Event, EventStatus, Location From 3bf7ffdf1d4f36ae7dc260e809586d16715b1bfe Mon Sep 17 00:00:00 2001 From: Daniel Grams Date: Sun, 2 Apr 2023 14:27:09 +0200 Subject: [PATCH 2/2] Bugfix iCalendar Recurrency Rule #400 --- project/services/event.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/services/event.py b/project/services/event.py index 8f5143f..9854a8f 100644 --- a/project/services/event.py +++ b/project/services/event.py @@ -536,7 +536,7 @@ def populate_ical_event_with_datish( for recc_line in recc_lines: recc_line_parts = recc_line.split(":", 1) - if len(recc_line_parts) != 2: + if len(recc_line_parts) != 2: # pragma: no cover continue recc_key, recc_value = recc_line_parts