summaryrefslogtreecommitdiff
path: root/src/facebook-connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/facebook-connection.c')
-rw-r--r--src/facebook-connection.c179
1 files changed, 169 insertions, 10 deletions
diff --git a/src/facebook-connection.c b/src/facebook-connection.c
index d0fc959..5a02929 100644
--- a/src/facebook-connection.c
+++ b/src/facebook-connection.c
@@ -28,6 +28,7 @@
#include <rtcom-telepathy-glib/extensions.h>
#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/handle-repo-dynamic.h>
#include <telepathy-glib/handle-repo-static.h>
#include <telepathy-glib/interfaces.h>
@@ -62,6 +63,7 @@ struct _GruschlerFacebookConnectionPrivate {
GHashTable *group_channels;
GHashTable *list_channels;
+ GHashTable *profiles;
char *email;
char *password;
@@ -69,7 +71,10 @@ struct _GruschlerFacebookConnectionPrivate {
};
static void
-_channel_manager_iface_init (TpChannelManagerIface *iface);
+_channel_manager_iface_init (TpChannelManagerIface *iface);
+
+static void
+_aliasing_iface_init (TpSvcConnectionInterfaceAliasingClass *iface);
G_DEFINE_TYPE_WITH_CODE (GruschlerFacebookConnection,
gruschler_facebook_connection,
@@ -77,6 +82,9 @@ G_DEFINE_TYPE_WITH_CODE (GruschlerFacebookConnection,
G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER,
_channel_manager_iface_init);
+
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING,
+ _aliasing_iface_init);
);
static void
@@ -151,10 +159,10 @@ _finalize (GObject *object)
g_object_unref (self->priv->groups);
if (self->priv->lists)
g_object_unref (self->priv->lists);
- if (self->priv->list_channels)
- g_hash_table_unref (self->priv->list_channels);
- if (self->priv->group_channels)
- g_hash_table_unref (self->priv->group_channels);
+
+ g_hash_table_unref (self->priv->list_channels);
+ g_hash_table_unref (self->priv->group_channels);
+ g_hash_table_unref (self->priv->profiles);
g_free (self->priv->email);
g_free (self->priv->password);
@@ -336,12 +344,31 @@ _get_unique_connection_name (TpBaseConnection *connection)
}
const char *
-_get_uid (GruschlerFacebookConnection *self)
+_get_self_uid (GruschlerFacebookConnection *self)
{
return tp_handle_inspect (self->priv->contacts,
TP_BASE_CONNECTION (self)->self_handle);
}
+const char *
+_get_contact_alias (GruschlerFacebookConnection *self,
+ TpHandle handle)
+{
+ RestXmlNode *profile, *node = NULL;
+
+ profile = g_hash_table_lookup (self->priv->profiles,
+ GUINT_TO_POINTER (handle));
+
+ if (!profile)
+ return NULL;
+
+ if (NULL != (node = rest_xml_node_find (profile, "name")) ||
+ NULL != (node = rest_xml_node_find (profile, "uid")))
+ return node->content;
+
+ return NULL;
+}
+
static void
_report_network_error (GruschlerFacebookConnection *self)
{
@@ -443,7 +470,50 @@ static void
_update_profiles (GruschlerFacebookConnection *self,
RestXmlNode *result)
{
- /* TODO: read profiles to make aliasing interface work */
+ RestXmlNode *user, *uid, *name;
+ GValue entry = { 0, };
+ GPtrArray *aliases;
+ TpHandle handle;
+ int i;
+
+ g_value_init (&entry, TP_STRUCT_TYPE_ALIAS_PAIR);
+ g_value_take_boxed (&entry, dbus_g_type_specialized_construct
+ (TP_STRUCT_TYPE_ALIAS_PAIR));
+
+ aliases = g_ptr_array_new ();
+
+ for (user = rest_xml_node_find (result, "user"); user; user = user->next)
+ {
+ if (g_strcmp0 (user->name, "user"))
+ continue;
+
+ uid = rest_xml_node_find (user, "uid");
+ name = rest_xml_node_find (user, "name");
+
+ if (!uid)
+ continue;
+
+ handle = tp_handle_ensure (self->priv->contacts,
+ uid->content, NULL, NULL);
+
+ g_hash_table_insert (self->priv->profiles,
+ GUINT_TO_POINTER (handle),
+ rest_xml_node_ref (user));
+
+ dbus_g_type_struct_set (&entry, 0, handle,
+ 1, name ? name->content
+ : uid->content, G_MAXUINT);
+
+ g_ptr_array_add (aliases, g_value_dup_boxed (&entry));
+ }
+
+ tp_svc_connection_interface_aliasing_emit_aliases_changed (aliases, aliases);
+
+ for (i = 0; aliases->len; ++i)
+ g_boxed_free (TP_STRUCT_TYPE_ALIAS_PAIR, aliases->pdata[i]);
+
+ g_ptr_array_free (aliases, TRUE);
+ g_value_unset (&entry);
}
static void
@@ -502,7 +572,7 @@ _update_friends (GruschlerFacebookConnection *self)
g_string_append_printf (queries,
"\"uids\":"
"\"SELECT uid2 FROM friend WHERE uid1=%s\"",
- _get_uid (self));
+ _get_self_uid (self));
g_string_append_c (queries, ',');
@@ -510,7 +580,7 @@ _update_friends (GruschlerFacebookConnection *self)
"\"profiles\":"
"\"SELECT uid,name,profile_update_time "
"FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=%s)\"",
- _get_uid (self));
+ _get_self_uid (self));
/* TODO: "AND profile_update_time > 0" */
g_string_append_c (queries, '}');
@@ -845,8 +915,8 @@ static void
gruschler_facebook_connection_class_init (GruschlerFacebookConnectionClass *class)
{
static const char *interfaces[] = {
-#if 0
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
+#if 0
TP_IFACE_CONNECTION_INTERFACE_AVATARS,
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_CONTACTS,
@@ -1041,6 +1111,93 @@ _channel_manager_iface_init (TpChannelManagerIface *iface)
}
static void
+_aliasing_get_alias_flags (TpSvcConnectionInterfaceAliasing *aliasing,
+ DBusGMethodInvocation *context)
+{
+ tp_svc_connection_interface_aliasing_return_from_get_alias_flags (context, 0);
+}
+
+static void
+_aliasing_request_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
+ const GArray *contacts,
+ DBusGMethodInvocation *context)
+{
+ GruschlerFacebookConnection *self;
+ const char **aliases;
+ TpHandle handle;
+ int i;
+
+ self = GRUSCHLER_FACEBOOK_CONNECTION (aliasing);
+ aliases = g_new0 (const char *, contacts->len + 1);
+
+ for (i = 0; i < contacts->len; ++i)
+ {
+ handle = g_array_index (contacts, TpHandle, i);
+ aliases[i] = _get_contact_alias (self, handle);
+ }
+
+ tp_svc_connection_interface_aliasing_return_from_request_aliases (context, aliases);
+
+ g_free (aliases);
+}
+
+static void
+_aliasing_get_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
+ const GArray *contacts,
+ DBusGMethodInvocation *context)
+{
+ GruschlerFacebookConnection *self;
+ GHashTable *aliases;
+ TpHandle handle;
+ const char *name;
+ int i;
+
+ self = GRUSCHLER_FACEBOOK_CONNECTION (aliasing);
+ aliases = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+
+ for (i = 0; i < contacts->len; ++i)
+ {
+ handle = g_array_index (contacts, TpHandle, i);
+ name = _get_contact_alias (self, handle);
+
+ if (!name)
+ continue;
+
+ g_hash_table_insert (aliases,
+ GUINT_TO_POINTER (handle),
+ g_strdup (name));
+ }
+
+ tp_svc_connection_interface_aliasing_return_from_get_aliases (context, aliases);
+ g_hash_table_unref (aliases);
+}
+
+static void
+_aliasing_set_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
+ GHashTable *aliases,
+ DBusGMethodInvocation *context)
+{
+ GError error = {
+ TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
+ "you cannot modify Facebook aliases"
+ };
+
+ dbus_g_method_return_error (context, &error);
+}
+
+static void
+_aliasing_iface_init (TpSvcConnectionInterfaceAliasingClass *iface)
+{
+#define IMPLEMENT(x) \
+ tp_svc_connection_interface_aliasing_implement_##x (iface, _aliasing_##x)
+ IMPLEMENT (get_alias_flags);
+ IMPLEMENT (request_aliases);
+ IMPLEMENT (get_aliases);
+ IMPLEMENT (set_aliases);
+#undef IMPLEMENT
+}
+
+static void
gruschler_facebook_connection_init (GruschlerFacebookConnection *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
@@ -1051,6 +1208,8 @@ gruschler_facebook_connection_init (GruschlerFacebookConnection *self)
(g_direct_hash, g_direct_equal, NULL, g_object_unref);
self->priv->group_channels = g_hash_table_new_full
(g_direct_hash, g_direct_equal, NULL, g_object_unref);
+ self->priv->profiles = g_hash_table_new_full
+ (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) rest_xml_node_unref);
}
TpBaseConnection *