]> www.infradead.org Git - users/dwmw2/ews-sync.git/commitdiff
Attempt to handle recursing to fetch modified subitems
authorDavid Woodhouse <dwmw2@infradead.org>
Thu, 22 Jul 2010 12:06:50 +0000 (13:06 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Thu, 22 Jul 2010 12:06:50 +0000 (13:06 +0100)
calitem_to_ical.c
ews2ical.c
ews_syncfolder.c
libews.h

index 7967e72bdd99d612ea38305544e4d80b7cb6250f..4b1028e93b6060c6dcd3e9e190aadd41e8de3cf0 100644 (file)
@@ -36,6 +36,7 @@ gboolean process_organizer(icalcomponent *comp, xmlNode *xml_node, GError **erro
 gboolean process_required_attendees(icalcomponent *comp, xmlNode *xml_node, GError **error);
 gboolean process_optional_attendees(icalcomponent *comp, xmlNode *xml_node, GError **error);
 gboolean process_time(icalcomponent *comp, xmlNode *xml_node, icaltimetype *ical_time, GError **error);
+gboolean process_orig_start(icalcomponent *comp, xmlNode *xml_node, icaltimezone *icaltz, GError **error);
 gboolean process_truefalse(icalcomponent *comp, xmlNode *xml_node, gboolean *val, GError **error);
 gboolean process_location(icalcomponent *comp, xmlNode *xml_node, GError **error);
 gboolean process_sequence(icalcomponent *comp, xmlNode *xml_node, GError **error);
@@ -44,17 +45,27 @@ gboolean process_subject(icalcomponent *comp, xmlNode *xml_node, GError **error)
 gboolean process_recurrence(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone, GError **error);
 gboolean process_deleted_occurrences(icalcomponent *comp, xmlNode *xml_node,
                                     icaltimetype **deletia, int *count, GError **error);
+gboolean process_modified_occurrences(icalcomponent *comp, xmlNode *xml_node,
+                                      const char ***modifia, int *count, GError **error);
 gboolean process_itemid(icalcomponent *comp, xmlNode *xmlnode, GError **error);
 gboolean process_reminder_mins(icalcomponent *comp, xmlNode *xmlnode, GError **error);
 icaltimezone *get_timezone(xmlNode *xmlnode, GError **error);
 icaltimezone *get_meeting_timezone(xmlNode *xml_node, GError **error);
 
 icalcomponent *ews_calitem_to_ical(xmlNode *xml_node, const gchar *parent_id,
-                                  icaltimezone *parent_zone, GError **error)
+                                  icaltimezone *parent_zone, 
+                                  icalcomponent *(fetch_subitem)(void *priv,
+                                                                 const gchar *item_id,
+                                                                 const gchar *parent_id,
+                                                                 icaltimezone *zone,
+                                                                 GError **error),
+                                  void *fetch_subitem_priv,
+                                  GError **error)
 {
        icaltimetype dtstart, dtend;
        icaltimetype *deletia = NULL;
-       int i, deletia_count = 0;
+       const char **modifia = NULL; 
+       int i, deletia_count = 0, modifia_count = 0;
        icaltimezone *icaltz;
        gboolean freetz = FALSE;
        icalcomponent *comp, *calcomp;
@@ -67,19 +78,27 @@ icalcomponent *ews_calitem_to_ical(xmlNode *xml_node, const gchar *parent_id,
        icalcomponent_set_method(calcomp, ICAL_METHOD_PUBLISH);
        prop = icalproperty_new_version("2.0");
        icalcomponent_add_property(calcomp, prop);
-       
-       icaltz = get_meeting_timezone(xml_node, error);
-       if (icaltz)
-               freetz = TRUE;
+
+       if (parent_zone)
+               icaltz = parent_zone;
        else {
-               icaltz = get_timezone(xml_node, error);
-               if (icaltz) {
-                       icalcomponent *comp = icaltimezone_get_component(icaltz);
-                       icalcomponent_add_component(calcomp, comp);
+               icaltz = get_meeting_timezone(xml_node, error);
+               if (icaltz)
+                       freetz = TRUE;
+               else {
+                       icaltz = get_timezone(xml_node, error);
+                       if (icaltz) {
+                               icalcomponent *comp = icaltimezone_get_component(icaltz);
+                               icalcomponent_add_component(calcomp, comp);
+                       }
                }
        }
+
        comp = icalcomponent_new(ICAL_VEVENT_COMPONENT);
 
+       if (parent_id)
+               icalcomponent_set_uid(comp, parent_id);
+
        for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
                if (xml_node->type != XML_ELEMENT_NODE)
                        continue;
@@ -113,8 +132,14 @@ icalcomponent *ews_calitem_to_ical(xmlNode *xml_node, const gchar *parent_id,
                } else if (!strcmp((char *)xml_node->name, "DeletedOccurrences")) {
                        if (!process_deleted_occurrences(comp, xml_node, &deletia, &deletia_count, error))
                                goto err;
+               } else if (!strcmp((char *)xml_node->name, "ModifiedOccurrences")) {
+                       if (!process_modified_occurrences(comp, xml_node, &modifia, &modifia_count, error))
+                               goto err;
+               } else if (!strcmp((char *)xml_node->name, "OriginalStart")) {
+                       if (!process_orig_start(comp, xml_node, icaltz, error))
+                               goto err;
                } else if (!strcmp((char *)xml_node->name, "ItemId")) {
-                       if (!process_itemid(comp, xml_node, error))
+                       if (!parent_id && !process_itemid(comp, xml_node, error))
                                goto err;
                } else if (!strcmp((char *)xml_node->name, "IsAllDayEvent")) {
                        if (!process_truefalse(comp, xml_node, &allday, error))
@@ -204,9 +229,24 @@ icalcomponent *ews_calitem_to_ical(xmlNode *xml_node, const gchar *parent_id,
                }
                free(deletia);
        }
+       icalcomponent_add_component(calcomp, comp);
+
+       if (modifia) {
+               const char *uid = icalcomponent_get_uid(comp);
+
+               for (i = 0; i < modifia_count; i++) {
+                       printf("Modified: %s\n", modifia[i]);
+                       if (fetch_subitem) {
+                               comp = fetch_subitem(fetch_subitem_priv, modifia[i], uid, icaltz, error);
+                               if (!comp)
+                                       goto err;
+                       }
+               }
+               free(modifia);
+       }
+
        if (freetz)
                icaltimezone_free(icaltz, 1);
-       icalcomponent_add_component(calcomp, comp);
        return calcomp;
 
  err:
@@ -353,6 +393,19 @@ gboolean process_time(icalcomponent *comp, xmlNode *xml_node, icaltimetype *ical
        return TRUE;
 }
 
+gboolean process_orig_start(icalcomponent *comp, xmlNode *xml_node, icaltimezone *icaltz, GError **error)
+{
+       icaltimetype t;
+
+       if (!process_time(comp, xml_node, &t, error))
+               return FALSE;
+
+       if (icaltz)
+               t = icaltime_convert_to_zone(t, icaltz);
+       icalcomponent_set_recurrenceid(comp, t);
+       return TRUE;
+}
+
 gboolean process_truefalse(icalcomponent *comp, xmlNode *xml_node, gboolean *val, GError **error)
 {
        char *truth = (char *)xmlNodeGetContent(xml_node);
@@ -531,6 +584,49 @@ gboolean process_deleted_occurrences(icalcomponent *comp, xmlNode *xml_node,
        return TRUE;
 }
 
+gboolean process_modified_occurrences(icalcomponent *comp, xmlNode *xml_node,
+                                     const char ***modifia_ret, int *count_ret, GError **error)
+{
+       const gchar **modifia = NULL, *this;
+       int count = 0;
+       xmlNode *xml_node2;
+
+       for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
+               if (xml_node->type != XML_ELEMENT_NODE)
+                       continue;
+               if (strcmp((char *)xml_node->name, "Occurrence")) {
+                       g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE,
+                                   "Unknown element %s in <ModifiedOccurrences>",
+                                   xml_node->name);
+                       return FALSE;
+               }
+               for (xml_node2 = xml_node->children; xml_node2; xml_node2 = xml_node2->next) {
+                       if (xml_node2->type == XML_ELEMENT_NODE &&
+                           !strcmp((char *)xml_node2->name, "ItemId"))
+                               break;
+               }
+               if (!xml_node2) {
+                       g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE,
+                                   "Modified <Occurrence> has no <ItemId>");
+                       return FALSE;
+               }
+               this = (char *)xmlGetProp(xml_node2, (xmlChar *)"Id");
+               if (!this) {
+                       g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE,
+                                   "Modified occurence <ItemId> has no Id= property");
+                       return FALSE;
+               }
+
+               count++;
+               modifia = realloc(modifia, sizeof(char *) * count);
+
+               modifia[count-1] = this;
+       }
+       *modifia_ret = modifia;
+       *count_ret = count;
+       return TRUE;
+}
+
 gboolean process_recurrence(icalcomponent *comp, xmlNode *xml_node, icaltimezone *zone, GError **error)
 {
        struct icalrecurrencetype ical_recur;
index ab5e13dc951c9a7f5fc4fae3f08235c70b33e232..ac72ee9459e59136ccd3d1c958e37f26fd698012 100644 (file)
@@ -129,7 +129,7 @@ int main(int argc, char **argv)
                return -1;
        }
 
-       calcomp = ews_calitem_to_ical(xml_node, NULL, NULL, &error);
+       calcomp = ews_calitem_to_ical(xml_node, NULL, NULL, NULL, NULL, &error);
 
        if (!calcomp) {
                fprintf(stderr, "Failed to convert: %s\n", error->message);
index 1bfa02b15d7da35978d49288ca0347dd10be5795..9e3462635f09173f88ccb138f49da5274b2a776d 100644 (file)
@@ -395,7 +395,7 @@ int fetch_xml_item(SoupSession *sess, char *url, const char *itemid,
                exit (1);
        }
 
-       calcomp = ews_calitem_to_ical(node, parent_id, parent_zone, &error);
+       calcomp = ews_calitem_to_ical(node, parent_id, parent_zone, NULL, NULL, &error);
        if (!calcomp) {
                printf("Failed to parse calendar: %s\n", error->message);
                g_clear_error(&error);
index d969ba9e3226c8bc63cb92797eee59a7d4e4a0c3..7b6ba7cc2861d33758fbe5ac566b3771966da4fb 100644 (file)
--- a/libews.h
+++ b/libews.h
 #include <glib/gerror.h>
 #include <glib/gquark.h>
 
-icalcomponent *ews_calitem_to_ical(xmlNode *xml_node, const char *parent_id,
-                                  icaltimezone *parent_zone, GError **error);
+icalcomponent *ews_calitem_to_ical(xmlNode *xml_node, const gchar *parent_id,
+                                  icaltimezone *parent_zone, 
+                                  icalcomponent *(fetch_subitem)(void *priv,
+                                                                 const gchar *item_id,
+                                                                 const gchar *parent_id,
+                                                                 icaltimezone *zone,
+                                                                 GError **error),
+                                  void *fetch_subitem_priv, GError **error);
 
 #define EWS_ERROR (ews_error_quark())