Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/bitfireAT/ical4android.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRicki Hirner <hirner@bitfire.at>2022-03-23 19:02:31 +0300
committerRicki Hirner <hirner@bitfire.at>2022-03-23 19:43:01 +0300
commit6c2cb6dd380fe897ce42ca173180f8970f2eea26 (patch)
treebd389d28101b40519fef0e74b24dc1a203143923
parent9bca5faccdd7095f1ded5fcdb7bffd571584a34c (diff)
Create fake main event for exceptions of recurring events where the main event is missing
* fixes bitfireAT/icsx5#27 * fixes bitfireAT/davx5#58
-rw-r--r--src/main/java/at/bitfire/ical4android/AndroidEvent.kt8
-rw-r--r--src/main/java/at/bitfire/ical4android/Event.kt21
-rw-r--r--src/test/java/at/bitfire/ical4android/EventTest.kt15
-rw-r--r--src/test/resources/events/recurring-only-exception.ics11
4 files changed, 48 insertions, 7 deletions
diff --git a/src/main/java/at/bitfire/ical4android/AndroidEvent.kt b/src/main/java/at/bitfire/ical4android/AndroidEvent.kt
index 3005d30..a465c06 100644
--- a/src/main/java/at/bitfire/ical4android/AndroidEvent.kt
+++ b/src/main/java/at/bitfire/ical4android/AndroidEvent.kt
@@ -573,10 +573,10 @@ abstract class AndroidEvent(
(it checks for RRULE and aborts if no RRULE is found).
So I have chosen the method of inserting the exception event manually.
- It's also noteworthy that the link between the main event and the exception is not
- between ID and ORIGINAL_ID (as one could assume), but between _SYNC_ID and ORIGINAL_SYNC_ID.
- So, if you don't set _SYNC_ID in the master event and ORIGINAL_SYNC_ID in the exception,
- the exception will appear additionally (and not *instead* of the instance).
+ It's also noteworthy that linking the main event to the exception only works using _SYNC_ID
+ and ORIGINAL_SYNC_ID (and not ID and ORIGINAL_ID, as one could assume). So, if you don't
+ set _SYNC_ID in the main event and ORIGINAL_SYNC_ID in the exception, the exception will
+ appear additionally (and not *instead* of the instance).
*/
val recurrenceId = exception.recurrenceId
diff --git a/src/main/java/at/bitfire/ical4android/Event.kt b/src/main/java/at/bitfire/ical4android/Event.kt
index d96ac73..fcbb67f 100644
--- a/src/main/java/at/bitfire/ical4android/Event.kt
+++ b/src/main/java/at/bitfire/ical4android/Event.kt
@@ -94,7 +94,6 @@ class Event: ICalendar() {
Ical4Android.log.fine("Assigning exceptions to main events")
val mainEvents = mutableMapOf<String /* UID */,VEvent>()
val exceptions = mutableMapOf<String /* UID */,MutableMap<String /* RECURRENCE-ID */,VEvent>>()
-
for (vEvent in vEvents) {
val uid = vEvent.uid.value
val sequence = vEvent.sequence?.sequenceNo ?: 0
@@ -124,11 +123,17 @@ class Event: ICalendar() {
}
}
+ /* There may be UIDs which have only RECURRENCE-ID entries and not a main entry (for instance, a recurring
+ event with an exception where the current user has been invited only to this exception. In this case,
+ the UID will not appear in mainEvents but only in exceptions. */
+
val events = mutableListOf<Event>()
for ((uid, vEvent) in mainEvents) {
val event = fromVEvent(vEvent)
- exceptions[uid]?.let { eventExceptions ->
- event.exceptions.addAll(eventExceptions.map { (_,it) -> fromVEvent(it) })
+
+ // assign exceptions to main event and then remove them from exceptions array
+ exceptions.remove(uid)?.let { eventExceptions ->
+ event.exceptions.addAll(eventExceptions.values.map { fromVEvent(it) })
}
// make sure that exceptions have at least a SUMMARY
@@ -137,6 +142,16 @@ class Event: ICalendar() {
events += event
}
+ for ((uid, onlyExceptions) in exceptions) {
+ Ical4Android.log.info("UID $uid doesn't have a main event but only exceptions: $onlyExceptions")
+
+ // create a fake main event from the first exception
+ val fakeEvent = fromVEvent(onlyExceptions.values.first())
+ fakeEvent.exceptions.addAll(onlyExceptions.values.map { fromVEvent(it) })
+
+ events += fakeEvent
+ }
+
return events
}
diff --git a/src/test/java/at/bitfire/ical4android/EventTest.kt b/src/test/java/at/bitfire/ical4android/EventTest.kt
index e4d25c8..6842974 100644
--- a/src/test/java/at/bitfire/ical4android/EventTest.kt
+++ b/src/test/java/at/bitfire/ical4android/EventTest.kt
@@ -158,6 +158,21 @@ class EventTest {
}
@Test
+ fun testRecurringOnlyException() {
+ val event = parseCalendar("recurring-only-exception.ics").first()
+
+ assertEquals(1, event.exceptions.size)
+ val exception = event.exceptions.first
+ assertEquals("20150503T010203Z", exception.recurrenceId!!.value)
+ assertEquals("This is an exception", exception.summary)
+
+ // fake main event
+ assertEquals(event.summary, exception.summary)
+ assertEquals(event.dtStart, exception.dtStart)
+ assertEquals(event.dtEnd, exception.dtEnd)
+ }
+
+ @Test
fun testStartEndTimes() {
// event with start+end date-time
val eViennaEvolution = parseCalendar("vienna-evolution.ics").first()
diff --git a/src/test/resources/events/recurring-only-exception.ics b/src/test/resources/events/recurring-only-exception.ics
new file mode 100644
index 0000000..26012e1
--- /dev/null
+++ b/src/test/resources/events/recurring-only-exception.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+UID:fcb42e4d-bc6e-4499-97f0-6616a02da7bc
+RECURRENCE-ID:20150503T010203Z
+DTSTART:20150503T010203Z
+DTEND:20150504T010203Z
+SUMMARY:This is an exception
+DESCRIPTION:The main event is not visible for us.
+END:VEVENT
+END:VCALENDAR