[libsocialweb] facebook: support for contacts
- From: Alban Crequy <albanc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsocialweb] facebook: support for contacts
- Date: Thu, 31 Mar 2011 15:36:02 +0000 (UTC)
commit 7fc2cc8a29633fca742542370ab640866ae69366
Author: Alban Crequy <alban crequy collabora co uk>
Date: Mon Mar 28 19:09:14 2011 +0100
facebook: support for contacts
Inspired by:
Marco Barisione <marco barisione collabora co uk>
services/facebook/Makefile.am | 1 +
services/facebook/facebook-contact-view.c | 582 +++++++++++++++++++++++++++++
services/facebook/facebook-contact-view.h | 61 +++
services/facebook/facebook.c | 50 +++
4 files changed, 694 insertions(+), 0 deletions(-)
---
diff --git a/services/facebook/Makefile.am b/services/facebook/Makefile.am
index 26b7fd8..4f455e4 100644
--- a/services/facebook/Makefile.am
+++ b/services/facebook/Makefile.am
@@ -4,6 +4,7 @@ libfacebook_la_SOURCES = \
module.c \
facebook.c facebook.h \
facebook-util.c facebook-util.h \
+ facebook-contact-view.c facebook-contact-view.h \
facebook-item-view.c facebook-item-view.h
libfacebook_la_CFLAGS = \
diff --git a/services/facebook/facebook-contact-view.c b/services/facebook/facebook-contact-view.c
new file mode 100644
index 0000000..cde6791
--- /dev/null
+++ b/services/facebook/facebook-contact-view.c
@@ -0,0 +1,582 @@
+/*
+ * libsocialweb Facebook service support
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ * Copyright (C) 2010-2011 Collabora Ltd.
+ *
+ * Authors: Gary Ching-Pang Lin <glin novell com>
+ * Thomas Thurman <thomas thurman collabora co uk>
+ * Jonathon Jongsma <jonathon jongsma collabora co uk>
+ * Danielle Madeley <danielle madeley collabora co uk>
+ * Marco Barisione <marco barisione collabora co uk>
+ * Alban Crequy <alban crequy collabora co uk>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "facebook-contact-view.h"
+#include "facebook.h"
+#include "facebook-util.h"
+
+#include <libsocialweb/sw-debug.h>
+#include <libsocialweb/sw-contact.h>
+#include <libsocialweb/sw-set.h>
+#include <libsocialweb/sw-cache.h>
+
+#include <rest/rest-proxy.h>
+#include <rest/rest-xml-parser.h>
+#include <json-glib/json-glib.h>
+
+#define GET_PRIVATE(o) (((SwFacebookContactView *) o)->priv)
+
+#define UPDATE_TIMEOUT (5*60)
+
+G_DEFINE_TYPE (SwFacebookContactView, sw_facebook_contact_view, SW_TYPE_CONTACT_VIEW);
+
+static void facebook_contact_view_stop (SwContactView *self);
+static void facebook_contact_view_refresh (SwContactView *self);
+
+struct _SwFacebookContactViewPrivate
+{
+ RestProxy *proxy;
+ gchar *query;
+ GHashTable *params;
+
+ guint running;
+};
+
+enum /* properties */
+{
+ PROP_0,
+ PROP_PROXY,
+ PROP_QUERY,
+ PROP_PARAMS
+};
+
+static char*
+_facebook_status_node_get_link (JsonNode *status_node)
+{
+ JsonObject *status_object = json_node_get_object (status_node);
+ char *url = get_child_node_value (status_node, "link");
+
+ if (url == NULL)
+ {
+ /* try to extract a link to the 'comment' action for this post, which
+ * serves as a 'permalink' for a particular status update */
+ JsonArray *actions = NULL;
+ JsonNode *actions_node = json_object_get_member (status_object,
+ "actions");
+
+ if (actions_node != NULL)
+ actions = json_node_get_array (actions_node);
+
+ if (actions != NULL)
+ {
+ guint j;
+
+ for (j = 0; j < json_array_get_length (actions); j++)
+ {
+ JsonNode *action = json_array_get_element (actions, j);
+ char *action_name;
+
+ action_name = get_child_node_value (action, "name");
+
+ if (action_name == NULL)
+ {
+ continue;
+ }
+ else if (g_ascii_strcasecmp (action_name, "Comment") != 0)
+ {
+ g_free (action_name);
+
+ continue;
+ }
+
+ g_free (action_name);
+
+ url = get_child_node_value (action, "link");
+
+ break;
+ }
+ }
+ }
+
+ if (url == NULL)
+ {
+ /* can't find a decent url to associate with this post, so just link to
+ * the facebook homepage */
+ url = g_strdup ("http://www.facebook.com");
+ }
+
+ return url;
+}
+
+static void
+update_contact_from_node (SwContact *dest_contact,
+ const gchar *dest_name,
+ JsonNode *src_node,
+ const gchar *src_name)
+{
+ gchar *value;
+
+ value = get_child_node_value (src_node, src_name);
+ if (value != NULL)
+ sw_contact_take (dest_contact, dest_name, value);
+}
+
+static SwContact*
+_facebook_friend_node_to_contact (SwContactView *self,
+ JsonNode *friend_node)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+ SwContact *contact;
+ char *id, *uid, *pic_url, *urls;
+ char *name = NULL;
+ char *updated_time = NULL;
+ GStrv urls_array = NULL;
+ int i;
+
+ if (json_node_get_node_type (friend_node) != JSON_NODE_OBJECT)
+ return NULL;
+
+ contact = sw_contact_new ();
+ sw_contact_set_service (contact, sw_contact_view_get_service (self));
+
+ uid = get_child_node_value (friend_node, "id");
+ if (uid == NULL)
+ {
+ SW_DEBUG (FACEBOOK, "Got friend without an id");
+ g_object_unref (contact);
+
+ return NULL;
+ }
+
+ if (uid != NULL)
+ {
+ pic_url = build_picture_url (priv->proxy, uid, FB_PICTURE_SIZE_SQUARE);
+ sw_contact_request_image_fetch (contact, FALSE, "icon", pic_url);
+ g_free (pic_url);
+ }
+
+ id = g_strconcat ("facebook-", uid, NULL);
+ g_free (uid);
+ sw_contact_take (contact, "id", id);
+
+ name = get_child_node_value (friend_node, "name");
+ if (name == NULL)
+ {
+ SW_DEBUG (FACEBOOK, "Got friend without a name");
+ g_object_unref (contact);
+
+ return NULL;
+ }
+ sw_contact_take (contact, "name", name);
+
+ updated_time = get_child_node_value (friend_node, "updated_time");
+ if (updated_time == NULL)
+ {
+ SW_DEBUG (FACEBOOK, "Got friend without an update time");
+ g_object_unref (contact);
+
+ return NULL;
+ }
+ sw_contact_take (contact, "date", updated_time);
+
+ /* We use the vcard names as keys */
+ update_contact_from_node (contact, "x-gender", friend_node, "gender");
+ update_contact_from_node (contact, "url", friend_node, "link");
+ urls = get_child_node_value (friend_node, "website");
+ if (urls)
+ urls_array = g_strsplit (urls, "\r\n", 10);
+ if (urls_array) {
+ for (i = 0 ; urls_array[i] != NULL ; i++) {
+ sw_contact_put (contact, "url", urls_array[i]);
+ }
+ g_strfreev (urls_array);
+ g_free (urls);
+ }
+ /* This is a "special" url as it's the one for the facebook profile */
+ update_contact_from_node (contact, "x-facebook-profile", friend_node, "link");
+ /* We could just properly set this as an "N" field and separating the
+ * values with semicolons, but that would require escaping semicolons
+ * and would make things more difficult for who uses libsocialweb
+ * without caring about vcards */
+ update_contact_from_node (contact, "n.given", friend_node, "first_name");
+ update_contact_from_node (contact, "n.family", friend_node, "last_name");
+
+ return contact;
+}
+
+static SwSet*
+_facebook_update_node_to_set (SwContactView *self,
+ JsonNode *root)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+ JsonObject *root_object = NULL;
+ JsonNode *statuses = NULL;
+ JsonArray *updates_array = NULL;
+ SwSet *set = NULL;
+ guint i;
+
+ if (json_node_get_node_type (root) == JSON_NODE_OBJECT)
+ root_object = json_node_get_object (root);
+ else
+ return NULL;
+
+ if (!json_object_has_member (root_object, "data"))
+ return NULL;
+
+ statuses = json_object_get_member (root_object, "data");
+
+ if (json_node_get_node_type (statuses) == JSON_NODE_ARRAY)
+ updates_array = json_node_get_array (statuses);
+ else
+ return NULL;
+
+ set = sw_contact_set_new ();
+
+ for (i = 0; i < json_array_get_length (updates_array); i++)
+ {
+ JsonNode *status;
+ SwContact *contact;
+
+ status = json_array_get_element (updates_array, i);
+
+ contact = _facebook_friend_node_to_contact (self, status);
+
+ if (contact != NULL)
+ {
+ sw_set_add (set, G_OBJECT (contact));
+ g_object_unref (contact);
+ }
+ }
+
+ return set;
+}
+
+static void
+got_updates_cb (RestProxyCall *call,
+ GError *error,
+ GObject *weak_object,
+ gpointer userdata)
+{
+ SwContactView *self = SW_CONTACT_VIEW (weak_object);
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+ JsonNode *root;
+ SwSet *set;
+
+ if (error)
+ {
+ g_message ("Error: %s", error->message);
+
+ return;
+ }
+
+ root = json_node_from_call (call, NULL);
+ if (!root)
+ return;
+
+ set = _facebook_update_node_to_set (self, root);
+
+ json_node_free (root);
+
+ if (set != NULL)
+ {
+ sw_contact_view_set_from_set (self, set);
+
+ /* Save the results of this set to the cache */
+ sw_cache_save (sw_contact_view_get_service (self),
+ priv->query,
+ priv->params,
+ set);
+
+ sw_set_unref (set);
+ }
+}
+
+static void
+get_updates (SwContactView *self)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+ RestProxyCall *call;
+ const char *my_uid = sw_service_facebook_get_uid (
+ (SwServiceFacebook *) sw_contact_view_get_service (self));
+
+ if (my_uid == NULL || priv->running == 0)
+ return;
+
+ call = rest_proxy_new_call (priv->proxy);
+
+ if (g_strcmp0 (priv->query, "people") == 0)
+ {
+ rest_proxy_call_set_function (call, "me/friends");
+ rest_proxy_call_add_param (call, "fields",
+ "updated_time,name,first_name,last_name,link,website,gender");
+ }
+ else
+ {
+ g_return_if_reached ();
+ }
+
+ rest_proxy_call_async (call,
+ (RestProxyCallAsyncCallback) got_updates_cb,
+ (GObject*) self,
+ NULL,
+ NULL);
+
+ g_object_unref (call);
+}
+
+static void
+load_from_cache (SwContactView *self)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+ SwSet *set;
+
+ set = sw_cache_load (sw_contact_view_get_service (self),
+ priv->query,
+ priv->params,
+ sw_contact_set_new);
+
+ if (set != NULL)
+ {
+ sw_contact_view_set_from_set (self, set);
+
+ sw_set_unref (set);
+ }
+}
+
+static void
+_service_user_changed (SwService *service,
+ SwContactView *self)
+{
+ SwSet *set;
+
+ /* We need to empty the set */
+ set = sw_contact_set_new ();
+ sw_contact_view_set_from_set (self, set);
+ sw_set_unref (set);
+
+ /* And drop the cache */
+ sw_cache_drop_all (service);
+}
+
+static void
+_service_capabilities_changed (SwService *service,
+ const gchar **caps,
+ SwContactView *self)
+{
+ if (sw_service_has_cap (caps, CREDENTIALS_VALID))
+ {
+ facebook_contact_view_refresh (self);
+ }
+}
+
+static void
+facebook_contact_view_constructed (GObject *self)
+{
+ SwService *service = sw_contact_view_get_service ((SwContactView *) self);
+
+ g_signal_connect_object (service, "user-changed",
+ G_CALLBACK (_service_user_changed), self, 0);
+ g_signal_connect_object (service, "capabilities-changed",
+ G_CALLBACK (_service_capabilities_changed), self, 0);
+
+ if (G_OBJECT_CLASS (sw_facebook_contact_view_parent_class)->constructed != NULL)
+ G_OBJECT_CLASS (sw_facebook_contact_view_parent_class)->constructed (self);
+}
+
+static void
+facebook_contact_view_set_property (GObject *self,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_PROXY:
+ priv->proxy = g_value_dup_object (value);
+ break;
+
+ case PROP_QUERY:
+ priv->query = g_value_dup_string (value);
+ break;
+
+ case PROP_PARAMS:
+ priv->params = g_value_dup_boxed (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec);
+ break;
+ }
+}
+
+static void
+facebook_contact_view_get_property (GObject *self,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_PROXY:
+ g_value_set_object (value, priv->proxy);
+ break;
+
+ case PROP_QUERY:
+ g_value_set_string (value, priv->query);
+ break;
+
+ case PROP_PARAMS:
+ g_value_set_boxed (value, priv->params);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec);
+ break;
+ }
+}
+
+static void
+facebook_contact_view_dispose (GObject *self)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+
+ facebook_contact_view_stop ((SwContactView *) self);
+
+ g_object_unref (priv->proxy);
+ priv->proxy = NULL;
+
+ G_OBJECT_CLASS (sw_facebook_contact_view_parent_class)->dispose (self);
+}
+
+static void
+facebook_contact_view_finalize (GObject *self)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+
+ g_free (priv->query);
+ g_boxed_free (G_TYPE_HASH_TABLE, priv->params);
+
+ G_OBJECT_CLASS (sw_facebook_contact_view_parent_class)->finalize (self);
+}
+
+static gboolean
+_update_timeout_cb (gpointer user_data)
+{
+ get_updates ((SwContactView *) user_data);
+
+ return TRUE;
+}
+
+static void
+facebook_contact_view_start (SwContactView *self)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+
+ if (priv->running != 0)
+ {
+ g_message (G_STRLOC ": View asked to start, but already running");
+ }
+ else
+ {
+ SW_DEBUG (FACEBOOK, "Starting up the Facebook view");
+
+ priv->running = g_timeout_add_seconds (UPDATE_TIMEOUT,
+ _update_timeout_cb,
+ self);
+
+ load_from_cache (self);
+ get_updates (self);
+ }
+}
+
+static void
+facebook_contact_view_stop (SwContactView *self)
+{
+ SwFacebookContactViewPrivate *priv = GET_PRIVATE (self);
+
+ if (priv->running == 0)
+ {
+ g_message (G_STRLOC ": View ask to stop, but not running");
+ }
+ else
+ {
+ SW_DEBUG (FACEBOOK, "Stopping the Facebook view");
+
+ g_source_remove (priv->running);
+ priv->running = 0;
+ }
+
+}
+
+static void
+facebook_contact_view_refresh (SwContactView *self)
+{
+ SW_DEBUG (FACEBOOK, "Forced a refresh of the Facebook view");
+
+ get_updates (self);
+}
+
+static void
+sw_facebook_contact_view_class_init (SwFacebookContactViewClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SwContactViewClass *contact_view_class = SW_CONTACT_VIEW_CLASS (klass);
+
+ gobject_class->constructed = facebook_contact_view_constructed;
+ gobject_class->set_property = facebook_contact_view_set_property;
+ gobject_class->get_property = facebook_contact_view_get_property;
+ gobject_class->dispose = facebook_contact_view_dispose;
+ gobject_class->finalize = facebook_contact_view_finalize;
+
+ contact_view_class->start = facebook_contact_view_start;
+ contact_view_class->stop = facebook_contact_view_stop;
+ contact_view_class->refresh = facebook_contact_view_refresh;
+
+ g_object_class_install_property (gobject_class, PROP_PROXY,
+ g_param_spec_object ("proxy",
+ "Proxy",
+ "The #RestProxy we're using to make API calls",
+ REST_TYPE_PROXY,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_QUERY,
+ g_param_spec_string ("query",
+ "Query",
+ "The query requested for this view",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_PARAMS,
+ g_param_spec_boxed ("params",
+ "Params",
+ "Additional parameters passed to the query",
+ G_TYPE_HASH_TABLE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private (gobject_class, sizeof (SwFacebookContactViewPrivate));
+}
+
+static void
+sw_facebook_contact_view_init (SwFacebookContactView *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
+ SW_TYPE_FACEBOOK_CONTACT_VIEW, SwFacebookContactViewPrivate);
+}
diff --git a/services/facebook/facebook-contact-view.h b/services/facebook/facebook-contact-view.h
new file mode 100644
index 0000000..2c31735
--- /dev/null
+++ b/services/facebook/facebook-contact-view.h
@@ -0,0 +1,61 @@
+/*
+ * libsocialweb Facebook service support
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ * Copyright (C) 2010-2011 Collabora Ltd.
+ *
+ * Authors: Gary Ching-Pang Lin <glin novell com>
+ * Thomas Thurman <thomas thurman collabora co uk>
+ * Jonathon Jongsma <jonathon jongsma collabora co uk>
+ * Danielle Madeley <danielle madeley collabora co uk>
+ * Alban Crequy <alban crequy collabora co uk>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __FACEBOOK_CONTACT_VIEW_H__
+#define __FACEBOOK_CONTACT_VIEW_H__
+
+#include <glib-object.h>
+#include <libsocialweb/sw-contact-view.h>
+
+G_BEGIN_DECLS
+
+#define SW_TYPE_FACEBOOK_CONTACT_VIEW (sw_facebook_contact_view_get_type ())
+#define SW_FACEBOOK_CONTACT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SW_TYPE_FACEBOOK_CONTACT_VIEW, SwFacebookContactView))
+#define SW_FACEBOOK_CONTACT_VIEW_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), SW_TYPE_FACEBOOK_CONTACT_VIEW, SwFacebookContactViewClass))
+#define SW_IS_FACEBOOK_CONTACT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SW_TYPE_FACEBOOK_CONTACT_VIEW))
+#define SW_IS_FACEBOOK_CONTACT_VIEW_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), SW_TYPE_FACEBOOK_CONTACT_VIEW))
+#define SW_FACEBOOK_CONTACT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SW_TYPE_FACEBOOK_CONTACT_VIEW, SwFacebookContactViewClass))
+
+typedef struct _SwFacebookContactView SwFacebookContactView;
+typedef struct _SwFacebookContactViewClass SwFacebookContactViewClass;
+typedef struct _SwFacebookContactViewPrivate SwFacebookContactViewPrivate;
+
+struct _SwFacebookContactView
+{
+ SwContactView parent;
+ SwFacebookContactViewPrivate *priv;
+};
+
+struct _SwFacebookContactViewClass
+{
+ SwContactViewClass parent_class;
+};
+
+GType sw_facebook_contact_view_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/services/facebook/facebook.c b/services/facebook/facebook.c
index 433dbf8..6bfef4a 100644
--- a/services/facebook/facebook.c
+++ b/services/facebook/facebook.c
@@ -29,6 +29,7 @@
#include "facebook.h"
#include "facebook-util.h"
+#include "facebook-contact-view.h"
#include "facebook-item-view.h"
#include <json-glib/json-glib.h>
@@ -46,10 +47,12 @@
#include <interfaces/sw-status-update-ginterface.h>
#include <interfaces/sw-photo-upload-ginterface.h>
#include <interfaces/sw-video-upload-ginterface.h>
+#include <interfaces/sw-contacts-query-ginterface.h>
#include <interfaces/sw-query-ginterface.h>
#include <interfaces/sw-collections-ginterface.h>
static void initable_iface_init (gpointer g_iface, gpointer iface_data);
+static void contacts_query_iface_init (gpointer g_iface, gpointer iface_data);
static void query_iface_init (gpointer g_iface, gpointer iface_data);
static void avatar_iface_init (gpointer g_iface, gpointer iface_data);
static void status_update_iface_init (gpointer g_iface, gpointer iface_data);
@@ -62,6 +65,8 @@ G_DEFINE_TYPE_WITH_CODE (SwServiceFacebook,
SW_TYPE_SERVICE,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
initable_iface_init)
+ G_IMPLEMENT_INTERFACE (SW_TYPE_CONTACTS_QUERY_IFACE,
+ contacts_query_iface_init)
G_IMPLEMENT_INTERFACE (SW_TYPE_QUERY_IFACE,
query_iface_init)
G_IMPLEMENT_INTERFACE (SW_TYPE_AVATAR_IFACE,
@@ -121,6 +126,7 @@ get_static_caps (SwService *service)
HAS_UPDATE_STATUS_IFACE,
HAS_AVATAR_IFACE,
HAS_BANISHABLE_IFACE,
+ HAS_CONTACTS_QUERY_IFACE,
HAS_QUERY_IFACE,
HAS_PHOTO_UPLOAD_IFACE,
HAS_VIDEO_UPLOAD_IFACE,
@@ -462,6 +468,42 @@ initable_iface_init (gpointer g_iface, gpointer iface_data)
/* Query interface */
static void
+_facebook_contacts_query_open_view (SwContactsQueryIface *self,
+ const gchar *query,
+ GHashTable *params,
+ DBusGMethodInvocation *context)
+{
+ SwServiceFacebookPrivate *priv = GET_PRIVATE (self);
+ SwContactView *contact_view;
+ const gchar *object_path;
+
+ g_debug ("query = '%s'", query);
+ if (!g_str_equal (query, "people"))
+ {
+ dbus_g_method_return_error (context,
+ g_error_new (SW_SERVICE_ERROR,
+ SW_SERVICE_ERROR_INVALID_QUERY,
+ "Query '%s' is invalid",
+ query));
+ return;
+ }
+
+ contact_view = g_object_new (SW_TYPE_FACEBOOK_CONTACT_VIEW,
+ "service", self,
+ "proxy", priv->proxy,
+ "query", query,
+ "params", params,
+ NULL);
+ object_path = sw_contact_view_get_object_path (contact_view);
+
+ /* Ensure the object gets disposed when the client goes away */
+ sw_client_monitor_add (dbus_g_method_get_sender (context),
+ (GObject *) contact_view);
+
+ sw_contacts_query_iface_return_from_open_view (context, object_path);
+}
+
+static void
_facebook_query_open_view (SwQueryIface *self,
const gchar *query,
GHashTable *params,
@@ -489,6 +531,14 @@ _facebook_query_open_view (SwQueryIface *self,
}
static void
+contacts_query_iface_init (gpointer g_iface, gpointer iface_data)
+{
+ SwContactsQueryIfaceClass *klass = (SwContactsQueryIfaceClass*) g_iface;
+
+ sw_contacts_query_iface_implement_open_view (klass, _facebook_contacts_query_open_view);
+}
+
+static void
query_iface_init (gpointer g_iface, gpointer iface_data)
{
SwQueryIfaceClass *klass = (SwQueryIfaceClass*) g_iface;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]