[folks] eds: Add anti-linking support



commit a87ba87ae231f2c2f511fad804c8cfd8da4c82e3
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun May 6 22:59:34 2012 +0100

    eds: Add anti-linking support
    
    Helps: https://bugzilla.gnome.org/show_bug.cgi?id=629537

 backends/eds/lib/edsf-persona-store.vala |   53 +++++++++++++++++++++++++--
 backends/eds/lib/edsf-persona.vala       |   59 ++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 3 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index ba048a1..bb11254 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -59,6 +59,8 @@ public class Edsf.PersonaStore : Folks.PersonaStore
    * in your language, please *do not* translate this string. */
   internal const string android_favourite_group_name = N_("Starred in Android");
 
+  internal static const string anti_links_attribute_name = "X-FOLKS-ANTI-LINKS";
+
   /**
    * The type of persona store this is.
    *
@@ -781,9 +783,9 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                 {
                   string[] fields = ((!) supported_fields).split (",");
 
-                  /* We always support local-ids, web-service-addresses, gender
-                   * and favourite because we use custom vCard attributes for
-                   * them. */
+                  /* We always support local-ids, web-service-addresses, gender,
+                   * anti-links and favourite because we use custom vCard
+                   * attributes for them. */
                   prop_set.add ((!) Folks.PersonaStore.detail_key (
                       PersonaDetail.LOCAL_IDS));
                   prop_set.add ((!) Folks.PersonaStore.detail_key (
@@ -792,6 +794,8 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                       PersonaDetail.GENDER));
                   prop_set.add ((!) Folks.PersonaStore.detail_key (
                       PersonaDetail.IS_FAVOURITE));
+                  prop_set.add ((!) Folks.PersonaStore.detail_key (
+                      PersonaDetail.ANTI_LINKS));
 
                   foreach (unowned string field in fields)
                     {
@@ -2078,6 +2082,49 @@ public class Edsf.PersonaStore : Folks.PersonaStore
         }
     }
 
+  internal async void _set_anti_links (Edsf.Persona persona,
+      Set<string> anti_links) throws PropertyError
+    {
+      if (!("anti-links" in this._always_writeable_properties))
+        {
+          throw new PropertyError.NOT_WRITEABLE (
+              _("Anti-links are not writeable on this contact."));
+        }
+
+      if (Folks.Internal.equal_sets<string> (anti_links, persona.anti_links))
+        {
+          return;
+        }
+
+      yield this._set_contact_anti_links (persona.contact, anti_links);
+      yield this._commit_modified_property (persona, "anti-links");
+    }
+
+  private async void _set_contact_anti_links (E.Contact contact,
+      Set<string> anti_links)
+    {
+      var vcard = (E.VCard) contact;
+      vcard.remove_attributes (null, this.anti_links_attribute_name);
+
+      var persona_uid =
+          Folks.Persona.build_uid (BACKEND_NAME, this.id, contact.id);
+
+      foreach (var anti_link_uid in anti_links)
+        {
+          /* Skip the persona's UID; don't allow reflexive anti-links. */
+          if (anti_link_uid == persona_uid)
+            {
+              continue;
+            }
+
+          var attr = new E.VCardAttribute (null,
+              this.anti_links_attribute_name);
+          attr.add_value (anti_link_uid);
+
+          contact.add_attribute ((owned) attr);
+        }
+    }
+
   private void _contacts_added_cb (GLib.List<E.Contact> contacts)
     {
       var added_personas = new HashSet<Persona> ();
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index e9bd8d1..026fd0e 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -30,6 +30,7 @@ using Xml;
  * A persona subclass which represents a single EDS contact.
  */
 public class Edsf.Persona : Folks.Persona,
+    AntiLinkable,
     AvatarDetails,
     BirthdayDetails,
     EmailDetails,
@@ -672,6 +673,32 @@ public class Edsf.Persona : Folks.Persona,
           is_favourite);
     }
 
+  private HashSet<string> _anti_links;
+  private Set<string> _anti_links_ro;
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  [CCode (notify = false)]
+  public Set<string> anti_links
+    {
+      get { return this._anti_links_ro; }
+      set { this.change_anti_links.begin (value); }
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void change_anti_links (Set<string> anti_links)
+      throws PropertyError
+    {
+      yield ((Edsf.PersonaStore) this.store)._set_anti_links (this, anti_links);
+    }
+
   /**
    * Build a IID.
    *
@@ -776,6 +803,8 @@ public class Edsf.Persona : Folks.Persona,
            AbstractFieldDetails<Role>.hash_static,
            AbstractFieldDetails<Role>.equal_static);
       this._roles_ro = this._roles.read_only_view;
+      this._anti_links = new HashSet<string> ();
+      this._anti_links_ro = this._anti_links.read_only_view;
 
       this._update (this._contact);
     }
@@ -865,6 +894,7 @@ public class Edsf.Persona : Folks.Persona,
       this._update_birthday ();
       this._update_roles ();
       this._update_favourite ();
+      this._update_anti_links ();
 
       this.thaw_notify ();
     }
@@ -1751,6 +1781,35 @@ public class Edsf.Persona : Folks.Persona,
         }
     }
 
+  private void _update_anti_links ()
+    {
+      var new_anti_links = new HashSet<string> ();
+
+      var vcard = (E.VCard) this.contact;
+      foreach (unowned E.VCardAttribute attr in vcard.get_attributes ())
+        {
+          if (attr.get_name () != Edsf.PersonaStore.anti_links_attribute_name)
+            {
+              continue;
+            }
+
+          var val = attr.get_value ();
+          if (val == null || (!) val == "")
+             {
+              continue;
+            }
+
+          new_anti_links.add ((!) val);
+        }
+
+      if (!Folks.Internal.equal_sets<string> (new_anti_links, this._anti_links))
+        {
+          this._anti_links = new_anti_links;
+          this._anti_links_ro = new_anti_links.read_only_view;
+          this.notify_property ("anti-links");
+        }
+    }
+
   internal static T? _get_property_from_contact<T> (E.Contact contact,
       string prop_name)
     {



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