]> www.infradead.org Git - users/dwmw2/ews-sync.git/commitdiff
Handle all day events
authorDavid Woodhouse <dwmw2@infradead.org>
Mon, 19 Jul 2010 10:05:08 +0000 (11:05 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Mon, 19 Jul 2010 10:05:08 +0000 (11:05 +0100)
ews2ical.c

index a0739e884f7feb1b87002fe64ed0c39d5c766a1b..56ae8d2a52ec8445a4f4617578bde40b45bee475 100644 (file)
@@ -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...
+               <t:Start>2010-07-20T11:00:00Z</t:Start>
+               <t:End>2010-07-20T11:00:00Z</t:End>
+
+          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 <Recurrence> 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)