[evolution-data-server/openismus-work] Store E.164 phone number values automatically in the vCard



commit 88fe4b67830e242cc2a3588982dcbbbaf7db9604
Author: Tristan Van Berkom <tristanvb openismus com>
Date:   Fri Feb 15 20:56:41 2013 +0900

    Store E.164 phone number values automatically in the vCard
    
    The E.164 normalized phone number is of interest for handset related
    applications. With this change a X-EVOLUTION-E164 attribute is added
    to each TEL attribute if the contact summary contains a E.164 formatted
    variant of the phone number. This shall avoid overhead and inconsistency
    that would occur if clients would use their own mechanism to compute
    that already stored information.
    
    Updated Mathias Hasselmann's patch on bug 689622 to apply to current master.

 .../libedata-book/e-book-backend-sqlitedb.c        |   69 +++++++++
 tests/libebook/client/Makefile.am                  |    5 +-
 tests/libebook/client/test-client-e164-param.c     |  158 ++++++++++++++++++++
 tests/libebook/data/vcards/custom-2.vcf            |    2 +-
 4 files changed, 232 insertions(+), 2 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c 
b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index 758ade6..2577262 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -1643,6 +1643,71 @@ insert_stmt_from_contact (EBookBackendSqliteDB *ebsdb,
        return g_string_free (string, FALSE);
 }
 
+static void
+update_e164_attribute_params (EVCard *vcard)
+{
+       GList *attr_list;
+
+       for (attr_list = e_vcard_get_attributes (vcard); attr_list; attr_list = attr_list->next) {
+               EVCardAttribute *const attr = attr_list->data;
+               EVCardAttributeParam *param = NULL;
+               gchar *e164 = NULL, *cc, *nn;
+               GList *param_list, *values;
+
+               /* We only attach E164 parameters to TEL attributes. */
+               if (strcmp (e_vcard_attribute_get_name (attr), EVC_TEL) != 0)
+                       continue;
+
+               /* Compute E164 number. */
+               values = e_vcard_attribute_get_values (attr);
+               e164 = values && values->data ? convert_phone (values->data, NULL) : NULL;
+
+               if (e164 == NULL) {
+                       e_vcard_attribute_remove_param (attr, EVC_X_E164);
+                       continue;
+               }
+
+               /* Find already exisiting parameter, so that we can reuse it. */
+               for (param_list = e_vcard_attribute_get_params (attr); param_list; param_list = 
param_list->next) {
+                       if (strcmp (e_vcard_attribute_param_get_name (param_list->data), EVC_X_E164) == 0) {
+                               param = param_list->data;
+                               break;
+                       }
+               }
+
+               /* Create a new parameter instance if needed. Otherwise clean
+                * the existing parameter's values: This is much cheaper than
+                * checking for modifications. */
+               if (param == NULL) {
+                       param = e_vcard_attribute_param_new (EVC_X_E164);
+                       e_vcard_attribute_add_param (attr, param);
+               } else {
+                       e_vcard_attribute_param_remove_values (param);
+               }
+
+               /* Split the phone number into country calling code and
+                * national number code. */
+               nn = strchr (e164, '|');
+
+               if (nn == NULL) {
+                       g_warn_if_reached ();
+                       continue;
+               }
+
+               *nn++ = '\0';
+               cc = e164;
+
+               /* Assign the parameter values. It seems odd that we revert
+                * the order of NN and CC, but at least EVCard's parser doesn't
+                * permit an empty first param value. Which of course could be
+                * fixed - in order to create a nice potential IOP problem with
+                ** other vCard parsers. */
+               e_vcard_attribute_param_add_values (param, nn, cc, NULL);
+
+               g_free (e164);
+       }
+}
+
 static gboolean
 insert_contact (EBookBackendSqliteDB *ebsdb,
                EContact *contact,
@@ -1656,6 +1721,10 @@ insert_contact (EBookBackendSqliteDB *ebsdb,
 
        priv = ebsdb->priv;
 
+       /* Update E.164 parameters in vcard if needed */
+       if (priv->store_vcard)
+               update_e164_attribute_params (E_VCARD (contact));
+
        /* Update main summary table */
        stmt = insert_stmt_from_contact (ebsdb, contact, folderid, priv->store_vcard, replace_existing);
        success = book_backend_sql_exec (priv->db, stmt, NULL, NULL, error);
diff --git a/tests/libebook/client/Makefile.am b/tests/libebook/client/Makefile.am
index 86096ab..072e7dd 100644
--- a/tests/libebook/client/Makefile.am
+++ b/tests/libebook/client/Makefile.am
@@ -44,7 +44,8 @@ TESTS =                                                               \
        test-client-preserve-uid                                \
        test-client-get-contact                                 \
        test-client-get-contact-uids                            \
-       test-client-custom-summary                              \
+       test-client-e164-param                                  \
+        test-client-custom-summary                             \
        test-client-get-revision                                \
        test-client-get-view                                    \
        test-client-view-operations                             \
@@ -105,6 +106,8 @@ test_client_get_contact_LDADD=$(TEST_LIBS)
 test_client_get_contact_CPPFLAGS=$(TEST_CPPFLAGS)
 test_client_get_contact_uids_LDADD=$(TEST_LIBS)
 test_client_get_contact_uids_CPPFLAGS=$(TEST_CPPFLAGS)
+test_client_e164_param_LDADD=$(TEST_LIBS)
+test_client_e164_param_CPPFLAGS=$(TEST_CPPFLAGS)
 test_client_custom_summary_LDADD=$(TEST_LIBS)
 test_client_custom_summary_CPPFLAGS=$(TEST_CPPFLAGS)
 test_client_get_revision_LDADD=$(TEST_LIBS)
diff --git a/tests/libebook/client/test-client-e164-param.c b/tests/libebook/client/test-client-e164-param.c
new file mode 100644
index 0000000..9c0a757
--- /dev/null
+++ b/tests/libebook/client/test-client-e164-param.c
@@ -0,0 +1,158 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Authors: Tristan Van Berkom <tristanvb openismus com>
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <libebook/libebook.h>
+
+#include "client-test-utils.h"
+#include "e-test-server-utils.h"
+
+#ifdef ENABLE_PHONENUMBER
+
+typedef struct {
+       ETestServerClosure parent;
+
+       gchar *vcard_name;
+       gchar *formatted_number;
+       gchar *country_calling_code;
+       gchar *national_number;
+} TestData;
+
+static void
+test_data_free (gpointer user_data)
+{
+       TestData *const data = user_data;
+
+       g_free (data->vcard_name);
+       g_free (data->formatted_number);
+       g_free (data->country_calling_code);
+       g_free (data->national_number);
+       g_free (data);
+}
+
+static TestData *
+test_data_new (const gchar *vcard_name,
+              const gchar *formatted_number,
+              const gchar *country_calling_code,
+              const gchar *national_number)
+{
+       TestData *const data = g_new0 (TestData, 1);
+
+       data->parent.type = E_TEST_SERVER_ADDRESS_BOOK;
+       data->parent.destroy_closure_func = test_data_free;
+       data->vcard_name = g_strdup (vcard_name);
+       data->formatted_number = g_strdup (formatted_number);
+       data->country_calling_code = g_strdup (country_calling_code);
+       data->national_number = g_strdup (national_number);
+
+       g_print ("%d %p\n", data->parent.calendar_source_type, data->parent.destroy_closure_func);
+
+       return data;
+}
+
+static void
+test_add_e164_param (ETestServerFixture *fixture,
+                    gconstpointer       user_data)
+{
+       const TestData *const data = user_data;
+       EBookClient          *book_client;
+       EContact             *contact;
+       gchar                *vcard;
+       gchar                *uid;
+       EVCardAttribute      *tel;
+       GList                *values;
+       GError               *error = NULL;
+
+       book_client = E_TEST_SERVER_UTILS_SERVICE (fixture, EBookClient);
+       g_print ("%p\n", book_client);
+
+       vcard   = new_vcard_from_test_case (data->vcard_name);
+       contact = e_contact_new_from_vcard (vcard);
+       g_free (vcard);
+
+       tel = e_vcard_get_attribute (E_VCARD (contact), EVC_TEL);
+       values = tel ? e_vcard_attribute_get_values (tel) : NULL;
+
+       g_assert (values != NULL);
+       g_assert_cmpstr (values->data, ==, data->formatted_number);
+
+       values = e_vcard_attribute_get_param (tel, EVC_X_E164);
+       g_assert (values == NULL);
+
+       if (!e_book_client_add_contact_sync (book_client, contact, &uid, NULL, &error))
+               g_error ("Failed to add contact: %s", error->message);
+
+       g_object_unref (contact);
+
+       if (!e_book_client_get_contact_sync (book_client, uid, &contact, NULL, &error))
+               g_error ("Failed to restore contact: %s", error->message);
+
+       g_free (uid);
+
+
+       tel = e_vcard_get_attribute (E_VCARD (contact), EVC_TEL);
+       values = tel ? e_vcard_attribute_get_values (tel) : NULL;
+
+       g_assert (values != NULL);
+       g_assert_cmpstr (values->data, ==, data->formatted_number);
+
+       values = e_vcard_attribute_get_param (tel, EVC_X_E164);
+
+       g_assert (values != NULL);
+       g_assert_cmpstr (values->data, ==, data->national_number);
+
+       if (data->country_calling_code) {
+               g_assert (values->next != NULL);
+               g_assert_cmpstr (values->next->data, ==, data->country_calling_code);
+       } else {
+               g_assert (values->next == NULL);
+       }
+}
+
+#endif /* ENABLE_PHONENUMBER */
+
+gint
+main (gint argc,
+      gchar **argv)
+{
+#if !GLIB_CHECK_VERSION (2, 35, 1)
+       g_type_init ();
+#endif
+       g_test_init (&argc, &argv, NULL);
+
+#ifdef ENABLE_PHONENUMBER
+
+       g_test_add (
+               "/EBookClient/AddContact/AddE164Param/1", ETestServerFixture,
+               test_data_new ("custom-1", "+1-221-5423789", "+1", "2215423789"),
+               e_test_server_utils_setup, test_add_e164_param,
+               e_test_server_utils_teardown);
+       g_test_add (
+               "/EBookClient/AddContact/AddE164Param/2", ETestServerFixture,
+               test_data_new ("custom-2", "7654321", NULL, "7654321"),
+               e_test_server_utils_setup, test_add_e164_param,
+               e_test_server_utils_teardown);
+
+#endif /* ENABLE_PHONENUMBER */
+
+       return e_test_server_utils_run ();
+}
diff --git a/tests/libebook/data/vcards/custom-2.vcf b/tests/libebook/data/vcards/custom-2.vcf
index 56c5dd6..4222049 100644
--- a/tests/libebook/data/vcards/custom-2.vcf
+++ b/tests/libebook/data/vcards/custom-2.vcf
@@ -1,7 +1,7 @@
 BEGIN:VCARD
 FN:Janet Jackson
 N:Janet
-TEL;HOME:+7654321
+TEL;HOME:7654321
 EMAIL:janet jackson com
 EMAIL:janny jackson com
 END:VCARD


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