From 0489968d1a76ccd296b8b60ce9862d822b3863ec Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 13 Sep 2010 11:16:29 +0100 Subject: [PATCH] =?utf8?q?Bug=20629311=20=E2=80=94=20Folks=20should=20norm?= =?utf8?q?alize=20IDs=20written=20to=20the=20writable=20backend?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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> im_addresses = + new HashTable> (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 addresses = (GenericArray) 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 im_address_array = new GenericArray (); - 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 im_address_array = new GenericArray (); - im_address_array.add (id); + im_address_array.add (IMable.normalise_im_address (id, + account.get_protocol ())); this._im_addresses = new HashTable> (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> 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 (); + } } -- 2.7.4