summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkrells <benoit.dereck-tricot@eyepea.eu>2017-09-28 09:56:14 +0200
committerSean Bright <sean.bright@gmail.com>2017-10-04 10:02:37 -0500
commit44d443d87e2363a82ad9433f8b5ebb19f65cb44d (patch)
tree82f821b65630a73ab0699ea0af9b72b256cafde6
parent752d55f7193c1f36ceabacbf2307eb4f84571762 (diff)
res_calendar_icalendar: Filter out occurrences superceded by another VEVENT
When we are loading the calendars, we call libical's icalcomponent_foreach_recurrence method for each VEVENT component that we have in our calendar. That method has no knowledge concerning the existence of the other VEVENT components and will feed our callback with all ocurrences matching the requested time span. The occurrences generated by icalcomponent_foreach_recurrence while expanding a recurring VEVENT's RRULE and RDATE properties can be superceded by an other VEVENT sharing the same UID. I use an external iterator (in libical terminology) to avoid messing with the internal ones from the calling function, and search for VEVENTS which could supersede the current occurrence. The event which can invalidate this occurence needs to have: - the same UID as our recurrent component (comp) - a RECURRENCE-ID property, which represents the start time of this occurrence If one component is found, just clean and return. ASTERISK-27296 #close Reported by: BenoƮt Dereck-Tricot Change-Id: I8587ae3eaa765af7cb21eda3b6bf84e8a1c87af8
-rw-r--r--res/res_calendar_icalendar.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/res/res_calendar_icalendar.c b/res/res_calendar_icalendar.c
index c465bf175..dd409f755 100644
--- a/res/res_calendar_icalendar.c
+++ b/res/res_calendar_icalendar.c
@@ -179,7 +179,7 @@ static time_t icalfloat_to_timet(icaltimetype time)
}
/* span->start & span->end may be dates or floating times which have no timezone,
- * which would mean that they should apply to the local timezone for all recepients.
+ * which would mean that they should apply to the local timezone for all recipients.
* For example, if a meeting was set for 1PM-2PM floating time, people in different time
* zones would not be scheduled at the same local times. Dates are often treated as
* floating times, so all day events will need to be converted--so we can trust the
@@ -251,7 +251,42 @@ static void icalendar_add_event(icalcomponent *comp, struct icaltime_span *span,
}
}
- /* Get the attendees */
+ /*
+ * If comp has an RRULE and/or RDATE property, we need to check whether
+ * another vevent component supercedes this span. Such a component would
+ * have two characteristics:
+ * - its UID is the same as comp
+ * - its RECURRENCE-ID property is the same time as span->start
+ */
+ if (icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY)
+ || icalcomponent_get_first_property(comp, ICAL_RDATE_PROPERTY)) {
+ icalcompiter comp_iter;
+ icaltimetype span_start = icaltime_from_timet_with_zone(
+ event->start, icaltime_is_date(start), icaltime_get_timezone(start));
+
+ icaltime_set_timezone(&span_start, icaltime_get_timezone(start));
+ for (comp_iter = icalcomponent_begin_component(pvt->data, ICAL_VEVENT_COMPONENT);
+ icalcompiter_deref(&comp_iter);
+ icalcompiter_next(&comp_iter)) {
+ icalcomponent *vevent = icalcompiter_deref(&comp_iter);
+ icalproperty *uid = icalcomponent_get_first_property(vevent, ICAL_UID_PROPERTY);
+
+ if (uid && !strcmp(icalproperty_get_value_as_string(uid), event->uid)) {
+ icaltimetype recurrence_id = icalcomponent_get_recurrenceid(vevent);
+
+ /* Set the same timezone that we want to compare against */
+ icaltime_set_timezone(&recurrence_id, icaltime_get_timezone(start));
+
+ if (!icaltime_compare(recurrence_id, span_start)
+ && icaltime_is_date(span_start) == icaltime_is_date(recurrence_id)) {
+ event = ast_calendar_unref_event(event);
+ return;
+ }
+ }
+ }
+ }
+
+ /* Get the attendees */
for (prop = icalcomponent_get_first_property(comp, ICAL_ATTENDEE_PROPERTY);
prop; prop = icalcomponent_get_next_property(comp, ICAL_ATTENDEE_PROPERTY)) {
struct ast_calendar_attendee *attendee;