[evolution-ews] Bug #679305 - EX addresses not decoded in folder summary



commit f7e410d05edefb5fbceee854a409a7ae0eac1212
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jul 3 15:18:44 2012 +0200

    Bug #679305 - EX addresses not decoded in folder summary

 src/addressbook/e-book-backend-ews.c   |   25 +------
 src/calendar/e-cal-backend-ews.c       |   27 +++++--
 src/camel/camel-ews-folder.c           |    6 +-
 src/camel/camel-ews-utils.c            |   45 +++++++-----
 src/camel/camel-ews-utils.h            |    1 +
 src/server/e-ews-connection.c          |  126 ++++++++++++++++++++++++++++++++
 src/server/e-ews-connection.h          |    8 ++
 src/server/e-ews-item.c                |   64 +++++++++--------
 src/server/e-ews-item.h                |    1 +
 src/server/tests/test-autocompletion.c |    4 +-
 10 files changed, 224 insertions(+), 83 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index f49d3bb..251b749 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -2042,23 +2042,6 @@ ebews_get_vcards_list (GSList *new_items,
 }
 
 static void
-ews_mb_free (EwsMailbox *mb)
-{
-	if (mb) {
-		g_free (mb->name);
-		g_free (mb->email);
-
-		if (mb->item_id) {
-			g_free (mb->item_id->id);
-			g_free (mb->item_id->change_key);
-			g_free (mb->item_id);
-		}
-
-		g_free (mb);
-	}
-}
-
-static void
 ebews_store_distribution_list_items (EBookBackendEws *ebews,
                                      const EwsId *id,
                                      const gchar *d_name,
@@ -2098,7 +2081,7 @@ ebews_store_distribution_list_items (EBookBackendEws *ebews,
 			e_vcard_attribute_add_value (attr, mb->email);
 
 		e_vcard_add_attribute (E_VCARD (contact), attr);
-		ews_mb_free (mb);
+		e_ews_mailbox_free (mb);
 	}
 
 	g_slist_free (members);
@@ -2146,7 +2129,7 @@ ebews_vcards_append_dl (const EwsId *id,
 			e_vcard_attribute_add_value (attr, mb->email);
 
 		e_vcard_add_attribute (E_VCARD (contact), attr);
-		ews_mb_free (mb);
+		e_ews_mailbox_free (mb);
 	}
 	vcard_string = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
 	*vcards = g_slist_append (*vcards, g_strdup(vcard_string));
@@ -2603,9 +2586,7 @@ e_book_backend_ews_start_book_view (EBookBackend *backend,
 
 		e_data_book_view_notify_update (book_view, contact);
 
-		g_free (mb->email);
-		g_free (mb->name);
-		g_free (mb);
+		e_ews_mailbox_free (mb);
 		e_ews_free_resolve_contact (rc);
 		g_object_unref (contact);
 	}
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 3bfcbde..52c0d26 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -2930,6 +2930,7 @@ ews_get_attachments (ECalBackendEws *cbews,
 
 static void
 add_item_to_cache (ECalBackendEws *cbews,
+		   EEwsConnection *cnc,
                    EEwsItem *item)
 {
 	ECalBackendEwsPrivate *priv;
@@ -3065,9 +3066,7 @@ add_item_to_cache (ECalBackendEws *cbews,
 				icalcomponent_add_property (icalcomp, icalprop);
 
 				g_free (mailtoname);
-				g_free (mb->email);
-				g_free (mb->name);
-				g_free (mb);
+				e_ews_mailbox_free (mb);
 			}
 			g_slist_free (mailboxes);
 		}
@@ -3124,15 +3123,29 @@ add_item_to_cache (ECalBackendEws *cbews,
 		/* Attendees */
 		for (l = e_ews_item_get_attendees (item); l != NULL; l = g_slist_next (l)) {
 			icalparameter *param, *cu_type;
-			gchar *mailtoname;
+			gchar *mailtoname, *email = NULL;
 			EwsAttendee *attendee = (EwsAttendee *) l->data;
+
+			if (!attendee->mailbox)
+				continue;
+
+			if (g_strcmp0 (attendee->mailbox->mb_type, "EX") == 0) {
+				e_ews_connection_ex_to_smtp_sync (
+					cnc, EWS_PRIORITY_MEDIUM,
+					attendee->mailbox->email, &email,
+					NULL, NULL);
+			}
+
 			/*remove organizer for attendees list*/
-			if (g_ascii_strcasecmp (org_email_address, attendee->mailbox->email)== 0)
+			if (g_ascii_strcasecmp (org_email_address, email ? email : attendee->mailbox->email) == 0) {
+				g_free (email);
 				continue;
+			}
 
-			mailtoname = g_strdup_printf("mailto:%s";, attendee->mailbox->email);
+			mailtoname = g_strdup_printf ("mailto:%s";, email ? email : attendee->mailbox->email);
 			icalprop = icalproperty_new_attendee (mailtoname);
 			g_free (mailtoname);
+			g_free (email);
 
 			param = icalparameter_new_cn (attendee->mailbox->name);
 			icalproperty_add_parameter (icalprop, param);
@@ -3338,7 +3351,7 @@ ews_cal_get_items_ready_cb (GObject *obj,
 		EEwsItem *item = (EEwsItem *) l->data;
 
 		if (item && e_ews_item_get_item_type (item) != E_EWS_ITEM_TYPE_ERROR) {
-			add_item_to_cache (cbews, item);
+			add_item_to_cache (cbews, cnc, item);
 			ews_get_attachments (cbews, item);
 			g_object_unref (item);
 		}
diff --git a/src/camel/camel-ews-folder.c b/src/camel/camel-ews-folder.c
index cb0ed8f..c8be750 100644
--- a/src/camel/camel-ews-folder.c
+++ b/src/camel/camel-ews-folder.c
@@ -1210,7 +1210,7 @@ sync_created_items (CamelEwsFolder *ews_folder,
 	if (*error)
 		goto exit;
 
-	camel_ews_utils_sync_created_items (ews_folder, items);
+	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 	items = NULL;
 
 	if (post_item_ids)
@@ -1223,7 +1223,7 @@ sync_created_items (CamelEwsFolder *ews_folder,
 	if (*error)
 		goto exit;
 
-	camel_ews_utils_sync_created_items (ews_folder, items);
+	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 	items = NULL;
 
 	if (generic_item_ids)
@@ -1233,7 +1233,7 @@ sync_created_items (CamelEwsFolder *ews_folder,
 			FALSE, NULL, &items, NULL, NULL,
 			cancellable, error);
 
-	camel_ews_utils_sync_created_items (ews_folder, items);
+	camel_ews_utils_sync_created_items (ews_folder, cnc, items);
 
 exit:
 	if (msg_ids) {
diff --git a/src/camel/camel-ews-utils.c b/src/camel/camel-ews-utils.c
index cf5f29f..2d21336 100644
--- a/src/camel/camel-ews-utils.c
+++ b/src/camel/camel-ews-utils.c
@@ -678,38 +678,44 @@ ews_utils_get_server_flags (EEwsItem *item)
 }
 
 static const gchar *
-form_email_string_from_mb (const EwsMailbox *mb)
+form_email_string_from_mb (EEwsConnection *cnc,
+			   const EwsMailbox *mb,
+			   GCancellable *cancellable)
 {
-	const gchar *ret = NULL;
-
 	if (mb) {
 		GString *str;
+		gchar *email = NULL;
+
+		if (g_strcmp0 (mb->mb_type, "EX") == 0) {
+			e_ews_connection_ex_to_smtp_sync (
+				cnc, EWS_PRIORITY_MEDIUM,
+				mb->email, &email,
+				cancellable, NULL);
+		}
 
 		str = g_string_new ("");
 		if (mb->name && mb->name[0]) {
-			str = g_string_append (str, mb->name);
-			str = g_string_append (str, " ");
-		} else {
-			str = g_string_append (str, mb->email);
-			str = g_string_append (str, " ");
+			g_string_append (str, mb->name);
+			g_string_append (str, " ");
 		}
 
-		if (mb->email) {
+		if (mb->email || email) {
 			g_string_append (str, "<");
-			str = g_string_append (str, mb->email);
+			g_string_append (str, email ? email : mb->email);
 			g_string_append (str, ">");
 		}
 
-		ret = camel_pstring_add (str->str, TRUE);
-		g_string_free (str, FALSE);
+		g_free (email);
 
-		return ret;
+		return camel_pstring_add (g_string_free (str, FALSE), TRUE);
 	} else
 	       return camel_pstring_strdup ("");
 }
 
 static const gchar *
-form_recipient_list (const GSList *recipients)
+form_recipient_list (EEwsConnection *cnc,
+		     const GSList *recipients,
+		     GCancellable *cancellable)
 {
 	const GSList *l;
 	GString *str = NULL;
@@ -720,7 +726,7 @@ form_recipient_list (const GSList *recipients)
 
 	for (l = recipients; l != NULL; l = g_slist_next (l)) {
 		EwsMailbox *mb = (EwsMailbox *) l->data;
-		const gchar *mb_str = form_email_string_from_mb (mb);
+		const gchar *mb_str = form_email_string_from_mb (cnc, mb, cancellable);
 
 		if (!str)
 			str = g_string_new ("");
@@ -859,6 +865,7 @@ camel_ews_utils_sync_updated_items (CamelEwsFolder *ews_folder,
 
 void
 camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder,
+				    EEwsConnection *cnc,
                                     GSList *items_created)
 {
 	CamelFolder *folder;
@@ -922,13 +929,15 @@ camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder,
 		mi->info.date_received = e_ews_item_get_date_received (item);
 
 		from = e_ews_item_get_from (item);
-		mi->info.from = form_email_string_from_mb (from);
+		if (!from)
+			from = e_ews_item_get_sender (item);
+		mi->info.from = form_email_string_from_mb (cnc, from, NULL);
 
 		to = e_ews_item_get_to_recipients (item);
-		mi->info.to = form_recipient_list (to);
+		mi->info.to = form_recipient_list (cnc, to, NULL);
 
 		cc = e_ews_item_get_cc_recipients (item);
-		mi->info.cc = form_recipient_list (cc);
+		mi->info.cc = form_recipient_list (cnc, cc, NULL);
 
 		e_ews_item_has_attachments (item, &has_attachments);
 		if (has_attachments)
diff --git a/src/camel/camel-ews-utils.h b/src/camel/camel-ews-utils.h
index 69ff55a..6916fa7 100644
--- a/src/camel/camel-ews-utils.h
+++ b/src/camel/camel-ews-utils.h
@@ -88,6 +88,7 @@ CamelFolderInfo *
 void	camel_ews_utils_sync_deleted_items	(CamelEwsFolder *ews_folder,
 						 GSList *items_deleted);
 void	camel_ews_utils_sync_created_items	(CamelEwsFolder *ews_folder,
+						 EEwsConnection *cnc,
 						 GSList *items_created);
 void	camel_ews_utils_sync_updated_items	(CamelEwsFolder *ews_folder,
 						 GSList *items_updated);
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index b77bef7..0ababda 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -3731,6 +3731,132 @@ e_ews_connection_resolve_names_sync (EEwsConnection *cnc,
 	return result;
 }
 
+gboolean
+e_ews_connection_ex_to_smtp_sync (EEwsConnection *cnc,
+				  gint pri,
+				  const gchar *ex_address,
+				  gchar **smtp_address,
+				  GCancellable *cancellable,
+				  GError **error)
+{
+	GSList *mailboxes = NULL;
+	GSList *contacts = NULL;
+	gboolean includes_last_item = FALSE;
+
+	g_return_val_if_fail (cnc != NULL, FALSE);
+	g_return_val_if_fail (ex_address != NULL, FALSE);
+	g_return_val_if_fail (smtp_address != NULL, FALSE);
+
+	*smtp_address = NULL;
+
+	e_ews_connection_resolve_names_sync (
+		cnc, pri, ex_address,
+		EWS_SEARCH_AD_CONTACTS, NULL, TRUE, &mailboxes, &contacts,
+		&includes_last_item, cancellable, error);
+
+	/* only one mailbox matches */
+	if (mailboxes && !mailboxes->next && mailboxes->data) {
+		const EwsMailbox *mailbox = mailboxes->data;
+		if (mailbox->email && *mailbox->email && g_strcmp0 (mailbox->mb_type, "EX") != 0) {
+			*smtp_address = g_strdup (mailbox->email);
+		} else if (contacts && !contacts->next && contacts->data) {
+			const EwsResolveContact *resolved = contacts->data;
+			gint ii;
+
+			for (ii = 0; ii < g_hash_table_size (resolved->email_addresses); ii++) {
+				gchar *key, *value;
+
+				key = g_strdup_printf ("EmailAddress%d", ii + 1);
+				value = g_hash_table_lookup (resolved->email_addresses, key);
+				g_free (key);
+
+				if (value && g_str_has_prefix (value, "SMTP:")) {
+					/* pick the first available SMTP address */
+					*smtp_address = g_strdup (value + 5);
+					break;
+				}
+			}
+		}
+	}
+
+	g_slist_free_full (mailboxes, (GDestroyNotify) e_ews_mailbox_free);
+	g_slist_free_full (contacts, (GDestroyNotify) e_ews_free_resolve_contact);
+
+	if (!*smtp_address) {
+		const gchar *usename;
+
+		usename = strrchr (ex_address, '/');
+		if (usename && g_ascii_strncasecmp (usename, "/cn=", 4) == 0) {
+			GSList *miter;
+			gint len;
+
+			usename += 4;
+			len = strlen (usename);
+			mailboxes = NULL;
+			contacts = NULL;
+
+			/* use the first error, not the guess-part error */
+			e_ews_connection_resolve_names_sync (
+				cnc, pri, usename,
+				EWS_SEARCH_AD_CONTACTS, NULL, TRUE, &mailboxes, &contacts,
+				&includes_last_item, cancellable, NULL);
+
+			/* try to guess from common name of the EX address */
+			for (miter = mailboxes; miter; miter = miter->next) {
+				const EwsMailbox *mailbox = miter->data;
+				if (mailbox->email && *mailbox->email && g_strcmp0 (mailbox->mb_type, "EX") != 0
+				    && g_str_has_prefix (mailbox->email, usename) && mailbox->email[len] == '@') {
+					*smtp_address = g_strdup (mailbox->email);
+					break;
+				} else if (contacts && !contacts->next && contacts->data) {
+					const EwsResolveContact *resolved = contacts->data;
+					GList *emails = g_hash_table_get_values (resolved->email_addresses), *iter;
+					gboolean found = FALSE;
+
+					for (iter = emails; iter && !found; iter = iter->next) {
+						const gchar *it_email = iter->data;
+
+						if (it_email && g_str_has_prefix (it_email, "SMTP:")
+						    && g_str_has_prefix (it_email, usename) && it_email[len] == '@') {
+							found = TRUE;
+							break;
+						}
+					}
+
+					g_list_free (emails);
+
+					if (found) {
+						gint ii;
+
+						for (ii = 0; ii < g_hash_table_size (resolved->email_addresses); ii++) {
+							gchar *key, *value;
+
+							key = g_strdup_printf ("EmailAddress%d", ii + 1);
+							value = g_hash_table_lookup (resolved->email_addresses, key);
+							g_free (key);
+
+							if (value && g_str_has_prefix (value, "SMTP:")) {
+								/* pick the first available SMTP address */
+								*smtp_address = g_strdup (value + 5);
+								break;
+							}
+						}
+						break;
+					}
+				}
+			}
+
+			g_slist_free_full (mailboxes, (GDestroyNotify) e_ews_mailbox_free);
+			g_slist_free_full (contacts, (GDestroyNotify) e_ews_free_resolve_contact);
+		}
+	}
+
+	if (*smtp_address)
+		g_clear_error (error);
+
+	return *smtp_address != NULL;
+}
+
 void
 e_ews_connection_expand_dl (EEwsConnection *cnc,
                             gint pri,
diff --git a/src/server/e-ews-connection.h b/src/server/e-ews-connection.h
index 5a29b6b..9c06fe4 100644
--- a/src/server/e-ews-connection.h
+++ b/src/server/e-ews-connection.h
@@ -497,6 +497,14 @@ gboolean	e_ews_connection_expand_dl_sync	(EEwsConnection *cnc,
 						 GCancellable *cancellable,
 						 GError **error);
 
+gboolean	e_ews_connection_ex_to_smtp_sync
+						(EEwsConnection *cnc,
+						 gint pri,
+						 const gchar *ex_address,
+						 gchar **smtp_address,
+						 GCancellable *cancellable,
+						 GError **error);
+
 void		e_ews_connection_create_folder	(EEwsConnection *cnc,
 						 gint pri,
 						 const gchar *parent_folder_id,
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index bba13e8..b643eff 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -202,7 +202,6 @@ struct _EEwsItemPrivate {
 };
 
 static GObjectClass *parent_class = NULL;
-static void	ews_item_free_mailbox (EwsMailbox *mb);
 static void	ews_item_free_attendee (EwsAttendee *attendee);
 static void	ews_free_contact_fields (struct _EEwsContactFields *con_fields);
 
@@ -255,19 +254,19 @@ e_ews_item_dispose (GObject *object)
 	priv->timezone = NULL;
 
 	if (priv->to_recipients) {
-		g_slist_foreach (priv->to_recipients, (GFunc) ews_item_free_mailbox, NULL);
+		g_slist_foreach (priv->to_recipients, (GFunc) e_ews_mailbox_free, NULL);
 		g_slist_free (priv->to_recipients);
 		priv->to_recipients = NULL;
 	}
 
 	if (priv->cc_recipients) {
-		g_slist_foreach (priv->cc_recipients, (GFunc) ews_item_free_mailbox, NULL);
+		g_slist_foreach (priv->cc_recipients, (GFunc) e_ews_mailbox_free, NULL);
 		g_slist_free (priv->cc_recipients);
 		priv->cc_recipients = NULL;
 	}
 
 	if (priv->bcc_recipients) {
-		g_slist_foreach (priv->bcc_recipients, (GFunc) ews_item_free_mailbox, NULL);
+		g_slist_foreach (priv->bcc_recipients, (GFunc) e_ews_mailbox_free, NULL);
 		g_slist_free (priv->bcc_recipients);
 		priv->bcc_recipients = NULL;
 	}
@@ -298,8 +297,8 @@ e_ews_item_dispose (GObject *object)
 		priv->calendar_item_accept_id = NULL;
 	}
 
-	ews_item_free_mailbox (priv->sender);
-	ews_item_free_mailbox (priv->from);
+	e_ews_mailbox_free (priv->sender);
+	e_ews_mailbox_free (priv->from);
 
 	if (priv->item_type == E_EWS_ITEM_TYPE_CONTACT)
 		ews_free_contact_fields (priv->contact_fields);
@@ -411,20 +410,10 @@ ews_free_contact_fields (struct _EEwsContactFields *con_fields)
 }
 
 static void
-ews_item_free_mailbox (EwsMailbox *mb)
-{
-	if (mb) {
-		g_free (mb->name);
-		g_free (mb->email);
-		g_free (mb);
-	}
-}
-
-static void
 ews_item_free_attendee (EwsAttendee *attendee)
 {
 	if (attendee) {
-		ews_item_free_mailbox (attendee->mailbox);
+		e_ews_mailbox_free (attendee->mailbox);
 		g_free (attendee->responsetype);
 		g_free (attendee);
 	}
@@ -1391,19 +1380,6 @@ e_ews_item_mailbox_from_soap_param (ESoapParameter *param)
 	EwsMailbox *mb;
 	ESoapParameter *subparam;
 
-	/* Return NULL if RoutingType of Mailbox is not SMTP
-		 * For instance, people who don't exist any more	*/
-	subparam = e_soap_parameter_get_first_child_by_name (param, "RoutingType");
-	if (subparam) {
-		gchar *routingtype;
-		routingtype = e_soap_parameter_get_string_value (subparam);
-		if (g_ascii_strcasecmp (routingtype, "SMTP")) {
-			g_free (routingtype);
-			return NULL;
-		}
-		g_free (routingtype);
-	}
-
 	mb = g_new0 (EwsMailbox, 1);
 
 	subparam = e_soap_parameter_get_first_child_by_name (param, "Name");
@@ -1414,9 +1390,37 @@ e_ews_item_mailbox_from_soap_param (ESoapParameter *param)
 	if (subparam)
 		mb->email = e_soap_parameter_get_string_value (subparam);
 
+	subparam = e_soap_parameter_get_first_child_by_name (param, "RoutingType");
+	if (subparam)
+		mb->mb_type = e_soap_parameter_get_string_value (subparam);
+
+	if (!mb->email) {
+		e_ews_mailbox_free (mb);
+		mb = NULL;
+	}
+
 	return mb;
 }
 
+void
+e_ews_mailbox_free (EwsMailbox *mailbox)
+{
+	if (!mailbox)
+		return;
+
+	g_free (mailbox->name);
+	g_free (mailbox->email);
+	g_free (mailbox->mb_type);
+
+	if (mailbox->item_id) {
+		g_free (mailbox->item_id->id);
+		g_free (mailbox->item_id->change_key);
+		g_free (mailbox->item_id);
+	}
+
+	g_free (mailbox);
+}
+
 const GSList *
 e_ews_item_get_modified_occurrences (EEwsItem *item)
 {
diff --git a/src/server/e-ews-item.h b/src/server/e-ews-item.h
index 04be20d..47db6de 100644
--- a/src/server/e-ews-item.h
+++ b/src/server/e-ews-item.h
@@ -161,6 +161,7 @@ const GSList *
 EwsMailbox *
 		e_ews_item_mailbox_from_soap_param
 						(ESoapParameter *param);
+void		e_ews_mailbox_free		(EwsMailbox *mailbox);
 EwsResolveContact *
 		e_ews_item_resolve_contact_from_soap_param (ESoapParameter *param);
 void		e_ews_free_resolve_contact	(/*EwsResolveContact * */ gpointer rc);
diff --git a/src/server/tests/test-autocompletion.c b/src/server/tests/test-autocompletion.c
index 0227609..82c90de 100644
--- a/src/server/tests/test-autocompletion.c
+++ b/src/server/tests/test-autocompletion.c
@@ -58,9 +58,7 @@ resolve_names_cb (GObject *object,
 			EwsMailbox *mb = (EwsMailbox *) l->data;
 			g_print ("%s:%s \n", mb->name, mb->email);
 
-			g_free (mb->name);
-			g_free (mb->email);
-			g_free (mb);
+			e_ews_mailbox_free (mb);
 		}
 
 		g_slist_free (mailboxes);



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