[evolution-ews] Bug #658892 - Support contact list creation
- From: Fabiano Fidêncio <ffidencio src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Bug #658892 - Support contact list creation
- Date: Thu, 16 May 2013 12:28:18 +0000 (UTC)
commit 5de4de5a162e0621e0547dc1fb208b55dd4df252
Author: Fabiano Fidêncio <fidencio redhat com>
Date: Thu May 2 14:15:22 2013 +0200
Bug #658892 - Support contact list creation
src/addressbook/e-book-backend-ews.c | 301 +++++++++++++++++++++++++---------
src/server/e-ews-item.c | 8 +
2 files changed, 232 insertions(+), 77 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index b23e6e6..471c557 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -1228,6 +1228,61 @@ typedef struct {
} EwsCreateContact;
static void
+ews_write_dl_members (ESoapMessage *msg,
+ EContact *contact)
+{
+ GSList *emails, *l;
+
+ e_soap_message_start_element (msg, "Members", NULL, NULL);
+
+ emails = e_contact_get (contact, E_CONTACT_EMAIL);
+ for (l = emails; l; l = l->next) {
+ CamelInternetAddress *addr;
+
+ if (l->data == NULL)
+ continue;
+
+ addr = camel_internet_address_new ();
+ if (camel_address_decode (CAMEL_ADDRESS (addr), l->data) > 0) {
+ const gchar *name = NULL, *email = NULL;
+
+ if (camel_internet_address_get (addr, 0, &name, &email) && email) {
+ e_soap_message_start_element (msg, "Member", NULL, NULL);
+ e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
+ e_ews_message_write_string_parameter (msg, "Name", NULL, name ? : email);
+ e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, email);
+ e_soap_message_end_element (msg); /* Mailbox */
+ e_soap_message_end_element (msg); /* Member */
+ }
+ }
+ g_object_unref (addr);
+ }
+
+ g_slist_free_full (emails, g_free);
+ e_soap_message_end_element (msg); /* Members */
+}
+
+static void
+convert_dl_to_xml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EContact *contact = user_data;
+ EVCardAttribute *attribute;
+ GList *values;
+
+ /* Prepare DistributionList node in the SOAP message */
+ e_soap_message_start_element (msg, "DistributionList", NULL, NULL);
+
+ attribute = e_vcard_get_attribute (E_VCARD (contact), EVC_FN);
+ values = e_vcard_attribute_get_values (attribute);
+ e_ews_message_write_string_parameter (msg, "DisplayName", NULL, values->data);
+
+ ews_write_dl_members (msg, contact);
+
+ e_soap_message_end_element (msg); /* DistributionList */
+}
+
+static void
convert_contact_to_xml (ESoapMessage *msg,
gpointer user_data)
{
@@ -1341,6 +1396,7 @@ e_book_backend_ews_create_contacts (EBookBackend *backend,
EwsFolderId *fid;
EBookBackendEwsPrivate *priv;
GError *error = NULL;
+ gboolean is_dl = FALSE;
if (vcards->next != NULL) {
e_data_book_respond_create_contacts (
@@ -1378,9 +1434,18 @@ e_book_backend_ews_create_contacts (EBookBackend *backend,
contact = e_contact_new_from_vcard (vcards->data);
if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
- g_object_unref (contact);
- e_data_book_respond_create_contacts (book, opid, EDB_ERROR (NOT_SUPPORTED), NULL);
- return;
+ if (!e_ews_connection_satisfies_server_version (ebews->priv->cnc, E_EWS_EXCHANGE_2010)) {
+ g_object_unref (contact);
+ e_data_book_respond_create_contacts (
+ book,
+ opid,
+ EDB_ERROR_EX (
+ NOT_SUPPORTED,
+ _("Cannot save contact list, it's only supported on EWS Server 2010
or later")),
+ NULL);
+ return;
+ }
+ is_dl = TRUE;
}
create_contact = g_new0 (EwsCreateContact, 1);
@@ -1398,7 +1463,7 @@ e_book_backend_ews_create_contacts (EBookBackend *backend,
EWS_PRIORITY_MEDIUM, NULL,
NULL,
fid,
- convert_contact_to_xml,
+ is_dl ? convert_dl_to_xml : convert_contact_to_xml,
contact,
cancellable,
ews_create_contact_cb,
@@ -1584,6 +1649,26 @@ ews_modify_contact_cb (GObject *object,
}
static void
+convert_dl_to_updatexml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsModifyContact *modify_contact = user_data;
+ EwsId *id;
+ EContact *old_contact = modify_contact->old_contact;
+ EContact *new_contact = modify_contact->new_contact;
+
+ id = g_new0 (EwsId, 1);
+ id->id = e_contact_get (old_contact, E_CONTACT_UID);
+ id->change_key = e_contact_get (old_contact, E_CONTACT_REV);
+
+ e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM, id->id, id->change_key, 0);
+ e_ews_message_start_set_item_field (msg, "Members", "distributionlist", "DistributionList");
+ ews_write_dl_members (msg, new_contact);
+ e_ews_message_end_set_item_field (msg);
+ e_ews_message_end_item_change (msg);
+}
+
+static void
convert_contact_to_updatexml (ESoapMessage *msg,
gpointer user_data)
{
@@ -1652,6 +1737,7 @@ e_book_backend_ews_modify_contacts (EBookBackend *backend,
EwsId *id;
EBookBackendEwsPrivate *priv;
GError *error;
+ gboolean is_dl = FALSE;
if (vcards->next != NULL) {
e_data_book_respond_modify_contacts (book, opid,
@@ -1690,17 +1776,26 @@ e_book_backend_ews_modify_contacts (EBookBackend *backend,
contact = e_contact_new_from_vcard (vcards->data);
- id = g_new0 (EwsId, 1);
- id->id = e_contact_get (contact, E_CONTACT_UID);
- id->change_key = e_contact_get (contact, E_CONTACT_REV);
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ if (!e_ews_connection_satisfies_server_version (ebews->priv->cnc, E_EWS_EXCHANGE_2010)) {
+ g_object_unref (contact);
+ e_data_book_respond_create_contacts (
+ book,
+ opid,
+ EDB_ERROR_EX (
+ NOT_SUPPORTED,
+ _("Cannot save contact list, it's only supported on EWS Server 2010
or later")),
+ NULL);
+ return;
+ }
+ is_dl = TRUE;
+ }
/*get item id and change key from contact and fetch old contact and assign.*/
- if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
- g_object_unref (contact);
- e_data_book_respond_modify_contacts (book, opid, EDB_ERROR (NOT_SUPPORTED), NULL);
- return;
- }
+ id = g_new0 (EwsId, 1);
+ id->id = e_contact_get (contact, E_CONTACT_UID);
+ id->change_key = e_contact_get (contact, E_CONTACT_REV);
old_contact = e_book_backend_sqlitedb_get_contact (
priv->summary, priv->folder_id,
@@ -1721,10 +1816,14 @@ e_book_backend_ews_modify_contacts (EBookBackend *backend,
modify_contact->cancellable = g_object_ref (cancellable);
e_ews_connection_update_items (
- priv->cnc, EWS_PRIORITY_MEDIUM,
- "AlwaysOverwrite", "SendAndSaveCopy",
- "SendToAllAndSaveCopy", priv->folder_id,
- convert_contact_to_updatexml, modify_contact,
+ priv->cnc,
+ EWS_PRIORITY_MEDIUM,
+ "AlwaysOverwrite",
+ "SendAndSaveCopy",
+ "SendToAllAndSaveCopy",
+ priv->folder_id,
+ is_dl ? convert_dl_to_updatexml : convert_contact_to_updatexml,
+ modify_contact,
cancellable,
ews_modify_contact_cb,
modify_contact);
@@ -2490,65 +2589,82 @@ ebews_get_vcards_list (EBookBackendEws *ebews,
g_slist_free (new_items);
}
-static void
-ebews_store_distribution_list_items (EBookBackendEws *ebews,
- const EwsId *id,
- const gchar *d_name,
- GSList *members,
- GError **error)
-{
- GSList *l;
- EContact *contact;
+static gboolean
+ebews_traverse_dl (EBookBackendEws *ebews,
+ EContact **contact,
+ GHashTable *items,
+ GHashTable *values,
+ EwsMailbox *mb,
+ GError **error)
+{
+ if (g_strcmp0 (mb->mailbox_type, "PrivateDL") == 0) {
+ GSList *members = NULL, *l;
+ gboolean includes_last;
+ gboolean ret;
- g_return_if_fail (ebews->priv->summary != NULL);
+ if (!mb->item_id || !mb->item_id->id)
+ return FALSE;
- contact = e_contact_new ();
- e_contact_set (contact, E_CONTACT_UID, id->id);
- e_contact_set (contact, E_CONTACT_REV, id->change_key);
+ if (g_hash_table_lookup (items, mb->item_id->id) != NULL)
+ return TRUE;
- e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE));
- e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES, GINT_TO_POINTER (TRUE));
- e_contact_set (contact, E_CONTACT_FULL_NAME, d_name);
+ g_hash_table_insert (items, g_strdup (mb->item_id->id), GINT_TO_POINTER (1));
- for (l = members; l != NULL; l = g_slist_next (l)) {
- EwsMailbox *mb = (EwsMailbox *) l->data;
+ if (!e_ews_connection_expand_dl_sync (
+ ebews->priv->cnc,
+ EWS_PRIORITY_MEDIUM,
+ mb,
+ &members,
+ &includes_last,
+ ebews->priv->cancellable,
+ error))
+ return FALSE;
+
+ for (l = members; l; l = l->next) {
+ ret = ebews_traverse_dl (ebews, contact, items, values, l->data, error);
+ if (!ret)
+ break;
+ }
+
+ g_slist_free_full (members, (GDestroyNotify) e_ews_mailbox_free);
+ return ret;
+ } else {
EVCardAttribute *attr;
+ CamelInternetAddress *addr;
+ gchar *value = NULL;
+
+ if (mb->name == NULL && mb->email == NULL)
+ return TRUE;
+ addr = camel_internet_address_new ();
attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
- if (mb->name) {
- gint len = strlen (mb->name);
- gchar *value;
- if (mb->name[0] == '\"' && mb->name[len - 1] == '\"')
- value = g_strdup_printf ("%s <%s>", mb->name, mb->email);
- else
- value = g_strdup_printf ("\"%s\" <%s>", mb->name, mb->email);
+ camel_internet_address_add (addr, mb->name, mb->email ? : "");
+ value = camel_address_encode (CAMEL_ADDRESS (addr));
+ if (value && g_hash_table_lookup (values, value) == NULL) {
e_vcard_attribute_add_value (attr, value);
- g_free (value);
- } else
- e_vcard_attribute_add_value (attr, mb->email);
+ e_vcard_add_attribute (E_VCARD (*contact), attr);
- e_vcard_add_attribute (E_VCARD (contact), attr);
- e_ews_mailbox_free (mb);
- }
+ g_hash_table_insert (values, g_strdup (value), GINT_TO_POINTER (1));
+ }
- g_slist_free (members);
- e_book_backend_sqlitedb_new_contact (ebews->priv->summary, ebews->priv->folder_id, contact, TRUE,
error);
- e_book_backend_notify_update (E_BOOK_BACKEND (ebews), contact);
+ g_object_unref (addr);
- g_object_unref (contact);
+ return TRUE;
+ }
}
-static void
-ebews_vcards_append_dl (const EwsId *id,
- const gchar *d_name,
- GSList *members,
- GSList **vcards)
+static EContact *
+ebews_get_dl_info (EBookBackendEws *ebews,
+ const EwsId *id,
+ const gchar *d_name,
+ GSList *members,
+ GError **error)
{
+ GHashTable *items, *values;
GSList *l;
EContact *contact;
- gchar *vcard_string = NULL;
contact = e_contact_new ();
e_contact_set (contact, E_CONTACT_UID, id->id);
@@ -2558,32 +2674,62 @@ ebews_vcards_append_dl (const EwsId *id,
e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES, GINT_TO_POINTER (TRUE));
e_contact_set (contact, E_CONTACT_FULL_NAME, d_name);
- for (l = members; l != NULL; l = g_slist_next (l)) {
- EwsMailbox *mb = (EwsMailbox *) l->data;
- EVCardAttribute *attr;
+ items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
- if (mb->name) {
- gint len = strlen (mb->name);
- gchar *value;
+ for (l = members; l != NULL; l = l->next) {
+ if (!ebews_traverse_dl (ebews, &contact, items, values, l->data, error)) {
+ g_object_unref (contact);
+ contact = NULL;
+ goto exit;
+ }
+ }
- if (mb->name[0] == '\"' && mb->name[len - 1] == '\"')
- value = g_strdup_printf ("%s <%s>", mb->name, mb->email);
- else
- value = g_strdup_printf ("\"%s\" <%s>", mb->name, mb->email);
+exit:
+ g_hash_table_destroy (items);
+ g_hash_table_destroy (values);
+ return contact;
+}
- e_vcard_attribute_add_value (attr, value);
- g_free (value);
- } else
- e_vcard_attribute_add_value (attr, mb->email);
+static void
+ebews_store_distribution_list_items (EBookBackendEws *ebews,
+ const EwsId *id,
+ const gchar *d_name,
+ GSList *members,
+ GError **error)
+{
+ EContact *contact;
+ g_return_if_fail (ebews->priv->summary != NULL);
+
+ contact = ebews_get_dl_info (ebews, id, d_name, members, error);
+ if (contact == NULL)
+ return;
+
+ e_book_backend_sqlitedb_new_contact (ebews->priv->summary, ebews->priv->folder_id, contact, TRUE,
error);
+ e_book_backend_notify_update (E_BOOK_BACKEND (ebews), contact);
+
+ g_object_unref (contact);
+}
+
+static void
+ebews_vcards_append_dl (EBookBackendEws *ebews,
+ const EwsId *id,
+ const gchar *d_name,
+ GSList *members,
+ GSList **vcards,
+ GError **error)
+{
+ EContact *contact;
+ gchar *vcard_string = NULL;
+
+ contact = ebews_get_dl_info (ebews, id, d_name, members, error);
+ if (contact == NULL)
+ return;
- e_vcard_add_attribute (E_VCARD (contact), attr);
- 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));
+
g_free (vcard_string);
- g_slist_free (members);
g_object_unref (contact);
}
@@ -2682,9 +2828,10 @@ ebews_fetch_items (EBookBackendEws *ebews,
if (store_to_cache)
ebews_store_distribution_list_items (ebews, id, d_name, members, error);
else
- ebews_vcards_append_dl (id, d_name, members, vcards);
+ ebews_vcards_append_dl (ebews, id, d_name, members, vcards, error);
g_free (mb);
+ g_slist_free_full (members, (GDestroyNotify) e_ews_mailbox_free);
if (*error)
goto cleanup;
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index 810523a..7b1fbb0 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -1445,6 +1445,14 @@ e_ews_item_mailbox_from_soap_param (ESoapParameter *param)
if (subparam)
mb->mailbox_type = e_soap_parameter_get_string_value (subparam);
+ subparam = e_soap_parameter_get_first_child_by_name (param, "ItemId");
+ if (subparam) {
+ EwsId *id = g_new0 (EwsId, 1);
+ id->id = e_soap_parameter_get_property (subparam, "Id");
+ id->change_key = e_soap_parameter_get_property (subparam, "ChangeKey");
+ mb->item_id = id;
+ }
+
if (!mb->email && !mb->name) {
e_ews_mailbox_free (mb);
mb = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]