* Look for busy time in a VEVENT and add it to the supplied VFREEBUSY.
*
* fb The VFREEBUSY component to which we are appending
- * top_level_cal The top-level VCALENDAR component which contains VEVENT to be added
- * cal Caller supplies NULL, but we then use this variable for recursion
+ * top_level_cal The top-level VCALENDAR component which contains a VEVENT to be added
*/
-void ical_add_to_freebusy(icalcomponent *fb, icalcomponent *top_level_cal, icalcomponent *cal) {
+void ical_add_to_freebusy(icalcomponent *fb, icalcomponent *top_level_cal) {
+ icalcomponent *cal;
icalproperty *p;
icalvalue *v;
- struct icalperiodtype this_event_period;
-
- if (!top_level_cal) return;
- if (!cal) cal = top_level_cal;
+ struct icalperiodtype this_event_period = icalperiodtype_null_period();
+ icaltimetype dtstart = icaltime_null_time();
+ icaltimetype dtend = icaltime_null_time();
- this_event_period = icalperiodtype_null_period();
+ /* recur variables */
+ icalproperty *rrule = NULL;
+ struct icalrecurrencetype recur;
+ icalrecur_iterator *ritr = NULL;
+ struct icaldurationtype dur;
+ int num_recur = 0;
- /* Convert all time zones to UTC (FIXME this won't work with recurring events) */
- if (icalcomponent_isa(cal) != ICAL_VCALENDAR_COMPONENT) {
- ical_dezonify(cal);
- }
+ if (!top_level_cal) return;
- /* Now boil it down to the VEVENT only (FIXME this won't work with recurring events) */
- if (icalcomponent_isa(cal) != ICAL_VEVENT_COMPONENT) {
- ical_add_to_freebusy(fb, top_level_cal,
- icalcomponent_get_first_component(
- cal, ICAL_VEVENT_COMPONENT
- )
- );
- return;
- }
+ /* Find the VEVENT component containing an event */
+ cal = icalcomponent_get_first_component(top_level_cal, ICAL_VEVENT_COMPONENT);
+ if (!cal) return;
/* If this event is not opaque, the user isn't publishing it as
* busy time, so don't bother doing anything else.
}
}
- /* Convert the DTSTART and DTEND properties to an icalperiod. */
- p = icalcomponent_get_first_property(cal, ICAL_DTSTART_PROPERTY);
- if (p != NULL) {
- this_event_period.start = icalproperty_get_dtstart(p);
+ /*
+ * Now begin calculating the event start and end times.
+ */
+ dtstart = icalcomponent_get_dtstart(cal);
+ if (icaltime_is_null_time(dtstart)) return;
+
+ dtend = icalcomponent_get_dtend(cal);
+ if (!icaltime_is_null_time(dtend)) {
+ dur = icaltime_subtract(dtend, dtstart);
}
- p = icalcomponent_get_first_property(cal, ICAL_DTEND_PROPERTY);
- if (p != NULL) {
- this_event_period.end = icalproperty_get_dtstart(p);
+ /* Is a recurrence specified? If so, get ready to process it... */
+ rrule = ical_ctdl_get_subprop(cal, ICAL_RRULE_PROPERTY);
+ if (rrule) {
+ recur = icalproperty_get_rrule(rrule);
+ ritr = icalrecur_iterator_new(recur, dtstart);
}
- /* Now add it. */
- icalcomponent_add_property(fb,
- icalproperty_new_freebusy(this_event_period)
- );
+ do {
- /* Make sure the DTSTART property of the freebusy *list* is set to
- * the DTSTART property of the *earliest event*.
- */
- p = icalcomponent_get_first_property(fb, ICAL_DTSTART_PROPERTY);
- if (p == NULL) {
- icalcomponent_set_dtstart(fb,
- icalcomponent_get_dtstart(cal) );
- }
- else {
- if (icaltime_compare(
- icalcomponent_get_dtstart(cal),
- icalcomponent_get_dtstart(fb)
- ) < 0) {
- icalcomponent_set_dtstart(fb,
- icalcomponent_get_dtstart(cal) );
+
+ // FIXME add timezone conversion, we are currently outputting floating times
+
+
+
+ /* Convert the DTSTART and DTEND properties to an icalperiod. */
+ this_event_period.start = dtstart;
+
+ if (!icaltime_is_null_time(dtend)) {
+ this_event_period.end = dtend;
}
- }
+
+ /* Now add it. */
+ icalcomponent_add_property(fb, icalproperty_new_freebusy(this_event_period));
- /* Make sure the DTEND property of the freebusy *list* is set to
- * the DTEND property of the *latest event*.
- */
- p = icalcomponent_get_first_property(fb, ICAL_DTEND_PROPERTY);
- if (p == NULL) {
- icalcomponent_set_dtend(fb,
- icalcomponent_get_dtend(cal) );
- }
- else {
- if (icaltime_compare(
- icalcomponent_get_dtend(cal),
- icalcomponent_get_dtend(fb)
- ) > 0) {
- icalcomponent_set_dtend(fb,
- icalcomponent_get_dtend(cal) );
+ /* Make sure the DTSTART property of the freebusy *list* is set to
+ * the DTSTART property of the *earliest event*.
+ */
+ p = icalcomponent_get_first_property(fb, ICAL_DTSTART_PROPERTY);
+ if (p == NULL) {
+ icalcomponent_set_dtstart(fb, dtstart);
+ }
+ else {
+ if (icaltime_compare(dtstart, icalcomponent_get_dtstart(fb)) < 0) {
+ icalcomponent_set_dtstart(fb, dtstart);
+ }
+ }
+
+ /* Make sure the DTEND property of the freebusy *list* is set to
+ * the DTEND property of the *latest event*.
+ */
+ p = icalcomponent_get_first_property(fb, ICAL_DTEND_PROPERTY);
+ if (p == NULL) {
+ icalcomponent_set_dtend(fb, dtend);
+ }
+ else {
+ if (icaltime_compare(dtend, icalcomponent_get_dtend(fb)) > 0) {
+ icalcomponent_set_dtend(fb, dtend);
+ }
}
- }
+ if (rrule) {
+ dtstart = icalrecur_iterator_next(ritr);
+ if (!icaltime_is_null_time(dtend)) {
+ dtend = icaltime_add(dtstart, dur);
+ }
+ ++num_recur;
+ }
+
+ } while ( (rrule) && (!icaltime_is_null_time(dtstart)) && (num_recur < MAX_RECUR) ) ;
+ icalrecur_iterator_free(ritr);
}
CtdlFreeMessage(msg);
if (ird.cal) {
- ical_add_to_freebusy(fb, ird.cal, NULL); /* Add VEVENT times to VFREEBUSY */
+ ical_add_to_freebusy(fb, ird.cal); /* Add VEVENT times to VFREEBUSY */
icalcomponent_free(ird.cal);
}
}
serialized_request = icalcomponent_as_ical_string_r(encaps);
icalcomponent_free(encaps); /* Don't need this anymore. */
- cprintf("%d Here is the free/busy data:\n", LISTING_FOLLOWS);
+ cprintf("%d Free/busy for %s\n", LISTING_FOLLOWS, usbuf.fullname);
if (serialized_request != NULL) {
client_write(serialized_request, strlen(serialized_request));
free(serialized_request);
}
cprintf("%d Transmit data now\n", SEND_LISTING);
- calstream = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
+ calstream = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
if (calstream == NULL) {
return;
}