[evolution-data-server] Bug 605416 - Add aliases for accounts



commit 3d7b6477e75408ec3c220847aa4f1a349546a946
Author: Milan Crha <mcrha redhat com>
Date:   Tue Oct 18 18:37:07 2016 +0200

    Bug 605416 - Add aliases for accounts

 src/calendar/libedata-cal/e-cal-backend-util.c |  120 +++++++++-------
 src/calendar/libedata-cal/e-cal-backend-util.h |    2 +-
 src/libedataserver/e-source-mail-identity.c    |  179 +++++++++++++++++++++++-
 src/libedataserver/e-source-mail-identity.h    |    9 ++
 4 files changed, 254 insertions(+), 56 deletions(-)
---
diff --git a/src/calendar/libedata-cal/e-cal-backend-util.c b/src/calendar/libedata-cal/e-cal-backend-util.c
index 691f517..7bea238 100644
--- a/src/calendar/libedata-cal/e-cal-backend-util.c
+++ b/src/calendar/libedata-cal/e-cal-backend-util.c
@@ -77,7 +77,7 @@ e_cal_backend_mail_account_get_default (ESourceRegistry *registry,
  */
 gboolean
 e_cal_backend_mail_account_is_valid (ESourceRegistry *registry,
-                                     gchar *user,
+                                     const gchar *user,
                                      gchar **name)
 {
        GList *list, *iter;
@@ -126,6 +126,16 @@ e_cal_backend_mail_account_is_valid (ESourceRegistry *registry,
                        g_free (address);
                }
 
+               if (!match) {
+                       GHashTable *aliases;
+
+                       aliases = e_source_mail_identity_get_aliases_as_hash_table (mail_identity);
+                       if (aliases) {
+                               match = g_hash_table_contains (aliases, user);
+                               g_hash_table_destroy (aliases);
+                       }
+               }
+
                if (match && name != NULL)
                        *name = e_source_dup_display_name (source);
 
@@ -142,56 +152,29 @@ e_cal_backend_mail_account_is_valid (ESourceRegistry *registry,
        return valid;
 }
 
-/**
- * is_attendee_declined:
- * @icalcomp: Component where to check the attendee list.
- * @email: Attendee's email to look for.
- *
- * Returns: Whether the required attendee declined or not.
- *          It's not necessary to have this attendee in the list.
- **/
 static gboolean
-is_attendee_declined (icalcomponent *icalcomp,
-                      const gchar *email)
+is_attendee_declined (GSList *declined_attendees,
+                      const gchar *email,
+                     GHashTable *aliases)
 {
-       icalproperty *prop;
-       icalparameter *param;
+       GSList *iter;
 
-       g_return_val_if_fail (icalcomp != NULL, FALSE);
-       g_return_val_if_fail (email != NULL, FALSE);
+       if (!email && !aliases)
+               return FALSE;
 
-       for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
-            prop != NULL;
-            prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) {
-               gchar *attendee;
-               gchar *text;
+       for (iter = declined_attendees; iter; iter = g_slist_next (iter)) {
+               const gchar *attendee = iter->data;
 
-               attendee = icalproperty_get_value_as_string_r (prop);
                if (!attendee)
                        continue;
 
-               if (!g_ascii_strncasecmp (attendee, "mailto:";, 7))
-                       text = g_strdup (attendee + 7);
-               else
-                       text = g_strdup (attendee);
-
-               text = g_strstrip (text);
-
-               if (!g_ascii_strcasecmp (email, text)) {
-                       g_free (text);
-                       g_free (attendee);
-                       break;
+               if ((email && g_ascii_strcasecmp (email, attendee) == 0) ||
+                   (aliases && g_hash_table_contains (aliases, attendee))) {
+                       return TRUE;
                }
-               g_free (text);
-               g_free (attendee);
        }
 
-       if (!prop)
-               return FALSE;
-
-       param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
-
-       return param && icalparameter_get_partstat (param) == ICAL_PARTSTAT_DECLINED;
+       return FALSE;
 }
 
 /**
@@ -209,35 +192,66 @@ e_cal_backend_user_declined (ESourceRegistry *registry,
                              icalcomponent *icalcomp)
 {
        GList *list, *iter;
-       const gchar *extension_name;
+       GSList *declined_attendees = NULL;
        gboolean declined = FALSE;
+       icalproperty *prop;
+       icalparameter *param;
 
        g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
        g_return_val_if_fail (icalcomp != NULL, FALSE);
 
-       extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+       /* First test whether there is any declined attendee at all and remember his/her address */
+       for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+            prop != NULL;
+            prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) {
+               param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
 
-       list = e_source_registry_list_enabled (registry, extension_name);
+               if (param && icalparameter_get_partstat (param) == ICAL_PARTSTAT_DECLINED) {
+                       gchar *attendee;
+                       gchar *address;
 
-       for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+                       attendee = icalproperty_get_value_as_string_r (prop);
+                       if (attendee) {
+                               if (!g_ascii_strncasecmp (attendee, "mailto:";, 7))
+                                       address = g_strdup (attendee + 7);
+                               else
+                                       address = g_strdup (attendee);
+
+                               address = g_strstrip (address);
+
+                               if (address && *address)
+                                       declined_attendees = g_slist_prepend (declined_attendees, address);
+                               else
+                                       g_free (address);
+
+                               g_free (attendee);
+                       }
+               }
+       }
+
+       if (!declined_attendees)
+               return FALSE;
+
+       list = e_source_registry_list_enabled (registry, E_SOURCE_EXTENSION_MAIL_IDENTITY);
+
+       for (iter = list; iter != NULL && !declined; iter = g_list_next (iter)) {
                ESource *source = E_SOURCE (iter->data);
                ESourceMailIdentity *extension;
+               GHashTable *aliases;
                const gchar *address;
 
-               extension = e_source_get_extension (source, extension_name);
+               extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_IDENTITY);
                address = e_source_mail_identity_get_address (extension);
+               aliases = e_source_mail_identity_get_aliases_as_hash_table (extension);
 
-               if (address == NULL)
-                       continue;
+               declined = is_attendee_declined (declined_attendees, address, aliases);
 
-               if (is_attendee_declined (icalcomp, address)) {
-                       declined = TRUE;
-                       break;
-               }
+               if (aliases)
+                       g_hash_table_destroy (aliases);
        }
 
-       g_list_free_full (list, (GDestroyNotify) g_object_unref);
+       g_slist_free_full (declined_attendees, g_free);
+       g_list_free_full (list, g_object_unref);
 
        return declined;
 }
-
diff --git a/src/calendar/libedata-cal/e-cal-backend-util.h b/src/calendar/libedata-cal/e-cal-backend-util.h
index b4798de..730b704 100644
--- a/src/calendar/libedata-cal/e-cal-backend-util.h
+++ b/src/calendar/libedata-cal/e-cal-backend-util.h
@@ -41,7 +41,7 @@ gboolean      e_cal_backend_mail_account_get_default
                                                 gchar **name);
 gboolean       e_cal_backend_mail_account_is_valid
                                                (ESourceRegistry *registry,
-                                                gchar *user,
+                                                const gchar *user,
                                                 gchar **name);
 gboolean       e_cal_backend_user_declined     (ESourceRegistry *registry,
                                                  icalcomponent *icalcomp);
diff --git a/src/libedataserver/e-source-mail-identity.c b/src/libedataserver/e-source-mail-identity.c
index 06cabf7..72bbd9c 100644
--- a/src/libedataserver/e-source-mail-identity.c
+++ b/src/libedataserver/e-source-mail-identity.c
@@ -35,9 +35,13 @@
  * ]|
  **/
 
-#include "e-source-mail-identity.h"
+#include "evolution-data-server-config.h"
+
+#include "camel/camel.h"
 
-#include <libedataserver/e-data-server-util.h>
+#include "e-data-server-util.h"
+
+#include "e-source-mail-identity.h"
 
 #define E_SOURCE_MAIL_IDENTITY_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
@@ -49,11 +53,13 @@ struct _ESourceMailIdentityPrivate {
        gchar *organization;
        gchar *reply_to;
        gchar *signature_uid;
+       gchar *aliases;
 };
 
 enum {
        PROP_0,
        PROP_ADDRESS,
+       PROP_ALIASES,
        PROP_NAME,
        PROP_ORGANIZATION,
        PROP_REPLY_TO,
@@ -78,6 +84,12 @@ source_mail_identity_set_property (GObject *object,
                                g_value_get_string (value));
                        return;
 
+               case PROP_ALIASES:
+                       e_source_mail_identity_set_aliases (
+                               E_SOURCE_MAIL_IDENTITY (object),
+                               g_value_get_string (value));
+                       return;
+
                case PROP_NAME:
                        e_source_mail_identity_set_name (
                                E_SOURCE_MAIL_IDENTITY (object),
@@ -120,6 +132,13 @@ source_mail_identity_get_property (GObject *object,
                                E_SOURCE_MAIL_IDENTITY (object)));
                        return;
 
+               case PROP_ALIASES:
+                       g_value_take_string (
+                               value,
+                               e_source_mail_identity_dup_aliases (
+                               E_SOURCE_MAIL_IDENTITY (object)));
+                       return;
+
                case PROP_NAME:
                        g_value_take_string (
                                value,
@@ -164,6 +183,7 @@ source_mail_identity_finalize (GObject *object)
        g_free (priv->organization);
        g_free (priv->reply_to);
        g_free (priv->signature_uid);
+       g_free (priv->aliases);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (e_source_mail_identity_parent_class)->finalize (object);
@@ -200,6 +220,19 @@ e_source_mail_identity_class_init (ESourceMailIdentityClass *class)
 
        g_object_class_install_property (
                object_class,
+               PROP_ALIASES,
+               g_param_spec_string (
+                       "aliases",
+                       "Aliases",
+                       "Sender's email address aliases",
+                       NULL,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_STATIC_STRINGS |
+                       E_SOURCE_PARAM_SETTING));
+
+       g_object_class_install_property (
+               object_class,
                PROP_NAME,
                g_param_spec_string (
                        "name",
@@ -684,3 +717,145 @@ e_source_mail_identity_set_signature_uid (ESourceMailIdentity *extension,
        g_object_notify (G_OBJECT (extension), "signature-uid");
 }
 
+/**
+ * e_source_mail_identity_get_aliases:
+ * @extension: an #ESourceMailIdentity
+ *
+ * Returns the email address aliases for this identity. These are comma-separated
+ * email addresses which may or may not contain also different name.
+ * This may be an empty string, but will never be %NULL.
+ * There can be used camel_address_decode() on a #CamelInternetAddress
+ * to decode the list of aliases.
+ *
+ * Returns: (transfer none): the sender's email address aliases
+ *
+ * Since: 3.24
+ **/
+const gchar *
+e_source_mail_identity_get_aliases (ESourceMailIdentity *extension)
+{
+       g_return_val_if_fail (E_IS_SOURCE_MAIL_IDENTITY (extension), NULL);
+
+       return extension->priv->aliases;
+}
+
+/**
+ * e_source_mail_identity_dup_aliases:
+ * @extension: an #ESourceMailIdentity
+ *
+ * Thread-safe variation of e_source_mail_identity_get_aliases().
+ * Use this function when accessing @extension from multiple threads.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: (transfer full): a newly-allocated copy of #ESourceMailIdentity:aliases
+ *
+ * Since: 3.24
+ **/
+gchar *
+e_source_mail_identity_dup_aliases (ESourceMailIdentity *extension)
+{
+       const gchar *protected;
+       gchar *duplicate;
+
+       g_return_val_if_fail (E_IS_SOURCE_MAIL_IDENTITY (extension), NULL);
+
+       e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+       protected = e_source_mail_identity_get_aliases (extension);
+       duplicate = g_strdup (protected);
+
+       e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+       return duplicate;
+}
+
+/**
+ * e_source_mail_identity_set_aliases:
+ * @extension: an #ESourceMailIdentity
+ * @aliases: (allow-none): the sender's email address aliases, or %NULL
+ *
+ * Sets the email address aliases for this identity. These are comma-separated
+ * email addresses which may or may not contain also different name.
+ *
+ * The internal copy of @aliases is automatically stripped of leading and
+ * trailing whitespace. If the resulting string is empty, %NULL is set
+ * instead.
+ *
+ * Since: 3.24
+ **/
+void
+e_source_mail_identity_set_aliases (ESourceMailIdentity *extension,
+                                    const gchar *aliases)
+{
+       g_return_if_fail (E_IS_SOURCE_MAIL_IDENTITY (extension));
+
+       e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+       if (g_strcmp0 (extension->priv->aliases, aliases) == 0) {
+               e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+               return;
+       }
+
+       g_free (extension->priv->aliases);
+       extension->priv->aliases = e_util_strdup_strip (aliases);
+
+       e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+       g_object_notify (G_OBJECT (extension), "aliases");
+}
+
+/**
+ * e_source_mail_identity_get_aliases_as_hash_table:
+ * @extension: an #ESourceMailIdentity
+ *
+ * Returns a set aliases as a hash table with address as key and
+ * name as value of the hash table. The name can be sometimes
+ * empty or NULL, thus rather use g_hash_table_contains() when
+ * checking for particular address. The addresses are
+ * compared case insensitively. The same addresses with a different
+ * name are included only once, the last variant of it. Use
+ * e_source_mail_identity_get_aliases() if you need more fine-grained
+ * control on the list of aliases.
+ *
+ * Returns: (transfer full): A newly created #GHashTable will
+ *   all the aliases. Returns %NULL if there are none set. Use
+ *   g_hash_table_destroy() to free the returned hash table.
+ *
+ * Since: 3.24
+ **/
+GHashTable *
+e_source_mail_identity_get_aliases_as_hash_table (ESourceMailIdentity *extension)
+{
+       GHashTable *aliases = NULL;
+
+       g_return_val_if_fail (E_IS_SOURCE_MAIL_IDENTITY (extension), NULL);
+
+       e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+       if (extension->priv->aliases && *extension->priv->aliases) {
+               CamelInternetAddress *inet_address;
+               gint ii, len;
+
+               inet_address = camel_internet_address_new ();
+               len = camel_address_decode (CAMEL_ADDRESS (inet_address), extension->priv->aliases);
+
+               if (len > 0) {
+                       aliases = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, 
g_free);
+
+                       for (ii = 0; ii < len; ii++) {
+                               const gchar *name = NULL, *address = NULL;
+
+                               if (camel_internet_address_get (inet_address, ii, &name, &address) && address 
&& *address) {
+                                       g_hash_table_insert (aliases, g_strdup (address), g_strdup (name));
+                               }
+                       }
+               }
+
+               g_clear_object (&inet_address);
+       }
+
+       e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+       return aliases;
+}
diff --git a/src/libedataserver/e-source-mail-identity.h b/src/libedataserver/e-source-mail-identity.h
index dd7c050..a919fc3 100644
--- a/src/libedataserver/e-source-mail-identity.h
+++ b/src/libedataserver/e-source-mail-identity.h
@@ -113,6 +113,15 @@ gchar *            e_source_mail_identity_dup_signature_uid
 void           e_source_mail_identity_set_signature_uid
                                        (ESourceMailIdentity *extension,
                                         const gchar *signature_uid);
+const gchar *  e_source_mail_identity_get_aliases
+                                       (ESourceMailIdentity *extension);
+gchar *                e_source_mail_identity_dup_aliases
+                                       (ESourceMailIdentity *extension);
+void           e_source_mail_identity_set_aliases
+                                       (ESourceMailIdentity *extension,
+                                        const gchar *aliases);
+GHashTable *   e_source_mail_identity_get_aliases_as_hash_table
+                                       (ESourceMailIdentity *extension);
 
 G_END_DECLS
 


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