[Telepathy-commits] [telepathy-gabble/master] BuddyInfo.GetProperties now find properties from views

Guillaume Desmottes guillaume.desmottes at collabora.co.uk
Fri Sep 26 10:02:11 PDT 2008


20080523141237-7fe3f-f2617d768bed6c01ea5db9900bfd77dc3eb44df0.gz
---
 src/conn-olpc.c                         |   48 ++++++++++++++++++-
 src/olpc-buddy-view.c                   |   78 ++++++++++++++++++++++++++++++-
 src/olpc-buddy-view.h                   |    8 +++-
 tests/twisted/olpc/olpc-buddy-search.py |    4 ++
 4 files changed, 133 insertions(+), 5 deletions(-)

diff --git a/src/conn-olpc.c b/src/conn-olpc.c
index 14576db..d10d2b4 100644
--- a/src/conn-olpc.c
+++ b/src/conn-olpc.c
@@ -527,6 +527,31 @@ get_properties_reply_cb (GabbleConnection *conn,
   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 }
 
+static gboolean
+find_view_having_properties_for_buddy (gpointer id,
+                                       gpointer value,
+                                       gpointer buddy)
+{
+  GabbleOlpcBuddyView *view = GABBLE_OLPC_BUDDY_VIEW (value);
+  TpHandle handle = GPOINTER_TO_UINT (buddy);
+
+  return gabble_olpc_buddy_view_get_properties (view, handle) != NULL;
+}
+
+static GHashTable *
+find_buddy_properties_from_views (GabbleConnection *conn,
+                                  TpHandle buddy)
+{
+  GabbleOlpcBuddyView *view;
+
+  view = g_hash_table_find (conn->olpc_buddy_views,
+      find_view_having_properties_for_buddy, GUINT_TO_POINTER (buddy));
+  if (view == NULL)
+    return NULL;
+
+  return gabble_olpc_buddy_view_get_properties (view, buddy);
+}
+
 static void
 olpc_buddy_info_get_properties (GabbleSvcOLPCBuddyInfo *iface,
                                 guint contact,
@@ -535,6 +560,7 @@ olpc_buddy_info_get_properties (GabbleSvcOLPCBuddyInfo *iface,
   GabbleConnection *conn = GABBLE_CONNECTION (iface);
   TpBaseConnection *base = (TpBaseConnection *) conn;
   const gchar *jid;
+  GHashTable *properties;
 
   DEBUG ("called");
 
@@ -542,6 +568,16 @@ olpc_buddy_info_get_properties (GabbleSvcOLPCBuddyInfo *iface,
   if (!check_pep (conn, context))
     return;
 
+  /* First check if we can find properties in a buddy view */
+  properties = find_buddy_properties_from_views (conn, contact);
+  if (properties != NULL)
+    {
+      gabble_svc_olpc_buddy_info_return_from_get_properties (context,
+          properties);
+      return;
+    }
+
+  /* Then try to query the PEP node */
   jid = inspect_contact (base, context, contact);
   if (jid == NULL)
     return;
@@ -2869,8 +2905,10 @@ add_buddies_to_view_from_node (GabbleConnection *conn,
   TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
       (TpBaseConnection*) conn, TP_HANDLE_TYPE_CONTACT);
   LmMessageNode *buddy;
+  GPtrArray *buddies_properties;
 
   buddies = tp_handle_set_new (contact_repo);
+  buddies_properties = g_ptr_array_new ();
 
   for (buddy = node->children; buddy != NULL; buddy = buddy->next)
     {
@@ -2901,16 +2939,20 @@ add_buddies_to_view_from_node (GabbleConnection *conn,
       properties = lm_message_node_extract_properties (properties_node,
           "property");
 
+      g_ptr_array_add (buddies_properties, properties);
+
       /* FIXME: is it sane to fire this signal as the client doesn't know
        * this buddy yet? */
       gabble_svc_olpc_buddy_info_emit_properties_changed (conn, handle,
           properties);
-
-      g_hash_table_destroy (properties);
     }
 
-  gabble_olpc_buddy_view_add_buddies (view, buddies);
+  /* FIXME: we should update properties when needed */
+  gabble_olpc_buddy_view_add_buddies (view, buddies, buddies_properties);
+
   tp_handle_set_destroy (buddies);
+  g_ptr_array_foreach (buddies_properties, (GFunc) g_hash_table_unref, NULL);
+  g_ptr_array_free (buddies_properties, TRUE);
 
   return TRUE;
 }
diff --git a/src/olpc-buddy-view.c b/src/olpc-buddy-view.c
index 47b94cb..556a09e 100644
--- a/src/olpc-buddy-view.c
+++ b/src/olpc-buddy-view.c
@@ -62,6 +62,9 @@ struct _GabbleOlpcBuddyViewPrivate
   char *object_path;
   guint id;
 
+  /* TpHandle => GHashTable * */
+  GHashTable *buddy_properties;
+
   gboolean dispose_has_run;
 };
 
@@ -86,6 +89,9 @@ gabble_olpc_buddy_view_init (GabbleOlpcBuddyView *self)
 
   self->priv = priv;
 
+  priv->buddy_properties = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+      NULL, (GDestroyNotify) g_hash_table_unref);
+
   priv->dispose_has_run = FALSE;
 }
 
@@ -98,6 +104,12 @@ gabble_olpc_buddy_view_dispose (GObject *object)
   if (priv->dispose_has_run)
     return;
 
+  if (priv->buddy_properties != NULL)
+    {
+      g_hash_table_destroy (priv->buddy_properties);
+      priv->buddy_properties = NULL;
+    }
+
   priv->dispose_has_run = TRUE;
 
   if (G_OBJECT_CLASS (gabble_olpc_buddy_view_parent_class)->dispose)
@@ -322,17 +334,49 @@ olpc_buddy_view_close (GabbleSvcOLPCBuddyView *iface,
 
 void
 gabble_olpc_buddy_view_add_buddies (GabbleOlpcBuddyView *self,
-                                    TpHandleSet *buddies)
+                                    TpHandleSet *buddies,
+                                    GPtrArray *buddies_properties)
 {
+  GabbleOlpcBuddyViewPrivate *priv = GABBLE_OLPC_BUDDY_VIEW_GET_PRIVATE (self);
   TpIntSet *empty;
+  GArray *buddies_array;
+  guint i;
 
   empty = tp_intset_new ();
+  buddies_array = tp_handle_set_to_array (buddies);
+
+  g_assert (buddies_array->len == buddies_properties->len);
 
   tp_group_mixin_change_members (G_OBJECT (self), "",
       tp_handle_set_peek (buddies), empty, empty, empty,
       0, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
 
+  /* store properties */
+  for (i = 0; i < buddies_array->len; i++)
+    {
+      TpHandle handle;
+      GHashTable *properties;
+
+      handle = g_array_index (buddies_array, TpHandle, i);
+      properties = g_ptr_array_index (buddies_properties, i);
+
+      g_hash_table_insert (priv->buddy_properties, GUINT_TO_POINTER (handle),
+          properties);
+      g_hash_table_ref (properties);
+    }
+
   tp_intset_destroy (empty);
+  g_array_free (buddies_array, TRUE);
+}
+
+static void
+remove_properties_foreach (TpHandleSet *buddies,
+                           TpHandle handle,
+                           GabbleOlpcBuddyView *self)
+{
+  GabbleOlpcBuddyViewPrivate *priv = GABBLE_OLPC_BUDDY_VIEW_GET_PRIVATE (self);
+
+  g_hash_table_remove (priv->buddy_properties, GUINT_TO_POINTER (handle));
 }
 
 void
@@ -347,9 +391,41 @@ gabble_olpc_buddy_view_remove_buddies (GabbleOlpcBuddyView *self,
       empty, tp_handle_set_peek (buddies), empty, empty,
       0, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
 
+  tp_handle_set_foreach (buddies,
+      (TpHandleSetMemberFunc) remove_properties_foreach, self);
+
   tp_intset_destroy (empty);
 }
 
+gboolean
+gabble_olpc_buddy_view_set_properties (GabbleOlpcBuddyView *self,
+                                       TpHandle buddy,
+                                       GHashTable *properties)
+{
+  GabbleOlpcBuddyViewPrivate *priv = GABBLE_OLPC_BUDDY_VIEW_GET_PRIVATE (self);
+
+  if (!tp_handle_set_is_member (self->group.members, buddy))
+    {
+      DEBUG ("buddy %d is not member of this view", buddy);
+      return FALSE;
+    }
+
+  g_hash_table_insert (priv->buddy_properties, GUINT_TO_POINTER (buddy),
+      properties);
+  g_hash_table_ref (properties);
+
+  return TRUE;
+}
+
+GHashTable *
+gabble_olpc_buddy_view_get_properties (GabbleOlpcBuddyView *self,
+                                       TpHandle buddy)
+{
+  GabbleOlpcBuddyViewPrivate *priv = GABBLE_OLPC_BUDDY_VIEW_GET_PRIVATE (self);
+
+  return g_hash_table_lookup (priv->buddy_properties, GUINT_TO_POINTER (buddy));
+}
+
 static void
 buddy_view_iface_init (gpointer g_iface,
                        gpointer iface_data)
diff --git a/src/olpc-buddy-view.h b/src/olpc-buddy-view.h
index 2724fa5..51b1ea4 100644
--- a/src/olpc-buddy-view.h
+++ b/src/olpc-buddy-view.h
@@ -69,12 +69,18 @@ GabbleOlpcBuddyView * gabble_olpc_buddy_view_new (GabbleConnection *conn,
     guint id);
 
 void gabble_olpc_buddy_view_add_buddies (GabbleOlpcBuddyView *self,
-    TpHandleSet *handles);
+    TpHandleSet *handles, GPtrArray *buddies_properties);
 
 
 void gabble_olpc_buddy_view_remove_buddies (GabbleOlpcBuddyView *self,
     TpHandleSet *handles);
 
+gboolean gabble_olpc_buddy_view_set_properties (GabbleOlpcBuddyView *self,
+    TpHandle buddy, GHashTable *properties);
+
+GHashTable * gabble_olpc_buddy_view_get_properties (GabbleOlpcBuddyView *self,
+    TpHandle buddy);
+
 G_END_DECLS
 
 #endif /* #ifndef __GABBLE_OLPC_BUDDY_VIEW_H__ */
diff --git a/tests/twisted/olpc/olpc-buddy-search.py b/tests/twisted/olpc/olpc-buddy-search.py
index 8e77f0f..7d5053d 100644
--- a/tests/twisted/olpc/olpc-buddy-search.py
+++ b/tests/twisted/olpc/olpc-buddy-search.py
@@ -151,6 +151,10 @@ def test(q, bus, conn, stream):
     handle = added[0]
     assert conn.InspectHandles(1, [handle])[0] == 'bob at localhost'
 
+    # we can now get bob's properties
+    props = buddy_info_iface.GetProperties(handle)
+    assert props == {'color': '#005FE4,#00A0FF'}
+
     # buddy search
     props = {'color': '#AABBCC,#001122'}
     call_async(q, gadget_iface, 'SearchBuddiesByProperties', props)
-- 
1.5.6.5




More information about the Telepathy-commits mailing list