[evolution-ews] Passing and storing attachment ids when performing GetAttachment operation



commit 0f09652d9fc922a3436bf6d33de311a281ea99ad
Author: Or Goshen <orx goshen intel com>
Date:   Tue Jul 19 15:26:29 2011 +0300

    Passing and storing attachment ids when performing GetAttachment operation

 src/calendar/e-cal-backend-ews.c |   50 +++++++++++++++++++++++++++++++-------
 src/server/e-ews-connection.c    |   25 ++++++++++--------
 src/server/e-ews-connection.h    |    4 +-
 src/server/e-ews-item.c          |   38 ++++++++++++++++++++++------
 src/server/e-ews-item.h          |    3 +-
 5 files changed, 89 insertions(+), 31 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index f0380bc..88a8ad1 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -1179,6 +1179,12 @@ e_cal_backend_ews_remove_object (ECalBackend *backend, EDataCal *cal, EServerMet
 typedef struct {
 	ECalBackendEws *cbews;
 	ECalComponent *comp;
+
+	int cb_type; /* 0 - nothing, 1 - create, 2 - update */
+
+	EDataCal *cal;
+	EServerMethodContext context;
+
 } EwsAttachmentsData;
 
 static void
@@ -1193,6 +1199,7 @@ ews_create_attachments_cb(GObject *object, GAsyncResult *res, gpointer user_data
 	icalproperty *icalprop;
 	icalcomponent *icalcomp;
 	icalparameter *icalparam;
+	const gchar *comp_uid;
 
 	ids = e_ews_connection_create_attachments_finish (cnc, &change_key, res, &error);
 
@@ -1226,15 +1233,20 @@ ews_create_attachments_cb(GObject *object, GAsyncResult *res, gpointer user_data
 		icalparam = icalparameter_new_x (i->data);
 		icalparameter_set_xname (icalparam, "X-EWS-ATTACHMENTID");
 		icalproperty_add_parameter (icalprop, icalparam);
-
 		g_free (i->data);
 	}
 
 	e_cal_component_commit_sequence (create_data->comp);
-
 	/* update changes and release access to the store */
 	e_cal_backend_store_thaw_changes (priv->store);
 
+	e_cal_component_get_uid(create_data->comp, &comp_uid);
+	if (create_data->cb_type == 1) {
+		e_data_cal_notify_object_created (create_data->cal, create_data->context, error, comp_uid, e_cal_component_get_as_string(create_data->comp));
+	} else if (create_data->cb_type == 2) {
+
+	}
+
 	g_slist_free (ids);
 
 	g_object_unref (create_data->cbews);
@@ -1308,6 +1320,7 @@ ews_create_object_cb(GObject *object, GAsyncResult *res, gpointer user_data)
 	const EwsId *item_id;
 	icalproperty *icalprop;
 	icalcomponent *icalcomp;
+	guint n_attach;
 
 	/* get a list of ids from server (single item) */
 	e_ews_connection_create_items_finish(cnc, res, &ids, &error);
@@ -1321,12 +1334,19 @@ ews_create_object_cb(GObject *object, GAsyncResult *res, gpointer user_data)
 	item_id = e_ews_item_get_id((EEwsItem *)ids->data);
 	g_slist_free (ids);
 
+	/* set item id */
+	e_cal_component_set_uid(create_data->comp, item_id->id);
+
 	/* attachments */
-	if (e_cal_component_get_num_attachments (create_data->comp) > 0) {
+	n_attach = e_cal_component_get_num_attachments (create_data->comp);
+	if (n_attach > 0) {
 		EwsAttachmentsData *attach_data = g_new0(EwsAttachmentsData, 1);
 
 		attach_data->cbews = g_object_ref (create_data->cbews);
 		attach_data->comp = g_object_ref (create_data->comp);
+		attach_data->cal = create_data->cal;
+		attach_data->context = create_data->context;
+		attach_data->cb_type = 1;
 
 		e_cal_component_get_attachment_list (create_data->comp, &attachments);
 		e_ews_connection_create_attachments_start (cnc, EWS_PRIORITY_MEDIUM,
@@ -1340,9 +1360,6 @@ ews_create_object_cb(GObject *object, GAsyncResult *res, gpointer user_data)
 	/* get exclusive access to the store */
 	e_cal_backend_store_freeze_changes(priv->store);
 
-	/* set item id */
-	e_cal_component_set_uid(create_data->comp, item_id->id);
-
 	/* set a new ical property containing the change key we got from the exchange server for future use */
 	icalprop = icalproperty_new_x (item_id->change_key);
 	icalproperty_set_x_name (icalprop, "X-EVOLUTION-CHANGEKEY");
@@ -1356,7 +1373,9 @@ ews_create_object_cb(GObject *object, GAsyncResult *res, gpointer user_data)
 	/* notify the backend and the application that a new object was created */
 	e_cal_backend_notify_object_created (E_CAL_BACKEND(create_data->cbews), create_data->context);
 	e_cal_component_get_uid(create_data->comp, &comp_uid);
-	e_data_cal_notify_object_created (create_data->cal, create_data->context, error, comp_uid, e_cal_component_get_as_string(create_data->comp));
+	
+	if (n_attach == 0)
+		e_data_cal_notify_object_created (create_data->cal, create_data->context, error, comp_uid, e_cal_component_get_as_string(create_data->comp));
 
 	/* place new component in our cache */
 	PRIV_LOCK (priv);
@@ -2381,13 +2400,16 @@ ews_get_attachments_ready_callback (GObject *object, GAsyncResult *res, gpointer
 	EEwsConnection *cnc = E_EWS_CONNECTION (object);
 	EwsAttachmentData *att_data = user_data;
 	GError *error = NULL;
-	GSList *uris = NULL;
+	GSList *uris = NULL, *ids, *i;
 	ECalComponentId *id;
 	ECalBackendEws *cbews;
 	gchar *comp_str, *itemid;
 	ECalComponent *comp_att, *cache_comp = NULL;
+	icalcomponent *icalcomp;
+	icalproperty *icalprop;
+	icalparameter *icalparam;
 
-	e_ews_connection_get_attachments_finish	(cnc, res, &uris, &error);
+	ids = e_ews_connection_get_attachments_finish	(cnc, res, &uris, &error);
 
 	if (error != NULL) {
 		error->code = OtherError;
@@ -2400,6 +2422,16 @@ ews_get_attachments_ready_callback (GObject *object, GAsyncResult *res, gpointer
 
 	e_cal_component_set_attachment_list (comp_att, uris);
 
+	icalcomp = e_cal_component_get_icalcomponent (comp_att);
+	icalprop = icalcomponent_get_first_property (icalcomp, ICAL_ATTACH_PROPERTY);
+	i = ids;
+	for (; i && icalprop; i = i->next, icalprop = icalcomponent_get_next_property (icalcomp, ICAL_ATTACH_PROPERTY)) {
+		icalparam = icalparameter_new_x (i->data);
+		icalparameter_set_xname (icalparam, "X-EWS-ATTACHMENTID");
+		icalproperty_add_parameter (icalprop, icalparam);
+		g_free (i->data);
+	}
+
 	id = e_cal_component_get_id (comp_att);
 	cache_comp = e_cal_backend_store_get_component (cbews->priv->store, id->uid, id->rid);
 	e_cal_component_free_id (id);
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 55567e0..60a20cc 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -3749,7 +3749,7 @@ e_ews_connection_get_attachments_start	(EEwsConnection *cnc,
 				      cancellable, simple, cb == ews_sync_reply_cb);
 }
 
-gboolean
+GSList *
 e_ews_connection_get_attachments_finish(EEwsConnection *cnc,
 					 GAsyncResult *result,
 					 GSList **items,
@@ -3761,20 +3761,20 @@ e_ews_connection_get_attachments_finish(EEwsConnection *cnc,
 	g_return_val_if_fail (
 			g_simple_async_result_is_valid (
 					result, G_OBJECT (cnc), e_ews_connection_get_attachments_start),
-			FALSE);
+			NULL);
 
 	simple = G_SIMPLE_ASYNC_RESULT (result);
 	async_data = g_simple_async_result_get_op_res_gpointer (simple);
 
 	if (g_simple_async_result_propagate_error (simple, error))
-		return FALSE;
+		return NULL;
 
 	*items = async_data->items;
 
-	return TRUE;
+	return async_data->items_created;
 }
 
-gboolean
+GSList *
 e_ews_connection_get_attachments(EEwsConnection *cnc,
 				 gint pri,
 				 GSList *ids,
@@ -3787,7 +3787,7 @@ e_ews_connection_get_attachments(EEwsConnection *cnc,
 				 GError **error)
 {
 	EwsSyncData *sync_data;
-	gboolean result;
+	GSList *attachments_ids;
 
 	sync_data = g_new0 (EwsSyncData, 1);
 	sync_data->eflag = e_flag_new ();
@@ -3800,7 +3800,7 @@ e_ews_connection_get_attachments(EEwsConnection *cnc,
 
 	e_flag_wait (sync_data->eflag);
 
-	result = e_ews_connection_get_attachments_finish(cnc,
+	attachments_ids = e_ews_connection_get_attachments_finish(cnc,
 						    sync_data->res,
 						    items,
 						    error);
@@ -3809,7 +3809,7 @@ e_ews_connection_get_attachments(EEwsConnection *cnc,
 	g_object_unref (sync_data->res);
 	g_free (sync_data);
 
-	return result;
+	return attachments_ids;
 }
 
 static void
@@ -3817,7 +3817,7 @@ get_attachments_response_cb (ESoapParameter *param, EwsNode *enode)
 {
 	ESoapParameter *subparam, *attspara;
 	EwsAsyncData *async_data;
-	gchar *uri = NULL;
+	gchar *uri = NULL, *attach_id = NULL;
 	EEwsItem *item;
 	const gchar *name;
 
@@ -3830,15 +3830,18 @@ get_attachments_response_cb (ESoapParameter *param, EwsNode *enode)
 
 		if (!g_ascii_strcasecmp (name, "ItemAttachment")) {
 			item = e_ews_item_new_from_soap_parameter(subparam);
+			attach_id = g_strdup (e_ews_item_get_attachment_id (item)->id);
 			uri = e_ews_item_dump_mime_content(item, async_data->directory);
 
 		}
 		else if (!g_ascii_strcasecmp (name, "FileAttachment")) {
-			uri = e_ews_dump_file_attachment_from_soap_parameter(subparam, async_data->directory);
+			uri = e_ews_dump_file_attachment_from_soap_parameter(subparam, async_data->directory, &attach_id);
 		}
-		if (uri) {
+		if (uri && attach_id) {
 			async_data->items = g_slist_append (async_data->items, uri);
+			async_data->items_created = g_slist_append (async_data->items_created, attach_id);
 			uri = NULL;
+			attach_id = NULL;
 		}
 	}
 }
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index 5e78ca8..41d5b52 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -561,13 +561,13 @@ void		e_ews_connection_get_attachments_start
 						 GCancellable *cancellable,
 						 gpointer user_data);
 
-gboolean	e_ews_connection_get_attachments_finish
+GSList *	e_ews_connection_get_attachments_finish
 						(EEwsConnection *cnc,
 						 GAsyncResult *result,
 						 GSList **items,
 						 GError **error);
 
-gboolean	e_ews_connection_get_attachments
+GSList *	e_ews_connection_get_attachments
 						(EEwsConnection *cnc,
 						 gint pri,
 						 GSList *ids,
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index aa13a24..35be38c 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -139,6 +139,7 @@ struct _EEwsTaskFields {
 };
 
 struct _EEwsItemPrivate {
+	EwsId *attachment_id;
 	EEwsItemType item_type;
 
 	/* MAPI properties */
@@ -220,6 +221,13 @@ e_ews_item_dispose (GObject *object)
 		priv->item_id = NULL;
 	}
 
+	if (priv->attachment_id) {
+		g_free (priv->attachment_id->id);
+		g_free (priv->attachment_id->change_key);
+		g_free (priv->attachment_id);
+		priv->attachment_id = NULL;
+	}
+
 	g_free (priv->mime_content);
 
 	g_free (priv->subject);
@@ -847,7 +855,11 @@ e_ews_item_set_from_soap_parameter (EEwsItem *item, ESoapParameter *param)
 
 	g_return_val_if_fail (param != NULL, FALSE);
 
-	if ((node = e_soap_parameter_get_first_child_by_name (param, "Message")))
+	if ((node = e_soap_parameter_get_first_child_by_name (param, "AttachmentId"))) {
+		priv->attachment_id = g_new0 (EwsId, 1);
+		priv->attachment_id->id = e_soap_parameter_get_property (node, "Id");
+		priv->attachment_id->change_key = e_soap_parameter_get_property (node, "ChangeKey");
+	} else if ((node = e_soap_parameter_get_first_child_by_name (param, "Message")))
 		priv->item_type = E_EWS_ITEM_TYPE_MESSAGE;
 	else if ((node = e_soap_parameter_get_first_child_by_name (param, "CalendarItem")))
 		priv->item_type = E_EWS_ITEM_TYPE_CALENDAR_ITEM;
@@ -1079,6 +1091,14 @@ e_ews_item_get_id	(EEwsItem *item)
 	return (const EwsId *) item->priv->item_id;
 }
 
+const EwsId *
+e_ews_item_get_attachment_id	(EEwsItem *item)
+{
+	g_return_val_if_fail (E_IS_EWS_ITEM (item), NULL);
+
+	return (const EwsId *) item->priv->attachment_id;
+}
+
 gsize
 e_ews_item_get_size	(EEwsItem *item)
 {
@@ -1305,11 +1325,11 @@ e_ews_embed_attachment_id_in_uri (const gchar *olduri, const char *attach_id)
 }
 
 gchar *
-e_ews_dump_file_attachment_from_soap_parameter (ESoapParameter *param, const gchar *cache)
+e_ews_dump_file_attachment_from_soap_parameter (ESoapParameter *param, const gchar *cache, gchar **attach_id)
 {
 	ESoapParameter *subparam;
 	const gchar *param_name;
-	gchar *name = NULL, *value, filename[350], dirname[350], *attach_id = NULL;
+	gchar *name = NULL, *value, filename[350], dirname[350];
 	guchar *content = NULL;
 	gsize data_len = 0;
 	gchar *tmpdir, *tmpfilename;
@@ -1317,6 +1337,7 @@ e_ews_dump_file_attachment_from_soap_parameter (ESoapParameter *param, const gch
 	g_return_val_if_fail (param != NULL, NULL);
 
 	/* Parse element, look for filename and content */
+	*attach_id = NULL;
 	for (subparam = e_soap_parameter_get_first_child(param); subparam != NULL; subparam = e_soap_parameter_get_next_child(subparam)) {
 		param_name = e_soap_parameter_get_name(subparam);
 
@@ -1330,23 +1351,23 @@ e_ews_dump_file_attachment_from_soap_parameter (ESoapParameter *param, const gch
 			g_free (value);
 		} else if (g_ascii_strcasecmp(param_name, "AttachmentId") == 0) {
 			value = e_soap_parameter_get_property (subparam, "Id");
-			attach_id = g_uri_escape_string(value, "", TRUE);
+			*attach_id = g_uri_escape_string(value, "", TRUE);
 			g_free (value);
 		}
 	}
 
 	/* Make sure we have needed data */
-	if (!content || !name || !attach_id) {
+	if (!content || !name || !*attach_id) {
 		g_free(name);
 		g_free(content);
-		g_free(attach_id);
+		g_free(*attach_id);
 		return NULL;
 	}
 
 	tmpfilename = (gchar *) content;
 	tmpdir = g_strndup(tmpfilename, g_strrstr (tmpfilename, "/") - tmpfilename);
 
-	snprintf (dirname, 350, "%s/%s", tmpdir, attach_id);
+	snprintf (dirname, 350, "%s/%s", tmpdir, *attach_id);
 	if (g_mkdir (dirname, 0775) == -1) {
 		g_warning("Failed create directory to place file in [%s]: %s\n", dirname, strerror (errno));
 	}
@@ -1359,7 +1380,6 @@ e_ews_dump_file_attachment_from_soap_parameter (ESoapParameter *param, const gch
 	g_free(tmpdir);
 	g_free(name);
 	g_free(content);
-	g_free(attach_id);
 
 	/* Return URI to saved file */
 	return g_filename_to_uri(filename, NULL, NULL);
@@ -1730,3 +1750,5 @@ e_ews_item_get_tzid (EEwsItem *item)
 
 	return item->priv->timezone;
 }
+
+
diff --git a/src/server/e-ews-item.h b/src/server/e-ews-item.h
index 3507408..c6be166 100644
--- a/src/server/e-ews-item.h
+++ b/src/server/e-ews-item.h
@@ -119,6 +119,7 @@ const gchar *	e_ews_item_get_mime_content	(EEwsItem *item);
 void		e_ews_item_set_mime_content	(EEwsItem *item,
 						 const gchar *new_mime_content);
 const EwsId *	e_ews_item_get_id		(EEwsItem *item);
+const EwsId *	e_ews_item_get_attachment_id		(EEwsItem *item);
 gsize		e_ews_item_get_size		(EEwsItem *item);
 const gchar *	e_ews_item_get_msg_id		(EEwsItem *item);
 const gchar *	e_ews_item_get_in_replyto	(EEwsItem *item);
@@ -155,7 +156,7 @@ gchar *		e_ews_embed_attachment_id_in_uri (const gchar *olduri, const char *atta
 GSList *	e_ews_item_get_attachments_ids
 						(EEwsItem *item);
 gchar *
-e_ews_dump_file_attachment_from_soap_parameter (ESoapParameter *param, const gchar *cache);
+e_ews_dump_file_attachment_from_soap_parameter (ESoapParameter *param, const gchar *cache, gchar **attach_id);
 
 gchar *
 e_ews_item_ical_dump(EEwsItem *item);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]