From 344069277e8d1ac2db32dac6c4984d5d8c752b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Mon, 19 Jul 2021 03:15:23 +0200 Subject: Fix bug where 'base' of event repeated through multiple VEVENT:s would be "lost". --- module/vcomponent/recurrence/generate.scm | 3 --- module/vcomponent/vdir/parse.scm | 40 +++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 13 deletions(-) (limited to 'module/vcomponent') diff --git a/module/vcomponent/recurrence/generate.scm b/module/vcomponent/recurrence/generate.scm index e304f2c1..3b0f7083 100644 --- a/module/vcomponent/recurrence/generate.scm +++ b/module/vcomponent/recurrence/generate.scm @@ -383,9 +383,6 @@ (rrule-instances base-event) stream-null)) - ;; NOTE Others have interpreted the standard to allow RECURRENCE-ID:s to - ;; create new instances. While I thought that you needed to specifie them - ;; through RDATE components. (define alternative-times (awhen (prop base-event '-X-HNH-ALTERNATIVES) (list (list->stream diff --git a/module/vcomponent/vdir/parse.scm b/module/vcomponent/vdir/parse.scm index ac9cb1aa..7b10af07 100644 --- a/module/vcomponent/vdir/parse.scm +++ b/module/vcomponent/vdir/parse.scm @@ -65,11 +65,24 @@ ;; two or more [else - - ;; Sorting on SEQUENCE here would have been nice. - ;; But the patches can apparently share a sequence number - ;; of 0 with the original event! - ;; (╯°□°)╯ ┻━┻ + ;; Sequence numbers on their own specifies revisions of a + ;; single compenent, incremented by a central authorative + ;; source. In that case simply picking the version with the + ;; highest SEQUENCE number would suffice. However, for + ;; recurring events where each instance is its own VEVENT + ;; they also signify something. + ;; TODO Neither version is handled here (or anywhere else). + + + ;; Multiple VEVENT objects can share a UID if they have + ;; different RECURRENCE-ID fields. This signifies that they + ;; are instances of the same event, similar to RDATE. + ;; Here we first check if we have a component which contains + ;; an RRULE or lacks a RECURRENCE-ID, and uses that as base. + ;; Otherwise we just take the first component as base. + ;; + ;; All alternatives (and the base) is added the the -X-HNH-ALTERNATIVES + ;; property of the base object, to be extracted where needed. (let* ((head (or (find (extract 'RRULE) events) (find (negate (extract 'RECURRENCE-ID)) events) (car events))) @@ -78,11 +91,18 @@ (set! (prop head '-X-HNH-ALTERNATIVES) (alist->hash-table (map cons - (map (extract 'RECURRENCE-ID) rest) - rest)) - #; - (sort*! rest ;; HERE - date/-time< (extract 'RECURRENCE-ID))) + ;; head is added back to the collection to simplify + ;; generation of recurrences. The recurrence + ;; generation assumes that the base event either + ;; contains an RRULE property, OR is in the + ;; -X-HNH-ALTERNATIVES set. This might produce + ;; duplicates, since the base event might also + ;; get included through an RRULE. This however + ;; is almost a non-problem, since RDATES and RRULES + ;; can already produce duplicates, meaning that + ;; we need to filter duplicates either way. + (map (extract 'RECURRENCE-ID) (cons head rest)) + (cons head rest)))) (add-child! calendar head))]) ;; return -- cgit v1.2.3