[folks] linking: add interface for linkable web service contact UIDs
- From: Alban Crequy <albanc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] linking: add interface for linkable web service contact UIDs
- Date: Thu, 7 Apr 2011 17:47:35 +0000 (UTC)
commit 4a775a4a5092558ed28a8cd92a341e55beffbec2
Author: Alban Crequy <alban crequy collabora co uk>
Date: Tue Mar 29 19:13:19 2011 +0100
linking: add interface for linkable web service contact UIDs
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=644867
backends/key-file/kf-persona-store.vala | 18 +++++-
backends/key-file/kf-persona.vala | 94 +++++++++++++++++++++++++++-
backends/libsocialweb/lib/swf-persona.vala | 37 +++++++++--
folks/Makefile.am | 1 +
folks/individual-aggregator.vala | 68 ++++++++++++++------
folks/individual.vala | 55 ++++++++++++++++-
folks/persona-store.vala | 2 +
folks/web-service-details.vala | 49 ++++++++++++++
8 files changed, 293 insertions(+), 31 deletions(-)
---
diff --git a/backends/key-file/kf-persona-store.vala b/backends/key-file/kf-persona-store.vala
index d4c69dc..e3660ad 100644
--- a/backends/key-file/kf-persona-store.vala
+++ b/backends/key-file/kf-persona-store.vala
@@ -20,6 +20,7 @@
*/
using GLib;
+using Gee;
using Folks;
using Folks.Backends.Kf;
@@ -290,6 +291,7 @@ public class Folks.Backends.Kf.PersonaStore : Folks.PersonaStore
*
* Accepted keys for `details` are:
* - PersonaStore.detail_key (PersonaDetail.IM_ADDRESSES)
+ * - PersonaStore.detail_key (PersonaDetail.WEB_SERVICE_ADDRESSES)
*
* See { link Folks.PersonaStore.add_persona_from_details}.
*/
@@ -300,8 +302,15 @@ public class Folks.Backends.Kf.PersonaStore : Folks.PersonaStore
PersonaDetail.IM_ADDRESSES));
unowned HashTable<string, LinkedHashSet<string>> im_addresses =
(HashTable<string, LinkedHashSet<string>>) val.get_boxed ();
-
- if (im_addresses == null || im_addresses.size () == 0)
+ val = details.lookup (this.detail_key (PersonaDetail.WEB_SERVICE_ADDRESSES));
+ unowned HashMap<string, LinkedHashSet<string>> web_service_addresses =
+ (HashMap<string, LinkedHashSet<string>>) val.get_object ();
+ uint im_addresses_size = (im_addresses == null)
+ ? 0 : im_addresses.size ();
+ uint web_service_addresses_size = (web_service_addresses == null)
+ ? 0 : web_service_addresses.size;
+
+ if (im_addresses_size + web_service_addresses_size == 0)
{
throw new PersonaStoreError.INVALID_ARGUMENT (
/* Translators: the first two parameters are identifiers for the
@@ -325,11 +334,14 @@ public class Folks.Backends.Kf.PersonaStore : Folks.PersonaStore
}
while (this._key_file.has_group (persona_id) == true);
- /* Create a new persona and set its im-addresses property to update the
+ /* Create a new persona and set its addresses property to update the
* key file */
Persona persona = new Kf.Persona (this._key_file, persona_id, this);
this._personas.insert (persona.iid, persona);
- persona.im_addresses = im_addresses;
+ if (im_addresses_size > 0)
+ persona.im_addresses = im_addresses;
+ if (web_service_addresses_size > 0)
+ persona.web_service_addresses = web_service_addresses;
/* FIXME: GroupDetails.ChangeReason is not the right enum to use here */
GLib.List<Persona> personas = new GLib.List<Persona> ();
diff --git a/backends/key-file/kf-persona.vala b/backends/key-file/kf-persona.vala
index 5bd9177..bc78b7e 100644
--- a/backends/key-file/kf-persona.vala
+++ b/backends/key-file/kf-persona.vala
@@ -37,8 +37,13 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
* GenericArray<string> here rather than just string[], as null-terminated
* arrays aren't supported as generic types. */
private HashTable<string, LinkedHashSet<string>> _im_addresses;
+ private HashMap<string, LinkedHashSet<string>> _web_service_addresses;
private string _alias;
- private const string[] _linkable_properties = { "im-addresses" };
+ private const string[] _linkable_properties =
+ {
+ "im-addresses",
+ "web-service-addresses"
+ };
/**
* { inheritDoc}
@@ -143,6 +148,56 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
}
/**
+ * { inheritDoc}
+ */
+ public HashMap<string, LinkedHashSet<string>> web_service_addresses
+ {
+ get
+ { return this._web_service_addresses; }
+
+ set
+ {
+ /* Remove the current web service addresses from the key file */
+ foreach (var web_service in this._web_service_addresses.keys)
+ {
+ try
+ {
+ this._key_file.remove_key (this.display_id, "web-service." + web_service);
+ }
+ catch (KeyFileError e)
+ {
+ /* Ignore the error, since it's just a group or key not found
+ * error. */
+ }
+ }
+
+ /* Add the new web service addresses to the key file and build a
+ * table of them to set as the new property value */
+ HashMap<string, LinkedHashSet<string>> web_service_addresses =
+ new HashMap<string, LinkedHashSet<string>> (str_hash, str_equal);
+
+ foreach (var entry in value.entries)
+ {
+ unowned string web_service = (string) entry.key;
+ unowned LinkedHashSet<string?> addresses =
+ (LinkedHashSet<string?>) entry.value;
+
+ string[] addrs = (string[]) addresses.to_array ();
+ addrs.length = addresses.size;
+
+ this._key_file.set_string_list (this.display_id,
+ "web-service." + web_service, addrs);
+ web_service_addresses.set (web_service, addresses);
+ }
+
+ this._web_service_addresses = web_service_addresses;
+
+ /* Get the PersonaStore to save the key file */
+ ((Kf.PersonaStore) this.store).save_key_file.begin ();
+ }
+ }
+
+ /**
* Create a new persona.
*
* Create a new persona for the { link PersonaStore} `store`, representing
@@ -165,6 +220,9 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
this._key_file = key_file;
this._im_addresses = new HashTable<string, LinkedHashSet<string>> (
str_hash, str_equal);
+ this._web_service_addresses
+ = new HashMap<string, LinkedHashSet<string>> (str_hash,
+ str_equal);
/* Load the IM addresses from the key file */
try
@@ -181,6 +239,26 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
continue;
}
+ /* Web service addresses */
+ var decomposed_key = key.split(".", 2);
+ if (decomposed_key.length == 2 &&
+ decomposed_key[0] == "web-service")
+ {
+ unowned string web_service = decomposed_key[1];
+ var web_service_addresses = this._key_file.get_string_list (
+ this.display_id, web_service);
+
+ var address_set = new LinkedHashSet<string> ();
+
+ foreach (var web_service_address in web_service_addresses)
+ {
+ address_set.add (web_service_address);
+ }
+
+ this._web_service_addresses.set (web_service, address_set);
+ continue;
+ }
+
/* IM addresses */
unowned string protocol = key;
var im_addresses = this._key_file.get_string_list (
@@ -202,7 +280,7 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
warning (e.message);
continue;
}
- address_set.add (address);
+ address_set.add (address);
}
this._im_addresses.insert (protocol, address_set);
@@ -240,6 +318,18 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
callback (protocol + ":" + address);
});
}
+ else if (prop_name == "web-service-addresses")
+ {
+ foreach (var entry in this.web_service_addresses.entries)
+ {
+ unowned string web_service = (string) entry.key;
+ unowned LinkedHashSet<string> web_service_addresses =
+ (LinkedHashSet<string>) entry.value;
+
+ foreach (string address in web_service_addresses)
+ callback (web_service + ":" + address);
+ }
+ }
else
{
/* Chain up */
diff --git a/backends/libsocialweb/lib/swf-persona.vala b/backends/libsocialweb/lib/swf-persona.vala
index 0244e46..270f097 100644
--- a/backends/libsocialweb/lib/swf-persona.vala
+++ b/backends/libsocialweb/lib/swf-persona.vala
@@ -20,6 +20,7 @@
*/
using GLib;
+using Gee;
using Folks;
using SocialWebClient;
@@ -31,9 +32,14 @@ public class Swf.Persona : Folks.Persona,
GenderDetails,
ImDetails,
NameDetails,
- UrlDetails
+ UrlDetails,
+ WebServiceDetails
{
- private const string[] _linkable_properties = {};
+ private const string[] _linkable_properties =
+ {
+ "im-addresses",
+ "web-service-addresses"
+ };
/**
* The names of the Persona's linkable properties.
@@ -73,16 +79,16 @@ public class Swf.Persona : Folks.Persona,
*/
public Gender gender { get; private set; }
- private List<FieldDetails> _urls;
+ private GLib.List<FieldDetails> _urls;
/**
* { inheritDoc}
*/
- public List<FieldDetails> urls
+ public GLib.List<FieldDetails> urls
{
get { return this._urls; }
private set
{
- this._urls = new List<FieldDetails> ();
+ this._urls = new GLib.List<FieldDetails> ();
foreach (unowned FieldDetails ps in value)
this._urls.prepend (ps);
this._urls.reverse ();
@@ -91,6 +97,10 @@ public class Swf.Persona : Folks.Persona,
private HashTable<string, LinkedHashSet<string>> _im_addresses =
new HashTable<string, LinkedHashSet<string>> (str_hash, str_equal);
+
+ private HashMap<string, LinkedHashSet<string>> _web_service_addresses =
+ new HashMap<string, LinkedHashSet<string>> (str_hash, str_equal);
+
/**
* { inheritDoc}
*/
@@ -101,6 +111,15 @@ public class Swf.Persona : Folks.Persona,
}
/**
+ * { inheritDoc}
+ */
+ public HashMap<string, LinkedHashSet<string>> web_service_addresses
+ {
+ get { return this._web_service_addresses; }
+ private set {}
+ }
+
+ /**
* Build the Facebook JID.
*
* @param store_id the { link PersonaStore.id}
@@ -158,6 +177,7 @@ public class Swf.Persona : Folks.Persona,
public Persona (PersonaStore store, Contact contact)
{
var id = get_contact_id (contact);
+ var service = contact.service.dup();
var uid = this.build_uid (BACKEND_NAME, store.id, id);
var iid = this._build_iid (store.id, id);
@@ -192,6 +212,11 @@ public class Swf.Persona : Folks.Persona,
}
}
+ var web_service_address_array = new LinkedHashSet<string> ();
+ web_service_address_array.add (id);
+ this._web_service_addresses.set ((owned) service,
+ (owned) web_service_address_array);
+
update (contact);
}
@@ -233,7 +258,7 @@ public class Swf.Persona : Folks.Persona,
if (this.full_name != full_name)
this.full_name = full_name;
- var urls = new List<FieldDetails> ();
+ var urls = new GLib.List<FieldDetails> ();
var website = contact.get_value ("url");
if (website != null)
diff --git a/folks/Makefile.am b/folks/Makefile.am
index 4013118..6e8fb89 100644
--- a/folks/Makefile.am
+++ b/folks/Makefile.am
@@ -22,6 +22,7 @@ libfolks_la_SOURCES = \
field-details.vala \
gender-details.vala \
group-details.vala \
+ web-service-details.vala \
im-details.vala \
name-details.vala \
note-details.vala \
diff --git a/folks/individual-aggregator.vala b/folks/individual-aggregator.vala
index c1f3ebf..e3c0332 100644
--- a/folks/individual-aggregator.vala
+++ b/folks/individual-aggregator.vala
@@ -909,36 +909,66 @@ public class Folks.IndividualAggregator : Object
/* `protocols_addrs_set` will be passed to the new Kf.Persona */
var protocols_addrs_set =
new HashTable<string, LinkedHashSet<string>> (str_hash, str_equal);
+ var web_service_addrs_set =
+ new HashMap<string, LinkedHashSet<string>> (str_hash, str_equal);
foreach (var persona in personas)
{
- if (!(persona is ImDetails))
- continue;
-
- ((ImDetails) persona).im_addresses.foreach ((k, v) =>
+ if (persona is ImDetails)
{
- unowned string protocol = (string) k;
- unowned LinkedHashSet<string> addresses =
- (LinkedHashSet<string>) v;
-
- var address_set = protocols_addrs_set.lookup (protocol);
-
- if (address_set == null)
+ ((ImDetails) persona).im_addresses.foreach ((k, v) =>
{
- address_set = new LinkedHashSet<string> ();
+ unowned string protocol = (string) k;
+ unowned LinkedHashSet<string> addresses =
+ (LinkedHashSet<string>) v;
+
+ var address_set = protocols_addrs_set.lookup (protocol);
+
+ if (address_set == null)
+ {
+ address_set = new LinkedHashSet<string> ();
+
+ protocols_addrs_set.insert (protocol, address_set);
+ }
+
+ address_set.add_all (addresses);
+ });
+ }
- protocols_addrs_set.insert (protocol, address_set);
+ if (persona is WebServiceDetails)
+ {
+ foreach (var entry in
+ ((WebServiceDetails) persona).web_service_addresses.entries)
+ {
+ unowned string web_service = (string) entry.key;
+ unowned LinkedHashSet<string> addresses =
+ (LinkedHashSet<string>) entry.value;
+
+ var address_set = web_service_addrs_set.get (web_service);
+
+ if (address_set == null)
+ {
+ address_set = new LinkedHashSet<string> ();
+
+ web_service_addrs_set.set (web_service, address_set);
+ }
+
+ address_set.add_all (addresses);
}
-
- address_set.add_all (addresses);
- });
+ }
}
- var addresses_value = Value (typeof (HashTable));
- addresses_value.set_boxed (protocols_addrs_set);
+ var im_addresses_value = Value (typeof (HashTable));
+ im_addresses_value.set_boxed (protocols_addrs_set);
+
+ var web_service_addresses_value = Value (typeof (HashMap));
+ web_service_addresses_value.set_object (web_service_addrs_set);
var details = new HashTable<string, Value?> (str_hash, str_equal);
- details.insert ("im-addresses", addresses_value);
+ details.insert (PersonaStore.detail_key (PersonaDetail.IM_ADDRESSES),
+ im_addresses_value);
+ details.insert (PersonaStore.detail_key
+ (PersonaDetail.WEB_SERVICE_ADDRESSES), web_service_addresses_value);
yield this.add_persona_from_details (null, this._writeable_store,
details);
diff --git a/folks/individual.vala b/folks/individual.vala
index 39e3067..6f60940 100644
--- a/folks/individual.vala
+++ b/folks/individual.vala
@@ -77,7 +77,8 @@ public class Folks.Individual : Object,
PhoneDetails,
PostalAddressDetails,
RoleDetails,
- UrlDetails
+ UrlDetails,
+ WebServiceDetails
{
private bool _is_favourite;
private string _alias;
@@ -98,6 +99,7 @@ public class Folks.Individual : Object,
* Persona.is_user == true. Iff this is > 0, Individual.is_user == true. */
private uint _persona_user_count = 0;
private HashTable<string, LinkedHashSet<string>> _im_addresses;
+ private HashMap<string, LinkedHashSet<string>> _web_service_addresses;
/**
* The trust level of the Individual.
@@ -410,6 +412,15 @@ public class Folks.Individual : Object,
}
/**
+ * { inheritDoc}
+ */
+ public HashMap<string, LinkedHashSet<string>> web_service_addresses
+ {
+ get { return this._web_service_addresses; }
+ private set {}
+ }
+
+ /**
* The set of { link Persona}s encapsulated by this Individual.
*
* Changing the set of personas may cause updates to the aggregated properties
@@ -544,6 +555,11 @@ public class Folks.Individual : Object,
this._update_im_addresses ();
}
+ private void _notify_web_service_addresses_cb (Object obj, ParamSpec ps)
+ {
+ this._update_web_service_addresses ();
+ }
+
private void _notify_is_favourite_cb (Object obj, ParamSpec ps)
{
this._update_is_favourite ();
@@ -564,6 +580,8 @@ public class Folks.Individual : Object,
{
this._im_addresses =
new HashTable<string, LinkedHashSet<string>> (str_hash, str_equal);
+ this._web_service_addresses =
+ new HashMap<string, LinkedHashSet<string>> (str_hash, str_equal);
this._persona_set = new HashSet<Persona> (null, null);
this._stores = new HashMap<PersonaStore, uint> (null, null);
this._gender = Gender.UNSPECIFIED;
@@ -638,6 +656,7 @@ public class Folks.Individual : Object,
this._update_alias ();
this._update_trust_level ();
this._update_im_addresses ();
+ this._update_web_service_addresses ();
this._update_structured_name ();
this._update_full_name ();
this._update_nickname ();
@@ -914,6 +933,36 @@ public class Folks.Individual : Object,
this.notify_property ("im-addresses");
}
+ private void _update_web_service_addresses ()
+ {
+ /* populate the web service addresses as the union of our Personas' addresses */
+ foreach (var persona in this.personas)
+ {
+ if (persona is WebServiceDetails)
+ {
+ var web_service_details = (WebServiceDetails) persona;
+ foreach (var entry in
+ web_service_details.web_service_addresses.entries)
+ {
+ var cur_web_service = (string) entry.key;
+ var cur_addresses = (LinkedHashSet<string>) entry.value;
+ var web_service_set = this._web_service_addresses.get
+ (cur_web_service);
+
+ if (web_service_set == null)
+ {
+ web_service_set = new LinkedHashSet<string> ();
+ this._web_service_addresses.set (cur_web_service,
+ web_service_set);
+ }
+
+ web_service_set.add_all (cur_addresses);
+ }
+ }
+ }
+ this.notify_property ("web-service-addresses");
+ }
+
private void _connect_to_persona (Persona persona)
{
persona.notify["alias"].connect (this._notify_alias_cb);
@@ -921,6 +970,8 @@ public class Folks.Individual : Object,
persona.notify["presence-message"].connect (this._notify_presence_cb);
persona.notify["presence-type"].connect (this._notify_presence_cb);
persona.notify["im-addresses"].connect (this._notify_im_addresses_cb);
+ persona.notify["web-service-addresses"].connect
+ (this._notify_web_service_addresses_cb);
persona.notify["is-favourite"].connect (this._notify_is_favourite_cb);
persona.notify["structured-name"].connect (
this._notify_structured_name_cb);
@@ -1021,6 +1072,8 @@ public class Folks.Individual : Object,
persona.notify["presence-type"].disconnect (this._notify_presence_cb);
persona.notify["im-addresses"].disconnect (
this._notify_im_addresses_cb);
+ persona.notify["web-service-addresses"].disconnect (
+ this._notify_web_service_addresses_cb);
persona.notify["is-favourite"].disconnect (
this._notify_is_favourite_cb);
persona.notify["structured-name"].disconnect (
diff --git a/folks/persona-store.vala b/folks/persona-store.vala
index 38e68f9..bc392e6 100644
--- a/folks/persona-store.vala
+++ b/folks/persona-store.vala
@@ -117,6 +117,7 @@ public enum Folks.PersonaDetail
GENDER,
EMAIL_ADDRESSES,
IM_ADDRESSES,
+ WEB_SERVICE_ADDRESSES,
NOTES,
PHONE_NUMBERS,
POSTAL_ADDRESSES,
@@ -158,6 +159,7 @@ public abstract class Folks.PersonaStore : Object
"gender",
"email-addresses",
"im-addresses",
+ "web-service-addresses",
"notes",
"phone-numbers",
"postal-addresses",
diff --git a/folks/web-service-details.vala b/folks/web-service-details.vala
new file mode 100644
index 0000000..3afe19f
--- /dev/null
+++ b/folks/web-service-details.vala
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alban Crequy <alban crequy collabora co uk>
+ */
+
+using Gee;
+
+/**
+ * web service addresses exposed by an object implementing
+ * { link PresenceDetails}.
+ *
+ * @since UNRELEASED
+ */
+public interface Folks.WebServiceDetails : Object
+{
+ /**
+ * A mapping of web service to an ordered set of web service addresses.
+ *
+ * Each mapping is from an arbitrary web service identifier to a set of web
+ * service addresses for the contact, listed in preference order.
+ * The most-preferred web service address for each web service comes first
+ * in that web service's list.
+ *
+ * Web service addresses are guaranteed to be unique per web service, but
+ * not necessarily unique amongst all web services.
+ *
+ * @since UNRELEASED
+ */
+ public abstract Gee.HashMap<string, LinkedHashSet<string>>
+ web_service_addresses
+ {
+ get; set;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]