2 * Copyright (C) 2010 Collabora Ltd.
4 * This library is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 2.1 of the License, or
7 * (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library. If not, see <http://www.gnu.org/licenses/>.
18 * Philip Withnall <philip.withnall@collabora.co.uk>
24 using Folks.Backends.Kf;
27 * A persona subclass which represents a single persona from a simple key file.
31 public class Folks.Backends.Kf.Persona : Folks.Persona,
35 private unowned GLib.KeyFile _key_file;
36 /* FIXME: As described in the IMable interface, we have to use
37 * GenericArray<string> here rather than just string[], as null-terminated
38 * arrays aren't supported as generic types. */
39 private HashTable<string, LinkedHashSet<string>> _im_addresses;
40 private string _alias;
41 private const string[] _linkable_properties = { "im-addresses" };
46 public override string[] linkable_properties
48 get { return this._linkable_properties; }
58 get { return this._alias; }
62 if (this._alias == value)
65 debug ("Setting alias of Kf.Persona '%s' to '%s'.", this.uid, value);
68 this._key_file.set_string (this.display_id, "__alias", value);
70 ((Kf.PersonaStore) this.store).save_key_file.begin ();
77 public HashTable<string, LinkedHashSet<string>> im_addresses
80 { return this._im_addresses; }
84 /* Remove the current IM addresses from the key file */
85 this._im_addresses.foreach ((protocol, v) =>
89 this._key_file.remove_key (this.display_id, protocol);
91 catch (KeyFileError e)
93 /* Ignore the error, since it's just a group or key not found
98 /* Add the new IM addresses to the key file and build a normalised
99 * table of them to set as the new property value */
100 HashTable<string, LinkedHashSet<string>> im_addresses =
101 new HashTable<string, LinkedHashSet<string>> (str_hash, str_equal);
103 value.foreach ((k, v) =>
105 unowned string protocol = (string) k;
106 unowned LinkedHashSet<string?> addresses =
107 (LinkedHashSet<string?>) v;
108 LinkedHashSet<string> normalized_addresses =
109 new LinkedHashSet<string> ();
111 foreach (string address in addresses)
113 string normalized_address;
116 normalized_address = IMable.normalise_im_address (
119 catch (IMableError e)
121 /* Somehow an error has crept into the user's
122 * relationships.ini. Warn of it and ignore the IM
128 normalized_addresses.add (normalized_address);
131 string[] addrs = (string[]) normalized_addresses.to_array ();
132 addrs.length = normalized_addresses.size;
134 this._key_file.set_string_list (this.display_id, protocol, addrs);
135 im_addresses.insert (protocol, normalized_addresses);
138 this._im_addresses = im_addresses;
140 /* Get the PersonaStore to save the key file */
141 ((Kf.PersonaStore) this.store).save_key_file.begin ();
146 * Create a new persona.
148 * Create a new persona for the {@link PersonaStore} `store`, representing
149 * the Persona given by the group `uid` in the key file `key_file`.
151 public Persona (KeyFile key_file, string id, Folks.PersonaStore store)
153 var iid = store.id + ":" + id;
154 var uid = this.build_uid ("key-file", store.id, id);
156 Object (display_id: id,
162 debug ("Adding key-file Persona '%s' (IID '%s', group '%s')", uid, iid,
165 this._key_file = key_file;
166 this._im_addresses = new HashTable<string, LinkedHashSet<string>> (
167 str_hash, str_equal);
169 /* Load the IM addresses from the key file */
172 var keys = this._key_file.get_keys (this.display_id);
173 foreach (unowned string key in keys)
176 if (key == "__alias")
178 this._alias = this._key_file.get_string (this.display_id,
180 debug (" Loaded alias '%s'.", this._alias);
185 unowned string protocol = key;
186 var im_addresses = this._key_file.get_string_list (
187 this.display_id, protocol);
189 var address_set = new LinkedHashSet<string> ();
191 foreach (var im_address in im_addresses)
196 address = IMable.normalise_im_address (im_address,
199 catch (IMableError e)
201 /* Warn of and ignore any invalid IM addresses */
205 address_set.add (address);
208 this._im_addresses.insert (protocol, address_set);
211 catch (KeyFileError e)
213 /* We get a GROUP_NOT_FOUND exception if we're creating a new
214 * Persona, since it doesn't yet exist in the key file. We shouldn't
215 * get any other exceptions, since we're iterating through a list of
216 * keys we've just retrieved. */
217 if (!(e is KeyFileError.GROUP_NOT_FOUND))
219 /* Translators: the parameter is an error message. */
220 warning (_("Couldn't load data from key file: %s"), e.message);
228 public override void linkable_property_to_links (string prop_name,
229 Folks.Persona.LinkablePropertyCallback callback)
231 if (prop_name == "im-addresses")
233 this.im_addresses.foreach ((k, v) =>
235 unowned string protocol = (string) k;
236 unowned LinkedHashSet<string> im_addresses =
237 (LinkedHashSet<string>) v;
239 foreach (string address in im_addresses)
240 callback (protocol + ":" + address);
246 base.linkable_property_to_links (prop_name, callback);