Add the iCalendar round-trip
Parsing goes through icalendar's low-level parser, which keeps properties in order and keeps repeated ones. Writing is ours: that crate's writer escapes a whole property value as text, so CATEGORIES:Work,Personal would go out as one category named "Work,Personal" to every other client. Anything the model does not interpret is carried rather than dropped -- X-MOZ-LASTACK, X-EVOLUTION-ALARM-UID, ACKNOWLEDGED, the X-MICROSOFT-CDO set, unrecognised ATTENDEE parameters, and whole VTODO/VJOURNAL components. A calendar has several clients writing to it and this one is not the authority on which properties matter. VTIMEZONE is modelled properly, and TZID is stored exactly as written: Exchange names its zones "Pacific Standard Time", which no IANA lookup resolves, and normalising at parse time would make the document unrepresentable. Mapping to a real zone belongs at the point of use. Tested against a golden corpus captured from the live Baikal (seven producing clients over five years) and a published Outlook feed, scrubbed of private content with the structure left byte-for-byte. Eight hand-written fixtures cover what neither server had: DURATION, floating times, RDATE, DST boundaries, leap day, and the full escape set. The contract is that parse -> write -> parse is stable, plus a check that no property name loses occurrences across the trip, since a parser that dropped ATTENDEE entirely would round-trip perfectly and still be wrong.
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:DAVx5/4.4.8-gplay ical4j/3.2.19 (com.digibites.calendar)
|
||||
BEGIN:VEVENT
|
||||
UID:eee51914-187b-40d5-342c-dc80c118438a
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:Check-in
|
||||
CLASS:PUBLIC
|
||||
TRANSP:OPAQUE
|
||||
DTSTART;VALUE=DATE:20250331
|
||||
DTEND;VALUE=DATE:20250401
|
||||
RRULE:FREQ=WEEKLY;BYDAY=MO
|
||||
CREATED:20250902T164854Z
|
||||
DTSTAMP:20250902T164854Z
|
||||
LAST-MODIFIED:20250902T164854Z
|
||||
SEQUENCE:2
|
||||
BEGIN:VALARM
|
||||
ACTION:DISPLAY
|
||||
DESCRIPTION:Retrospective demo retro
|
||||
TRIGGER:-PT4H
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,40 @@
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:DAVx5/4.5.19-gplay ical4j/4.3.0
|
||||
BEGIN:VEVENT
|
||||
DTSTAMP:20260811T142404Z
|
||||
UID:3a21fd46-26c4-85b5-eee3-6d2d2256f8ef
|
||||
SUMMARY:Briefing
|
||||
DTSTART;TZID=America/New_York:20260818T083000
|
||||
DTEND;TZID=America/New_York:20260818T093000
|
||||
RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU
|
||||
STATUS:CONFIRMED
|
||||
BEGIN:VALARM
|
||||
TRIGGER:-PT1H
|
||||
ACTION:DISPLAY
|
||||
DESCRIPTION:Design
|
||||
END:VALARM
|
||||
BEGIN:VALARM
|
||||
TRIGGER:-PT12H
|
||||
ACTION:DISPLAY
|
||||
DESCRIPTION:Design
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:America/New_York
|
||||
BEGIN:STANDARD
|
||||
TZNAME:EST
|
||||
TZOFFSETFROM:-0400
|
||||
TZOFFSETTO:-0500
|
||||
DTSTART:20071104T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:EDT
|
||||
TZOFFSETFROM:-0500
|
||||
TZOFFSETTO:-0400
|
||||
DTSTART:20070311T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,44 @@
|
||||
BEGIN:VCALENDAR
|
||||
CALSCALE:GREGORIAN
|
||||
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:America/Denver
|
||||
X-LIC-LOCATION:America/Denver
|
||||
BEGIN:DAYLIGHT
|
||||
TZNAME:MDT
|
||||
TZOFFSETFROM:-0700
|
||||
TZOFFSETTO:-0600
|
||||
DTSTART:20070311T020000
|
||||
RRULE:FREQ=YEARLY;UNTIL=20370308T090000Z;BYDAY=2SU;BYMONTH=3
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZNAME:MST
|
||||
TZOFFSETFROM:-0600
|
||||
TZOFFSETTO:-0700
|
||||
DTSTART:20071104T020000
|
||||
RRULE:FREQ=YEARLY;UNTIL=20361102T080000Z;BYDAY=1SU;BYMONTH=11
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20210128T161146Z
|
||||
LAST-MODIFIED:20211019T060028Z
|
||||
DTSTAMP:20210128T203012Z
|
||||
UID:c615f0a3-b567-cd71-7925-216aa5c3cc06
|
||||
SUMMARY:Handoff
|
||||
X-MOZ-LASTACK:20210128T203012Z
|
||||
DTSTART;TZID=America/Denver:20210128T133000
|
||||
DTEND;TZID=America/Denver:20210128T143000
|
||||
TRANSP:OPAQUE
|
||||
X-MOZ-GENERATION:2
|
||||
BEGIN:VALARM
|
||||
X-EVOLUTION-ALARM-UID:799e9f4195fcc29e5cc98f57eda3937d400a3543
|
||||
ACTION:DISPLAY
|
||||
DESCRIPTION:Check-in retro sync
|
||||
TRIGGER;RELATED=START:-PT15M
|
||||
ACKNOWLEDGED:20211019T060028Z
|
||||
X-LIC-ERROR;X-LIC-ERRORTYPE=PARAMETER-VALUE-PARSE-ERROR:Got a VALUE paramet
|
||||
er with an illegal type for property: VALUE=DURATION
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,54 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:America/Denver
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:-0700
|
||||
TZOFFSETTO:-0600
|
||||
TZNAME:MDT
|
||||
DTSTART:19700308T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:-0600
|
||||
TZOFFSETTO:-0700
|
||||
TZNAME:MST
|
||||
DTSTART:19701101T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
LAST-MODIFIED:20210928T163536Z
|
||||
DTSTAMP:20210928T163536Z
|
||||
UID:BC7787EBDF79D94DA9E1A90BFB6ECA7E9CD51D0402D0FAEEEC9CD42126A75F5DBC7787E
|
||||
BDF79D94DA9E1A90BFB6ECA7E9CD51D0402D0FAEE
|
||||
SUMMARY:Standup Design
|
||||
PRIORITY:5
|
||||
STATUS:CONFIRMED
|
||||
ORGANIZER;CN=Dana Okafor;SCHEDULE-AGENT=CLIENT:mailto:dana.okafor@example.o
|
||||
rg
|
||||
ATTENDEE;RSVP=TRUE;CN="Priya Raman";PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:
|
||||
mailto:priya.raman@example.org
|
||||
DTSTART;TZID=America/Denver:20210930T140000
|
||||
DTEND;TZID=America/Denver:20210930T143000
|
||||
DESCRIPTION;LANGUAGE=en-US:Quarterly handoff budget retrospective workshop
|
||||
kickoff kickoff demo\nJoin: https://example.org/meet/653ba53ffa43\n
|
||||
CLASS:PUBLIC
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:0
|
||||
LOCATION;LANGUAGE=en-US:Virtual
|
||||
X-MICROSOFT-CDO-APPT-SEQUENCE:0
|
||||
X-MICROSOFT-CDO-OWNERAPPTID:-566454299
|
||||
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
|
||||
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
|
||||
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
|
||||
X-MICROSOFT-CDO-IMPORTANCE:1
|
||||
X-MICROSOFT-CDO-INSTTYPE:0
|
||||
X-MICROSOFT-DONOTFORWARDMEETING:FALSE
|
||||
X-MICROSOFT-DISALLOW-COUNTER:FALSE
|
||||
X-MICROSOFT-LOCATIONS:[]
|
||||
X-MOZ-RECEIVED-SEQUENCE:0
|
||||
X-MOZ-RECEIVED-DTSTAMP:20210928T141728Z
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,21 @@
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//calendar-app//calendar-app//EN
|
||||
BEGIN:VEVENT
|
||||
UID:0097f029-5408-49be-e522-73f1e8e7ab35-1764105096
|
||||
DTSTAMP:20251125T211136Z
|
||||
DTSTART:20251203T200000Z
|
||||
DTEND:20251203T203000Z
|
||||
SUMMARY:Briefing
|
||||
DESCRIPTION:https://gov.teams.example.org/l/meetup-join/19%3agcch%3ameeting_bc0ea8b8a3984e5c81dc505caf2c54b0%40thread.v2/0?context=%7b%22Tid%22%3a%22f50f4fcc-38ea-4525-a42e-e89136a91fed%22%2c%22Oid%22%3a%22b755cbb7-d40e-4324-b018-503bb3bfe89d%22%7d
|
||||
STATUS:CONFIRMED
|
||||
CLASS:PUBLIC
|
||||
CREATED:20251125T211136
|
||||
LAST-MODIFIED:20251125T211136Z
|
||||
BEGIN:VALARM
|
||||
ACTION:DISPLAY
|
||||
TRIGGER:-PT120M
|
||||
DESCRIPTION:Check-in
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,49 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Zurich
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0200
|
||||
TZNAME:CEST
|
||||
DTSTART:19700329T020000
|
||||
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0100
|
||||
TZNAME:CET
|
||||
DTSTART:19701025T030000
|
||||
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20210520T192010Z
|
||||
LAST-MODIFIED:20210520T201659Z
|
||||
DTSTAMP:20210520T201659Z
|
||||
UID:4d11f4742abb8ae6e6ab54d8b3@google.com
|
||||
SUMMARY:Review Briefing
|
||||
STATUS:CONFIRMED
|
||||
ORGANIZER;CN=Jordan Vale;SCHEDULE-AGENT=CLIENT:mailto:jordan.vale@example.o
|
||||
rg
|
||||
ATTENDEE;RSVP=TRUE;CN=Jordan Vale;PARTSTAT=ACCEPTED;CUTYPE=INDIVIDUAL;ROLE=
|
||||
REQ-PARTICIPANT;X-NUM-GUESTS=0:mailto:jordan.vale@example.org
|
||||
ATTENDEE;RSVP=TRUE;CN=Priya Raman;PARTSTAT=NEEDS-ACTION;CUTYPE=INDIVIDUAL;R
|
||||
OLE=REQ-PARTICIPANT;X-NUM-GUESTS=0:mailto:priya.raman@example.org
|
||||
ATTENDEE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:priya.raman@example.
|
||||
org
|
||||
RRULE:FREQ=WEEKLY;COUNT=5;BYDAY=TU,TH
|
||||
DTSTART;TZID=Europe/Zurich:20210520T210000
|
||||
DTEND;TZID=Europe/Zurich:20210520T213000
|
||||
X-MICROSOFT-CDO-OWNERAPPTID:-786089143
|
||||
DESCRIPTION:Join: https://example.org/meet/75a54b52f57c\nJoin: https://exam
|
||||
ple.org/meet/e93ac4d1f299\nRetrospective retro onboarding design planning
|
||||
planning handoff roadmap design standup demo handoff
|
||||
LOCATION:Conference Room B
|
||||
SEQUENCE:0
|
||||
TRANSP:OPAQUE
|
||||
X-MOZ-RECEIVED-SEQUENCE:0
|
||||
X-MOZ-RECEIVED-DTSTAMP:20210520T192011Z
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
@@ -0,0 +1,137 @@
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:America/Denver
|
||||
X-TZINFO:America/Denver[2023c]
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETTO:-070000
|
||||
TZOFFSETFROM:-065956
|
||||
TZNAME:America/Denver(STD)
|
||||
DTSTART:18831118T120004
|
||||
RDATE:18831118T120004
|
||||
END:STANDARD
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETTO:-070000
|
||||
TZOFFSETFROM:-060000
|
||||
TZNAME:America/Denver(STD)
|
||||
DTSTART:19181027T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19201031T020000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:America/Denver(DST)
|
||||
DTSTART:19180331T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19210327T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETTO:-070000
|
||||
TZOFFSETFROM:-060000
|
||||
TZNAME:America/Denver(STD)
|
||||
DTSTART:19210522T020000
|
||||
RDATE:19210522T020000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:America/Denver(DST)
|
||||
DTSTART:19420209T020000
|
||||
RDATE:19420209T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETTO:-070000
|
||||
TZOFFSETFROM:-060000
|
||||
TZNAME:America/Denver(STD)
|
||||
DTSTART:19450930T020000
|
||||
RDATE:19450930T020000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:America/Denver(DST)
|
||||
DTSTART:19650425T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1SU;UNTIL=19730429T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:America/Denver(DST)
|
||||
DTSTART:19740106T020000
|
||||
RDATE:19740106T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:America/Denver(DST)
|
||||
DTSTART:19750223T020000
|
||||
RDATE:19750223T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:America/Denver(DST)
|
||||
DTSTART:19760425T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1SU;UNTIL=19860427T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:America/Denver(DST)
|
||||
DTSTART:19870405T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU;UNTIL=20060402T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETTO:-070000
|
||||
TZOFFSETFROM:-060000
|
||||
TZNAME:America/Denver(STD)
|
||||
DTSTART:19651031T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=20061029T020000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:America/Denver(DST)
|
||||
DTSTART:20070311T020000
|
||||
RDATE:20070311T020000
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETTO:-070000
|
||||
TZOFFSETFROM:-060000
|
||||
TZNAME:America/Denver(STD)
|
||||
DTSTART:20071104T020000
|
||||
RDATE:20071104T020000
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETTO:-060000
|
||||
TZOFFSETFROM:-070000
|
||||
TZNAME:(DST)
|
||||
DTSTART:20080309T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETTO:-070000
|
||||
TZOFFSETFROM:-060000
|
||||
TZNAME:(STD)
|
||||
DTSTART:20081102T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
CREATED:20230901T204357Z
|
||||
LAST-MODIFIED:20230901T204400Z
|
||||
DTSTAMP:20230901T204400Z
|
||||
UID:c9525154-42b2-3c07-b11f-46760a4dab35
|
||||
SUMMARY:Check-in Budget
|
||||
STATUS:CONFIRMED
|
||||
X-MOZ-LASTACK:20230901T204400Z
|
||||
DTSTART;TZID=America/Denver:20230831T180000
|
||||
DTEND;TZID=America/Denver:20230831T190000
|
||||
X-MOZ-GENERATION:1
|
||||
BEGIN:VALARM
|
||||
ACTION:DISPLAY
|
||||
TRIGGER:-PT2H
|
||||
DESCRIPTION:Retrospective
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
Reference in New Issue
Block a user