[folks] Bug 629311 — Folks should normalize IDs written to the writable backend



commit 0489968d1a76ccd296b8b60ce9862d822b3863ec
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Mon Sep 13 11:16:29 2010 +0100

    Bug 629311 â?? Folks should normalize IDs written to the writable backend
    
    Add a new IMable.normalise_im_address() method, which should be called on
    any IM address added to IMable.im_addresses, normalising it so that only the
    canonical version is used within libfolks. Closes: bgo#629311

 backends/key-file/kf-persona.vala       |   31 +++++++++---
 backends/telepathy/lib/tpf-persona.vala |    3 +-
 folks/imable.vala                       |   79 +++++++++++++++++++++++++++++++
 3 files changed, 105 insertions(+), 8 deletions(-)
---
diff --git a/backends/key-file/kf-persona.vala b/backends/key-file/kf-persona.vala
index 31416b0..199eac5 100644
--- a/backends/key-file/kf-persona.vala
+++ b/backends/key-file/kf-persona.vala
@@ -87,19 +87,33 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
                 }
             });
 
-          this._im_addresses = value;
+          /* Add the new IM addresses to the key file and build a normalised
+           * table of them to set as the new property value */
+          HashTable<string, GenericArray<string>> im_addresses =
+              new HashTable<string, GenericArray<string>> (str_hash, str_equal);
 
-          /* Add the new IM addresses to the key file */
-          this._im_addresses.foreach ((k, v) =>
+          value.foreach ((k, v) =>
             {
               unowned string protocol = (string) k;
-              unowned PtrArray addresses = (PtrArray) v;
-              unowned string[] _addresses = (string[]) addresses.pdata;
-              _addresses.length = (int) addresses.len;
+              unowned GenericArray<string> addresses = (GenericArray<string>) v;
+
+              for (int i = 0; i < addresses.length; i++)
+                {
+                  addresses[i] =
+                      IMable.normalise_im_address (addresses[i], protocol);
+                }
+
+              unowned string[] _addresses =
+                  (string[]) ((PtrArray) addresses).pdata;
+              _addresses.length = (int) addresses.length;
+
               this.key_file.set_string_list (this.display_id, protocol,
                   _addresses);
+              im_addresses.insert (protocol, addresses);
             });
 
+          this._im_addresses = im_addresses;
+
           /* Get the PersonaStore to save the key file */
           ((Kf.PersonaStore) this.store).save_key_file.begin ();
         }
@@ -157,8 +171,11 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
               GenericArray<string> im_address_array =
                   new GenericArray<string> ();
 
-              foreach (string address in im_addresses)
+              foreach (string _address in im_addresses)
                 {
+                  string address =
+                      IMable.normalise_im_address (_address, protocol);
+
                   if (!address_set.contains (address))
                     {
                       im_address_array.add (address);
diff --git a/backends/telepathy/lib/tpf-persona.vala b/backends/telepathy/lib/tpf-persona.vala
index 6ecff9b..58d60a6 100644
--- a/backends/telepathy/lib/tpf-persona.vala
+++ b/backends/telepathy/lib/tpf-persona.vala
@@ -225,7 +225,8 @@ public class Tpf.Persona : Folks.Persona,
 
       /* Set our single IM address */
       GenericArray<string> im_address_array = new GenericArray<string> ();
-      im_address_array.add (id);
+      im_address_array.add (IMable.normalise_im_address (id,
+          account.get_protocol ()));
 
       this._im_addresses =
           new HashTable<string, GenericArray<string>> (str_hash, str_equal);
diff --git a/folks/imable.vala b/folks/imable.vala
index 7b7668d..8a2149e 100644
--- a/folks/imable.vala
+++ b/folks/imable.vala
@@ -43,10 +43,89 @@ public interface Folks.IMable : Object
    * There must be no duplicate IM addresses in each ordered set, though a given
    * IM address may be present in the sets for different protocols.
    *
+   * All the IM addresses must be normalised using
+   * { link IMable.normalise_im_address} before being added to this property.
+   *
    * @since 0.1.13
    */
   public abstract HashTable<string, GenericArray<string>> im_addresses
     {
       get; set;
     }
+
+  /**
+   * Normalise an IM address so that it's suitable for string comparison.
+   *
+   * IM addresses for various protocols can be represented in different ways,
+   * only one of which is canonical. In order to allow simple string comparisons
+   * of IM addresses to work, the IM addresses must be normalised beforehand.
+   *
+   * @since 0.2.0
+   */
+  public static string normalise_im_address (string im_address, string protocol)
+    {
+      string normalised;
+
+      if (protocol == "aim" || protocol == "myspace")
+        {
+          normalised = im_address.replace (" ", "").down ();
+        }
+      else if (protocol == "irc" || protocol == "yahoo" ||
+          protocol == "yahoojp" || protocol == "groupwise")
+        {
+          normalised = im_address.down ();
+        }
+      else if (protocol == "jabber")
+        {
+          /* Parse the JID */
+          string[] parts = im_address.split ("/", 2);
+
+          return_val_if_fail (parts.length >= 1, null);
+
+          string resource = null;
+          if (parts.length == 2)
+            resource = parts[1];
+
+          parts = parts[0].split ("@", 2);
+
+          return_val_if_fail (parts.length >= 1, null);
+
+          string node, domain;
+          if (parts.length == 2)
+            {
+              node = parts[0];
+              domain = parts[1];
+            }
+          else
+            {
+              node = null;
+              domain = parts[0];
+            }
+
+          return_val_if_fail (node == null || node != "", null);
+          return_val_if_fail (domain != null && domain != "", null);
+          return_val_if_fail (resource == null || resource != "", null);
+
+          domain = domain.down ();
+          if (node != null)
+            node = node.down ();
+
+          /* Build a new JID */
+          if (node != null && resource != null)
+            normalised = "%s %s/%s".printf (node, domain, resource);
+          else if (node != null)
+            normalised = "%s %s".printf (node, domain);
+          else if (resource != null)
+            normalised = "%s/%s".printf (domain, resource);
+          else
+            assert_not_reached ();
+        }
+      else
+        {
+          /* Fallback */
+          normalised = im_address;
+        }
+
+      return normalised.normalize ();
+    }
 }



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