From: David Woodhouse Date: Thu, 22 Jul 2010 12:06:50 +0000 (+0100) Subject: Attempt to handle recursing to fetch modified subitems X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=6cd0aad26d309efe11f69df1adf613aacf4d2e4d;p=users%2Fdwmw2%2Fews-sync.git Attempt to handle recursing to fetch modified subitems --- diff --git a/calitem_to_ical.c b/calitem_to_ical.c index 7967e72..4b1028e 100644 --- a/calitem_to_ical.c +++ b/calitem_to_ical.c @@ -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 ", + 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 has no "); + return FALSE; + } + this = (char *)xmlGetProp(xml_node2, (xmlChar *)"Id"); + if (!this) { + g_set_error(error, EWS_ERROR, EWS_ERROR_PARSE, + "Modified occurence 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; diff --git a/ews2ical.c b/ews2ical.c index ab5e13d..ac72ee9 100644 --- a/ews2ical.c +++ b/ews2ical.c @@ -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); diff --git a/ews_syncfolder.c b/ews_syncfolder.c index 1bfa02b..9e34626 100644 --- a/ews_syncfolder.c +++ b/ews_syncfolder.c @@ -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); diff --git a/libews.h b/libews.h index d969ba9..7b6ba7c 100644 --- a/libews.h +++ b/libews.h @@ -26,8 +26,14 @@ #include #include -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())