From: David Woodhouse Date: Mon, 19 Jul 2010 10:05:08 +0000 (+0100) Subject: Handle all day events X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a100d1d119a25afb586c680596d60af28f320aa9;p=users%2Fdwmw2%2Fews-sync.git Handle all day events --- diff --git a/ews2ical.c b/ews2ical.c index a0739e8..56ae8d2 100644 --- a/ews2ical.c +++ b/ews2ical.c @@ -29,8 +29,8 @@ int process_dailyrecurrence(xmlNode *xml_node, struct icalrecurrencetype *ical_r int process_organizer(icalcomponent *comp, xmlNode *xml_node); int process_required_attendees(icalcomponent *comp, xmlNode *xml_node); int process_optional_attendees(icalcomponent *comp, xmlNode *xml_node); -int process_start(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone); -int process_end(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone); +int process_time(icalcomponent *comp, xmlNode *xml_node, icaltimetype *ical_time); +int process_truefalse(icalcomponent *comp, xmlNode *xml_node, gboolean *val); int process_location(icalcomponent *comp, xmlNode *xml_node); int process_body(icalcomponent *comp, xmlNode *xml_node); int process_subject(icalcomponent *comp, xmlNode *xml_node); @@ -155,10 +155,14 @@ int main(int argc, char **argv) icalcomponent *ews_calitem_to_ical(xmlNode *xml_node) { + icaltimetype dtstart, dtend; icaltimezone *icaltz; icalcomponent *comp, *calcomp; icalproperty *prop; + gboolean allday = FALSE; + dtstart = dtend = icaltime_null_time(); + calcomp = icalcomponent_new_vcalendar(); icalcomponent_set_method(calcomp, ICAL_METHOD_PUBLISH); prop = icalproperty_new_version("2.0"); @@ -183,9 +187,9 @@ icalcomponent *ews_calitem_to_ical(xmlNode *xml_node) else if (!strcmp((char *)xml_node->name, "OptionalAttendees")) process_optional_attendees(comp, xml_node); else if (!strcmp((char *)xml_node->name, "Start")) - process_start(comp, xml_node, icaltz); + process_time(comp, xml_node, &dtstart); else if (!strcmp((char *)xml_node->name, "End")) - process_end(comp, xml_node, icaltz); + process_time(comp, xml_node, &dtend); else if (!strcmp((char *)xml_node->name, "Body")) process_body(comp, xml_node); else if (!strcmp((char *)xml_node->name, "Location")) @@ -196,6 +200,8 @@ icalcomponent *ews_calitem_to_ical(xmlNode *xml_node) process_recurrence(comp, xml_node, icaltz); else if (!strcmp((char *)xml_node->name, "ItemId")) process_itemid(comp, xml_node); + else if (!strcmp((char *)xml_node->name, "IsAllDayEvent")) + process_truefalse(comp, xml_node, &allday); else if (!strcmp((char *)xml_node->name, "ReminderMinutesBeforeStart")) process_reminder_mins(comp, xml_node); else if (!strcmp((char *)xml_node->name, "ParentFolderId") || @@ -228,6 +234,47 @@ icalcomponent *ews_calitem_to_ical(xmlNode *xml_node) fprintf(stderr, "Unhandled node type '%s'\n", xml_node->name); #endif } + + /* We don't handle really floating events -- which change their time + according to the time zone of the observer (like lunch at noon + under the sundial wherever you are in the world). But that's OK; + Exchange doesn't seem to either: + - AFAICT, you can't create them with Outlook. + - If you send Exchange an invitation with floating times, which + happens to have a VTIMEZONE, it'll assume that timezone (in + violation of RFC2445). + - If you send Exchange an invitation with floating times with + *no* stray VTIMEZONE in the file (which was a mistake), then + it creates an item with no timezone but does weird things -- + this invite: + DTSTART:20100720T120000 + DTEND:20100720T120010 + ... leads to an Exchange object saying... + 2010-07-20T11:00:00Z + 2010-07-20T11:00:00Z + + For any recurring object without time zones (including the last + test above, as well as all day events such as birthdays created + with Outlook/Exchange 2003, Exchange will refuse to return the + object if the field is requested, reporting + 'Corrupt Data'. + + Tested with Exchange 2007. + */ + if (icaltz && !allday) { + dtstart = icaltime_convert_to_zone(dtstart, icaltz); + dtend = icaltime_convert_to_zone(dtend, icaltz); + } + if (allday) { + dtstart.is_date = 1; + dtend.is_date = 1; + } + if (!icaltime_is_null_time(dtstart)) + icalcomponent_set_dtstart(comp, dtstart); + + if (!icaltime_is_null_time(dtend)) + icalcomponent_set_dtend(comp, dtend); + icalcomponent_add_component(calcomp, comp); return calcomp; } @@ -342,32 +389,32 @@ int process_optional_attendees(icalcomponent *comp, xmlNode *xml_node) return 0; } -int process_time(icalcomponent *comp, xmlNode *xml_node, int dtend, icaltimezone *zone) +int process_time(icalcomponent *comp, xmlNode *xml_node, icaltimetype *ical_time) { char *ews_time = (char *)xmlNodeGetContent(xml_node); - struct icaltimetype ical_time; if (!ews_time) return -1; - ical_time = icaltime_from_string(ews_time); - if (zone) - ical_time = icaltime_convert_to_zone(ical_time, zone); - - if (dtend) - icalcomponent_set_dtend(comp, ical_time); - else - icalcomponent_set_dtstart(comp, ical_time); + *ical_time = icaltime_from_string(ews_time); return 0; } -int process_start(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone) +int process_truefalse(icalcomponent *comp, xmlNode *xml_node, gboolean *val) { - return process_time(comp, xml_node, 0, zone); -} + char *truth = (char *)xmlNodeGetContent(xml_node); -int process_end(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone) -{ - return process_time(comp, xml_node, 1, zone); + if (!truth) + return -1; + if (!strcmp(truth, "true")) + *val = TRUE; + else if (!strcmp(truth, "false")) + *val = FALSE; + else { + fprintf(stderr, "Unrecognised truth value '%s' in %s node\n", + truth, xml_node->name); + return -1; + } + return 0; } int process_location (icalcomponent *comp, xmlNode *xml_node)