[folks] Write support for URLs in Edsf.Persona
- From: Travis Reitter <treitter src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] Write support for URLs in Edsf.Persona
- Date: Sat, 13 Aug 2011 16:59:40 +0000 (UTC)
commit f4f596bddedcc64670be03ec2ffa46e0d142a720
Author: Travis Reitter <travis reitter collabora co uk>
Date: Sat Aug 13 12:33:39 2011 +0200
Write support for URLs in Edsf.Persona
Closes: bgo#655609 - Implement setter for URLs
NEWS | 1 +
backends/eds/lib/edsf-persona-store.vala | 92 ++++++++++++++
backends/eds/lib/edsf-persona.vala | 39 ++++++-
folks/utils.vala | 38 ++++++
tests/eds/Makefile.am | 6 +
tests/eds/set-urls.vala | 197 ++++++++++++++++++++++++++++++
6 files changed, 370 insertions(+), 3 deletions(-)
---
diff --git a/NEWS b/NEWS
index 7e5bce9..a52fd91 100644
--- a/NEWS
+++ b/NEWS
@@ -47,6 +47,7 @@ Bugs fixed:
parameters
* Bug 655922 â Rebase UrlDetails.urls upon an AbstractFieldDetails-derived class
* Bug 648818 â Support the EDS backend being a primary
+* Bug 655609 â Implement setter for URLs
API changes:
* Swf.Persona retains and exposes its libsocialweb Contact
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index 9234f27..1de7ea3 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -214,6 +214,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
* - PersonaStore.detail_key (PersonaDetail.LOCAL_IDS)
* - PersonaDetail.detail_key (PersonaDetail.WEB_SERVICE_ADDRESSES)
* - PersonaStore.detail_key (PersonaDetail.NOTES)
+ * - PersonaStore.detail_key (PersonaDetail.URL)
*
* See { link Folks.PersonaStore.add_persona_from_details}.
*
@@ -299,6 +300,11 @@ public class Edsf.PersonaStore : Folks.PersonaStore
var gender = (Gender) v.get_enum ();
yield this._set_contact_gender (contact, gender);
}
+ else if (k == Folks.PersonaStore.detail_key (PersonaDetail.URLS))
+ {
+ Set<UrlFieldDetails> urls = (Set<UrlFieldDetails>) v.get_object ();
+ yield this._set_contact_urls (contact, urls);
+ }
}
Edsf.Persona? persona = null;
@@ -710,6 +716,92 @@ public class Edsf.PersonaStore : Folks.PersonaStore
contact.add_attribute (attr_n);
}
+ internal async void _set_urls (Edsf.Persona persona,
+ Set<UrlFieldDetails> urls)
+ {
+ if (Utils.set_afd_equal (persona.urls, urls))
+ return;
+
+ try
+ {
+ E.Contact contact = ((Edsf.Persona) persona).contact;
+ yield this._set_contact_urls (contact, urls);
+ yield this._addressbook.modify_contact (contact);
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Can't set urls: %s", e.message);
+ }
+ }
+
+ private async void _set_contact_urls (E.Contact contact,
+ Set<UrlFieldDetails> urls)
+ {
+ var vcard = (E.VCard) contact;
+ vcard.remove_attributes (null, "X-URIS");
+
+ foreach (var u in urls)
+ {
+ bool homepage = false;
+ bool blog = false;
+ bool fburl = false;
+ bool video = false;
+
+ var attr = new E.VCardAttribute (null, "X-URIS");
+ attr.add_value (u.value);
+ foreach (var param_name in u.parameters.get_keys ())
+ {
+ var param = new E.VCardAttributeParam (param_name.up ());
+ foreach (var param_val in u.parameters.get (param_name))
+ {
+ if (param_name == "type")
+ {
+ /* Keep in sync with Edsf.Persona.url_properties */
+ if (param_val == "homepage_url")
+ {
+ homepage = true;
+ }
+ else if (param_val == "blog_url")
+ {
+ blog = true;
+ }
+ else if (param_val == "fburl")
+ {
+ fburl = true;
+ }
+ else if (param_val == "video_url")
+ {
+ video = true;
+ }
+ }
+ param.add_value (param_val);
+ }
+ attr.add_param (param);
+ }
+
+ if (homepage)
+ {
+ contact.set (E.Contact.field_id ("homepage_url"), u.value);
+ }
+ else if (blog)
+ {
+ contact.set (E.Contact.field_id ("blog_url"), u.value);
+ }
+ else if (fburl)
+ {
+ contact.set (E.Contact.field_id ("fburl"), u.value);
+ }
+ else if (video)
+ {
+ contact.set (E.Contact.field_id ("video_url"), u.value);
+ }
+ else
+ {
+ contact.add_attribute (attr);
+ }
+ }
+ }
+
internal async void _set_local_ids (Edsf.Persona persona,
Set<string> local_ids)
{
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index 523a016..cf3330c 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -349,7 +349,7 @@ public class Edsf.Persona : Folks.Persona,
get { return this._urls_ro; }
set
{
- GLib.warning ("Urls setting not supported yet\n");
+ ((Edsf.PersonaStore) this.store)._set_urls (this, value);
}
}
@@ -802,17 +802,50 @@ public class Edsf.Persona : Folks.Persona,
private void _update_urls ()
{
this._urls.clear ();
+ var urls_temp = new HashSet<UrlFieldDetails> ();
+ /* First we get the standard Evo urls.. */
foreach (string url_property in this.url_properties)
{
string u = (string) this._get_property (url_property);
if (u != null && u != "")
{
- this._urls.add (new UrlFieldDetails (u));
+ var fd_u = new UrlFieldDetails (u);
+ fd_u.set_parameter("type", url_property);
+ urls_temp.add (fd_u);
}
}
- this.notify_property ("urls");
+ /* Now we go for extra URLs */
+ var vcard = (E.VCard) this.contact;
+ foreach (unowned E.VCardAttribute attr in vcard.get_attributes ())
+ {
+ if (attr.get_name () == "X-URIS")
+ {
+ var url_fd = new UrlFieldDetails (attr.get_value ());
+ foreach (var param in attr.get_params ())
+ {
+ string param_name = param.get_name ().down ();
+ foreach (var param_value in param.get_values ())
+ {
+ url_fd.add_parameter (param_name, param_value);
+ }
+ }
+ urls_temp.add (url_fd);
+ }
+ }
+
+ if (!Utils.set_afd_equal (urls_temp, this._urls))
+ {
+ this._urls.clear ();
+
+ foreach (var url_fd in urls_temp)
+ {
+ this._urls.add (url_fd);
+ }
+
+ this.notify_property ("urls");
+ }
}
private void _update_im_addresses ()
diff --git a/folks/utils.vala b/folks/utils.vala
index ccf69ce..318c722 100644
--- a/folks/utils.vala
+++ b/folks/utils.vala
@@ -127,4 +127,42 @@ public class Folks.Utils : Object
return true;
}
+
+ /**
+ * Check whether a set of strings to AbstractFieldDetails are equal.
+ *
+ * This performs a deep check for equality, checking whether both sets are of
+ * the same size, and that each key maps to the same set of values in both
+ * maps.
+ *
+ * @param a a set to compare
+ * @param b another set to compare
+ * @return `true` if the sets are equal, `false` otherwise
+ *
+ * @since UNRELEASED
+ */
+ public static bool set_afd_equal (
+ Set<AbstractFieldDetails> a,
+ Set<AbstractFieldDetails> b)
+ {
+ if (a == b)
+ return true;
+
+ if (a.size == b.size)
+ {
+ foreach (var val in a)
+ {
+ if (!b.contains (val))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/tests/eds/Makefile.am b/tests/eds/Makefile.am
index ec0f530..d5db601 100644
--- a/tests/eds/Makefile.am
+++ b/tests/eds/Makefile.am
@@ -66,6 +66,7 @@ noinst_PROGRAMS = \
set-notes \
add-contacts-stress-test \
set-gender \
+ set-urls \
$(NULL)
RUN_WITH_PRIVATE_BUS = $(top_srcdir)/tests/tools/with-session-bus-eds.sh
@@ -176,6 +177,10 @@ set_gender_SOURCES = \
set-gender.vala \
$(NULL)
+set_urls_SOURCES = \
+ set-urls.vala \
+ $(NULL)
+
CLEANFILES = \
*.pid \
*.address \
@@ -207,6 +212,7 @@ MAINTAINERCLEANFILES = \
set_notes_vala.stamp \
add_contacts_stress_test_vala.stamp \
set_gender_vala.stamp \
+ set_urls_vala.stamp \
$(NULL)
EXTRA_DIST = \
diff --git a/tests/eds/set-urls.vala b/tests/eds/set-urls.vala
new file mode 100644
index 0000000..7af273d
--- /dev/null
+++ b/tests/eds/set-urls.vala
@@ -0,0 +1,197 @@
+/*
+ * 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: Raul Gutierrez Segales <raul gutierrez segales collabora co uk>
+ *
+ */
+
+using EdsTest;
+using Folks;
+using Gee;
+
+public class SetUrlsTests : Folks.TestCase
+{
+ private EdsTest.Backend _eds_backend;
+ private IndividualAggregator _aggregator;
+ private GLib.MainLoop _main_loop;
+ private bool _found_before_update;
+ private bool _found_url_extra_1;
+ private bool _found_url_extra_2;
+ private bool _found_url_home;
+ private bool _found_url_blog;
+ private string _url_extra_1 = "http://example.org";
+ private string _url_extra_2 = "http://extra.example.org";
+ private string _url_home = "http://home.example.org";
+ private string _url_blog = "http://blog.example.org";
+
+
+ public SetUrlsTests ()
+ {
+ base ("SetUrls");
+
+ this._eds_backend = new EdsTest.Backend ();
+
+ this.add_test ("setting urls on e-d-s persona",
+ this.test_set_urls);
+ }
+
+ public override void set_up ()
+ {
+ this._eds_backend.set_up ();
+ }
+
+ public override void tear_down ()
+ {
+ this._eds_backend.tear_down ();
+ }
+
+ void test_set_urls ()
+ {
+ Gee.HashMap<string, Value?> c1 = new Gee.HashMap<string, Value?> ();
+ this._main_loop = new GLib.MainLoop (null, false);
+ Value? v;
+
+ this._found_before_update = false;
+ this._found_url_extra_1 = false;
+ this._found_url_extra_2 = false;
+ this._found_url_home = false;
+ this._found_url_blog = false;
+
+ this._eds_backend.reset ();
+
+ v = Value (typeof (string));
+ v.set_string ("Albus Percival Wulfric Brian Dumbledore");
+ c1.set ("full_name", (owned) v);
+ this._eds_backend.add_contact (c1);
+
+ this._test_set_urls_async ();
+
+ Timeout.add_seconds (5, () => {
+ this._main_loop.quit ();
+ assert_not_reached ();
+ });
+
+ this._main_loop.run ();
+
+ assert (this._found_before_update);
+ assert (this._found_url_extra_1);
+ assert (this._found_url_extra_2);
+ assert (this._found_url_home);
+ assert (this._found_url_blog);
+ }
+
+ private async void _test_set_urls_async ()
+ {
+ yield this._eds_backend.commit_contacts_to_addressbook ();
+
+ var store = BackendStore.dup ();
+ yield store.prepare ();
+ this._aggregator = new IndividualAggregator ();
+ this._aggregator.individuals_changed.connect
+ (this._individuals_changed_cb);
+ try
+ {
+ yield this._aggregator.prepare ();
+ }
+ catch (GLib.Error e)
+ {
+ GLib.warning ("Error when calling prepare: %s\n", e.message);
+ }
+ }
+
+ private void _individuals_changed_cb
+ (Set<Individual> added,
+ Set<Individual> removed,
+ string? message,
+ Persona? actor,
+ GroupDetails.ChangeReason reason)
+ {
+ assert (removed.size == 0);
+
+ foreach (Individual i in added)
+ {
+ var name = (Folks.NameDetails) i;
+
+ if (name.full_name == "Albus Percival Wulfric Brian Dumbledore")
+ {
+ i.notify["urls"].connect (this._notify_urls_cb);
+ this._found_before_update = true;
+
+ foreach (var p in i.personas)
+ {
+ var urls = new HashSet<UrlFieldDetails> ();
+
+ var p1 = new UrlFieldDetails (this._url_extra_1);
+ urls.add (p1);
+ var p2 = new UrlFieldDetails (this._url_extra_2);
+ urls.add (p2);
+ var p3 = new UrlFieldDetails (this._url_home);
+ p3.set_parameter("type", "homepage_url");
+ urls.add (p3);
+ var p4 = new UrlFieldDetails (this._url_blog);
+ p4.set_parameter("type", "blog_url");
+ urls.add (p4);
+
+ ((UrlDetails) p).urls = urls;
+ }
+ }
+ }
+ }
+
+ private void _notify_urls_cb (Object individual_obj, ParamSpec ps)
+ {
+ Folks.Individual i = (Folks.Individual) individual_obj;
+ foreach (var url in i.urls)
+ {
+ if (url.value == this._url_extra_1)
+ {
+ this._found_url_extra_1 = true;
+ }
+ else if (url.value == this._url_extra_2)
+ {
+ this._found_url_extra_2 = true;
+ }
+ else if (url.value == this._url_home)
+ {
+ this._found_url_home = true;
+ }
+ else if (url.value == this._url_blog)
+ {
+ this._found_url_blog = true;
+ }
+ }
+
+ if (this._found_url_extra_1 &&
+ this._found_url_extra_2 &&
+ this._found_url_home &&
+ this._found_url_blog)
+ {
+ this._main_loop.quit ();
+ }
+ }
+}
+
+public int main (string[] args)
+{
+ Test.init (ref args);
+
+ TestSuite root = TestSuite.get_root ();
+ root.add_suite (new SetUrlsTests ().get_suite ());
+
+ Test.run ();
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]