From 5dfa3bc9e78f282e54cc4b352e66426dcf4fc6cc Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Mon, 7 Oct 2024 15:42:09 +0100 Subject: [PATCH 1/6] Test types of new properties --- src/icalendar/cal.py | 2 +- src/icalendar/prop.py | 1 + .../tests/events/rfc_9074_example_1.ics | 16 ++++++++++++ .../tests/events/rfc_9074_example_2.ics | 25 ++++++++++++++++++ .../tests/events/rfc_9074_example_3.ics | 25 ++++++++++++++++++ .../tests/events/rfc_9074_example_4.ics | 26 +++++++++++++++++++ .../events/rfc_9074_example_proximity.ics | 14 ++++++++++ src/icalendar/tests/test_rfc_9074.py | 24 +++++++++++++++++ 8 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/icalendar/tests/events/rfc_9074_example_1.ics create mode 100644 src/icalendar/tests/events/rfc_9074_example_2.ics create mode 100644 src/icalendar/tests/events/rfc_9074_example_3.ics create mode 100644 src/icalendar/tests/events/rfc_9074_example_4.ics create mode 100644 src/icalendar/tests/events/rfc_9074_example_proximity.ics create mode 100644 src/icalendar/tests/test_rfc_9074.py diff --git a/src/icalendar/cal.py b/src/icalendar/cal.py index 83553f2a..468d6710 100644 --- a/src/icalendar/cal.py +++ b/src/icalendar/cal.py @@ -742,7 +742,7 @@ class Alarm(Component): required = ('ACTION', 'TRIGGER',) singletons = ( 'ATTACH', 'ACTION', 'DESCRIPTION', 'SUMMARY', 'TRIGGER', - 'DURATION', 'REPEAT', + 'DURATION', 'REPEAT', 'UID' ) inclusive = (('DURATION', 'REPEAT',), ('SUMMARY', 'ATTENDEE',)) multiple = ('ATTENDEE', 'ATTACH') diff --git a/src/icalendar/prop.py b/src/icalendar/prop.py index e7f58aba..738c3e8a 100644 --- a/src/icalendar/prop.py +++ b/src/icalendar/prop.py @@ -1072,6 +1072,7 @@ def __init__(self, *args, **kwargs): 'action': 'text', 'repeat': 'integer', 'trigger': 'duration', + 'acknowledged': 'date-time', # Change Management Component Properties 'created': 'date-time', 'dtstamp': 'date-time', diff --git a/src/icalendar/tests/events/rfc_9074_example_1.ics b/src/icalendar/tests/events/rfc_9074_example_1.ics new file mode 100644 index 00000000..97f885f3 --- /dev/null +++ b/src/icalendar/tests/events/rfc_9074_example_1.ics @@ -0,0 +1,16 @@ +BEGIN:VEVENT +CREATED:20210302T151004Z +UID:AC67C078-CED3-4BF5-9726-832C3749F627 +DTSTAMP:20210302T151004Z +DTSTART;TZID=America/New_York:20210302T103000 +DTEND;TZID=America/New_York:20210302T113000 +SUMMARY:Meeting + +BEGIN:VALARM +UID:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 +TRIGGER:-PT15M +DESCRIPTION:Event reminder +ACTION:DISPLAY +END:VALARM + +END:VEVENT \ No newline at end of file diff --git a/src/icalendar/tests/events/rfc_9074_example_2.ics b/src/icalendar/tests/events/rfc_9074_example_2.ics new file mode 100644 index 00000000..4dfe34cc --- /dev/null +++ b/src/icalendar/tests/events/rfc_9074_example_2.ics @@ -0,0 +1,25 @@ +BEGIN:VEVENT +CREATED:20210302T151004Z +UID:AC67C078-CED3-4BF5-9726-832C3749F627 +DTSTAMP:20210302T151516Z +DTSTART;TZID=America/New_York:20210302T103000 +DTEND;TZID=America/New_York:20210302T113000 +SUMMARY:Meeting + +BEGIN:VALARM +UID:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 +TRIGGER:-PT15M +DESCRIPTION:Event reminder +ACTION:DISPLAY +ACKNOWLEDGED:20210302T151514Z +END:VALARM + +BEGIN:VALARM +UID:DE7B5C34-83FF-47FE-BE9E-FF41AE6DD097 +TRIGGER;VALUE=DATE-TIME:20210302T152000Z +RELATED-TO;RELTYPE=SNOOZE:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 +DESCRIPTION:Event reminder +ACTION:DISPLAY +END:VALARM + +END:VEVENT diff --git a/src/icalendar/tests/events/rfc_9074_example_3.ics b/src/icalendar/tests/events/rfc_9074_example_3.ics new file mode 100644 index 00000000..e0b134f5 --- /dev/null +++ b/src/icalendar/tests/events/rfc_9074_example_3.ics @@ -0,0 +1,25 @@ +BEGIN:VEVENT +CREATED:20210302T151004Z +UID:AC67C078-CED3-4BF5-9726-832C3749F627 +DTSTAMP:20210302T152026Z +DTSTART;TZID=America/New_York:20210302T103000 +DTEND;TZID=America/New_York:20210302T113000 +SUMMARY:Meeting + +BEGIN:VALARM +UID:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 +TRIGGER:-PT15M +DESCRIPTION:Event reminder +ACTION:DISPLAY +ACKNOWLEDGED:20210302T152024Z +END:VALARM + +BEGIN:VALARM +UID:87D690A7-B5E8-4EB4-8500-491F50AFE394 +TRIGGER;VALUE=DATE-TIME:20210302T152500Z +RELATED-TO;RELTYPE=SNOOZE:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 +DESCRIPTION:Event reminder +ACTION:DISPLAY +END:VALARM + +END:VEVENT diff --git a/src/icalendar/tests/events/rfc_9074_example_4.ics b/src/icalendar/tests/events/rfc_9074_example_4.ics new file mode 100644 index 00000000..fe2f011f --- /dev/null +++ b/src/icalendar/tests/events/rfc_9074_example_4.ics @@ -0,0 +1,26 @@ +BEGIN:VEVENT +CREATED:20210302T151004Z +UID:AC67C078-CED3-4BF5-9726-832C3749F627 +DTSTAMP:20210302T152508Z +DTSTART;TZID=America/New_York:20210302T103000 +DTEND;TZID=America/New_York:20210302T113000 +SUMMARY:Meeting + +BEGIN:VALARM +UID:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 +TRIGGER:-PT15M +DESCRIPTION:Event reminder +ACTION:DISPLAY +ACKNOWLEDGED:20210302T152507Z +END:VALARM + +BEGIN:VALARM +UID:87D690A7-B5E8-4EB4-8500-491F50AFE394 +TRIGGER;VALUE=DATE-TIME:20210302T152500Z +RELATED-TO;RELTYPE=SNOOZE:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 +DESCRIPTION:Event reminder +ACTION:DISPLAY +ACKNOWLEDGED:20210302T152507Z +END:VALARM + +END:VEVENT \ No newline at end of file diff --git a/src/icalendar/tests/events/rfc_9074_example_proximity.ics b/src/icalendar/tests/events/rfc_9074_example_proximity.ics new file mode 100644 index 00000000..9f8ceac7 --- /dev/null +++ b/src/icalendar/tests/events/rfc_9074_example_proximity.ics @@ -0,0 +1,14 @@ +BEGIN:VEVENT +BEGIN:VALARM +UID:77D80D14-906B-4257-963F-85B1E734DBB6 +ACTION:DISPLAY +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +DESCRIPTION:Remember to buy milk +PROXIMITY:DEPART +BEGIN:VLOCATION +UID:123456-abcdef-98765432 +NAME:Office +URL:geo:40.443,-79.945;u=10 +END:VLOCATION +END:VALARM +END:VEVENT diff --git a/src/icalendar/tests/test_rfc_9074.py b/src/icalendar/tests/test_rfc_9074.py new file mode 100644 index 00000000..49723960 --- /dev/null +++ b/src/icalendar/tests/test_rfc_9074.py @@ -0,0 +1,24 @@ +"""Test the VALARM compatibility of RFC 9074. + +See https://www.rfc-editor.org/rfc/rfc9074.html +and also https://github.com/collective/icalendar/issues/657 +""" +import pytest +from icalendar.prop import vText, vDDDTypes + + +@pytest.mark.parametrize( + ("prop", "cls", "file", "alarm_index"), + [ + ("UID", vText, "rfc_9074_example_1", 0), + ("RELATED-TO", vText, "rfc_9074_example_2", 1), + ("ACKNOWLEDGED", vDDDTypes, "rfc_9074_example_3", 0), + ("PROXIMITY", vText, "rfc_9074_example_proximity", 0), + ] +) +def test_calendar_types(events, prop, cls, file, alarm_index): + """Check the types of the properties.""" + event = events[file] + alarm = event.subcomponents[alarm_index] + value = alarm[prop] + assert isinstance(value, cls) From 815279d7908207ccad9f1255e0495fcba8578d18 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Mon, 7 Oct 2024 15:49:40 +0100 Subject: [PATCH 2/6] test snooze and proximity --- src/icalendar/cal.py | 2 +- src/icalendar/tests/test_rfc_9074.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/icalendar/cal.py b/src/icalendar/cal.py index 468d6710..b2f2effe 100644 --- a/src/icalendar/cal.py +++ b/src/icalendar/cal.py @@ -742,7 +742,7 @@ class Alarm(Component): required = ('ACTION', 'TRIGGER',) singletons = ( 'ATTACH', 'ACTION', 'DESCRIPTION', 'SUMMARY', 'TRIGGER', - 'DURATION', 'REPEAT', 'UID' + 'DURATION', 'REPEAT', 'UID', 'PROXIMITY', ) inclusive = (('DURATION', 'REPEAT',), ('SUMMARY', 'ATTENDEE',)) multiple = ('ATTENDEE', 'ATTACH') diff --git a/src/icalendar/tests/test_rfc_9074.py b/src/icalendar/tests/test_rfc_9074.py index 49723960..2ded7adf 100644 --- a/src/icalendar/tests/test_rfc_9074.py +++ b/src/icalendar/tests/test_rfc_9074.py @@ -22,3 +22,20 @@ def test_calendar_types(events, prop, cls, file, alarm_index): alarm = event.subcomponents[alarm_index] value = alarm[prop] assert isinstance(value, cls) + + +def test_snooze(events): + """Check values of the alarms.""" + alarm_1 = events.rfc_9074_example_3.subcomponents[0] + assert alarm_1["ACKNOWLEDGED"].dt == vDDDTypes.from_ical("20210302T152024Z") + alarm_2 = events.rfc_9074_example_3.subcomponents[1] + assert alarm_2["RELATED-TO"] == "8297C37D-BA2D-4476-91AE-C1EAA364F8E1" + assert alarm_2["RELATED-TO"].params["RELTYPE"] == "SNOOZE" + +def test_proximity(events): + """Check the proximity values.""" + alarm = events.rfc_9074_example_proximity.subcomponents[0] + assert alarm["PROXIMITY"] == "DEPART" + assert len(alarm.subcomponents) == 1 + location = alarm.subcomponents[0] + assert location["UID"] == "123456-abcdef-98765432" From 6acdc377f3791d479e2cefc19eb20e4e956eceb9 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Mon, 7 Oct 2024 15:54:16 +0100 Subject: [PATCH 3/6] add new properties to singletons and multiple in Alarm class --- src/icalendar/cal.py | 4 ++-- src/icalendar/tests/test_rfc_9074.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/icalendar/cal.py b/src/icalendar/cal.py index b2f2effe..6233a79d 100644 --- a/src/icalendar/cal.py +++ b/src/icalendar/cal.py @@ -742,10 +742,10 @@ class Alarm(Component): required = ('ACTION', 'TRIGGER',) singletons = ( 'ATTACH', 'ACTION', 'DESCRIPTION', 'SUMMARY', 'TRIGGER', - 'DURATION', 'REPEAT', 'UID', 'PROXIMITY', + 'DURATION', 'REPEAT', 'UID', 'PROXIMITY', 'ACKNOWLEDGED' ) inclusive = (('DURATION', 'REPEAT',), ('SUMMARY', 'ATTENDEE',)) - multiple = ('ATTENDEE', 'ATTACH') + multiple = ('ATTENDEE', 'ATTACH', 'RELATED-TO') class Calendar(Component): diff --git a/src/icalendar/tests/test_rfc_9074.py b/src/icalendar/tests/test_rfc_9074.py index 2ded7adf..d7cd1de4 100644 --- a/src/icalendar/tests/test_rfc_9074.py +++ b/src/icalendar/tests/test_rfc_9074.py @@ -32,6 +32,7 @@ def test_snooze(events): assert alarm_2["RELATED-TO"] == "8297C37D-BA2D-4476-91AE-C1EAA364F8E1" assert alarm_2["RELATED-TO"].params["RELTYPE"] == "SNOOZE" + def test_proximity(events): """Check the proximity values.""" alarm = events.rfc_9074_example_proximity.subcomponents[0] From 38eeb2b96fa1398610f8633fa2017850c64aa7ef Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Mon, 7 Oct 2024 16:02:23 +0100 Subject: [PATCH 4/6] log changes --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9015a3bd..460a199b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,7 +14,7 @@ Breaking changes: New features: -- ... +- Add ``VALARM`` properties for :rfc:`9074`, see `Issue 657 `_ Bug fixes: From 7dc251ca45fa06609058997838abd1392805ca90 Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Mon, 7 Oct 2024 16:04:08 +0100 Subject: [PATCH 5/6] ruff formatting --- src/icalendar/tests/test_rfc_9074.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/icalendar/tests/test_rfc_9074.py b/src/icalendar/tests/test_rfc_9074.py index d7cd1de4..3fb22f93 100644 --- a/src/icalendar/tests/test_rfc_9074.py +++ b/src/icalendar/tests/test_rfc_9074.py @@ -4,7 +4,8 @@ and also https://github.com/collective/icalendar/issues/657 """ import pytest -from icalendar.prop import vText, vDDDTypes + +from icalendar.prop import vDDDTypes, vText @pytest.mark.parametrize( From 51418963bbc1ad39b3e1b801f18ed62ca46e352d Mon Sep 17 00:00:00 2001 From: Nicco Kunzmann Date: Mon, 7 Oct 2024 16:15:38 +0100 Subject: [PATCH 6/6] Update dependencies and RFC compatibility --- README.rst | 11 +++++------ docs/usage.rst | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/README.rst b/README.rst index 370ba277..4b6ab205 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,7 @@ Internet Calendaring and Scheduling (iCalendar) for Python ========================================================== -The `icalendar`_ package is a `RFC 5545`_ compatible parser/generator for iCalendar +The `icalendar`_ package is a :rfc:`5545` compatible parser/generator for iCalendar files. ---- @@ -10,7 +10,7 @@ files. :Homepage: https://icalendar.readthedocs.io :Code: https://github.com/collective/icalendar :Mailing list: https://github.com/collective/icalendar/issues -:Dependencies: `python-dateutil`_ and `pytz`_. +:Dependencies: `python-dateutil`_ and `tzdata`_. :License: `BSD`_ ---- @@ -41,9 +41,8 @@ files. .. _`icalendar`: https://pypi.org/project/icalendar/ -.. _`RFC 5545`: https://www.ietf.org/rfc/rfc5545.txt .. _`python-dateutil`: https://github.com/dateutil/dateutil/ -.. _`pytz`: https://pypi.org/project/pytz/ +.. _`tzdata`: https://pypi.org/project/tzdata/ .. _`BSD`: https://github.com/collective/icalendar/issues/2 Quick start guide @@ -96,7 +95,7 @@ Create Events, TODOs, Journals, Alarms, ... ------------------------------------------- ``icalendar`` supports the creation and parsing of all kinds of objects -in the iCalendar (RFC 5545) standard. +in the iCalendar (:rfc:`5545`) standard. .. code:: python @@ -177,7 +176,7 @@ Related projects * `icalevents `_. It is built on top of icalendar and allows you to query iCal files and get the events happening on specific dates. It manages recurrent events as well. * `recurring-ical-events `_. Library to query an ``ICalendar`` object for events happening at a certain date or within a certain time. -* `x-wr-timezone `_. Library to make ``ICalendar`` objects and files using the non-standard ``X-WR-TIMEZONE`` compliant with the standard (RFC 5545). +* `x-wr-timezone `_. Library to make ``ICalendar`` objects and files using the non-standard ``X-WR-TIMEZONE`` compliant with the standard (:rfc:`5545`). Further Reading =============== diff --git a/docs/usage.rst b/docs/usage.rst index 347dd03c..38fb6786 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -12,18 +12,18 @@ Compatibility This package is compatible with the following standards: -- :rfc:`5545` -- :rfc:`7529` - -We do not claim compatibility to: - -- :rfc:`2445` - which is obsoleted by :rfc:`5545` -- :rfc:`6886` -- :rfc:`7953` -- :rfc:`7986` -- :rfc:`9073` -- :rfc:`9074` -- :rfc:`9253` +- :rfc:`5545` - Internet Calendaring and Scheduling Core Object Specification (iCalendar) +- :rfc:`7529` - Non-Gregorian Recurrence Rules in the Internet Calendaring and Scheduling Core Object Specification (iCalendar) +- :rfc:`9074` - "VALARM" Extensions for iCalendar + +We do not claim compatibility to the following RFCs. They might work though. + +- :rfc:`2445` - obsoleted by :rfc:`5545` +- :rfc:`6868` - Parameter Value Encoding in iCalendar and vCard +- :rfc:`7953` - Calendar Availability +- :rfc:`7986` - New Properties for iCalendar +- :rfc:`9073` - Event Publishing Extensions to iCalendar +- :rfc:`9253` - Support for iCalendar Relationships File structure --------------