/soc/2015/jgeboski/facebook: e4d77bc25235: facebook: add and ali...
James Geboski
jgeboski at gmail.com
Tue Aug 11 00:37:25 EDT 2015
Changeset: e4d77bc252352415fee25f467a2532410c4e085e
Author: James Geboski <jgeboski at gmail.com>
Date: 2015-08-11 00:37 -0400
Branch: facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/e4d77bc25235
Description:
facebook: add and alias non-friend buddies
diffstat:
libpurple/glibcompat.h | 6 +
libpurple/protocols/facebook/api.c | 176 ++++++++++++++++++++++++++------
libpurple/protocols/facebook/api.h | 4 +
libpurple/protocols/facebook/data.c | 42 +++++++
libpurple/protocols/facebook/data.h | 7 +
libpurple/protocols/facebook/facebook.c | 103 ++++++++++++++++++-
6 files changed, 304 insertions(+), 34 deletions(-)
diffs (truncated from 538 to 300 lines):
diff --git a/libpurple/glibcompat.h b/libpurple/glibcompat.h
--- a/libpurple/glibcompat.h
+++ b/libpurple/glibcompat.h
@@ -105,6 +105,12 @@ static inline GByteArray * g_byte_array_
return array;
}
+static inline void g_queue_free_full(GQueue *queue, GDestroyNotify free_func)
+{
+ g_queue_foreach(queue, (GFunc)free_func, NULL);
+ g_queue_free(queue);
+}
+
static inline GThread * g_thread_try_new(const gchar *name, GThreadFunc func,
gpointer data, GError **error)
{
diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c
--- a/libpurple/protocols/facebook/api.c
+++ b/libpurple/protocols/facebook/api.c
@@ -224,6 +224,14 @@ fb_api_class_init(FbApiClass *klass)
fb_marshal_VOID__VOID,
G_TYPE_NONE,
0);
+ g_signal_new("contact",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_ACTION,
+ 0,
+ NULL, NULL,
+ fb_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1, G_TYPE_POINTER);
g_signal_new("contacts",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_ACTION,
@@ -352,6 +360,8 @@ fb_api_json_chk(FbApi *api, gconstpointe
return FALSE;
}
+ g_print("JSON: %.*s\n", (gint) size, (gchar*) data);
+
root = fb_json_node_new(data, size, &err);
FB_API_ERROR_EMIT(api, err, return FALSE);
@@ -549,6 +559,9 @@ fb_api_http_query(FbApi *api, gint64 que
gchar *json;
switch (query) {
+ case FB_API_QUERY_CONTACT:
+ name = "FetchContactQuery";
+ break;
case FB_API_QUERY_CONTACTS:
name = "FetchContactsFullQuery";
break;
@@ -1549,15 +1562,129 @@ fb_api_auth(FbApi *api, const gchar *use
prms, fb_api_cb_auth);
}
+static gboolean
+fb_api_contact_parse(FbApi *api, FbApiUser *user, JsonNode *root,
+ GError **error)
+{
+ const gchar *str;
+ FbApiPrivate *priv = api->priv;
+ FbHttpParams *params;
+ FbJsonValues *values;
+ GError *err = NULL;
+
+ values = fb_json_values_new(root);
+ fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
+ "$.represented_profile.id");
+ fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
+ "$.id");
+ fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
+ "$.represented_profile.friendship_status");
+ fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
+ "$.structured_name.text");
+ fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
+ "$.hugePictureUrl.uri");
+ fb_json_values_update(values, &err);
+
+ if (G_UNLIKELY(err != NULL)) {
+ g_propagate_error(error, err);
+ fb_json_values_free(values);
+ return FALSE;
+ }
+
+ str = fb_json_values_next_str(values, NULL);
+
+ if (str == NULL) {
+ str = fb_json_values_next_str(values, "0");
+ } else {
+ fb_json_values_next_str(values, NULL);
+ }
+
+ user->uid = FB_ID_FROM_STR(str);
+ str = fb_json_values_next_str(values, NULL);
+
+ if ((str != NULL) &&
+ !purple_strequal(str, "ARE_FRIENDS") &&
+ (user->uid != priv->uid))
+ {
+ return FALSE;
+ }
+
+ user->name = fb_json_values_next_str_dup(values, NULL);
+ user->icon = fb_json_values_next_str_dup(values, NULL);
+
+ params = fb_http_params_new_parse(user->icon, TRUE);
+ user->csum = fb_http_params_dup_str(params, "oh", &err);
+ fb_http_params_free(params);
+
+ fb_json_values_free(values);
+ return TRUE;
+}
+
+static void
+fb_api_cb_contact(PurpleHttpConnection *con, PurpleHttpResponse *res,
+ gpointer data)
+{
+ FbApi *api = data;
+ FbApiUser user;
+ GError *err = NULL;
+ JsonNode *node;
+ JsonNode *root;
+
+ if (!fb_api_http_chk(api, con, res, &root)) {
+ return;
+ }
+
+ node = fb_json_node_get_nth(root, 0);
+
+ if (node == NULL) {
+ fb_api_error(api, FB_API_ERROR_GENERAL,
+ _("Failed to obtain contact information"));
+ json_node_free(root);
+ return;
+ }
+
+ fb_api_user_reset(&user, FALSE);
+
+ if (!fb_api_contact_parse(api, &user, node, &err)) {
+ if (G_LIKELY(err == NULL)) {
+ fb_api_error(api, FB_API_ERROR_GENERAL,
+ _("Failed to parse contact information"));
+ } else {
+ fb_api_error_emit(api, err);
+ }
+ } else {
+ g_signal_emit_by_name(api, "contact", &user);
+ }
+
+ fb_api_user_reset(&user, TRUE);
+ json_node_free(root);
+}
+
+void
+fb_api_contact(FbApi *api, FbId uid)
+{
+ JsonBuilder *bldr;
+
+ /* Object key mapping:
+ * 0: contact_id
+ * 1: big_img_size
+ * 2: huge_img_size
+ * 3: small_img_size
+ * 4: low_res_cover_size
+ * 6: media_type
+ */
+
+ bldr = fb_json_bldr_new(JSON_NODE_OBJECT);
+ fb_json_bldr_add_strf(bldr, "0", "%" FB_ID_FORMAT, uid);
+ fb_api_http_query(api, FB_API_QUERY_CONTACT, bldr, fb_api_cb_contact);
+}
+
static void
fb_api_cb_contacts(PurpleHttpConnection *con, PurpleHttpResponse *res,
gpointer data)
{
- const gchar *str;
FbApi *api = data;
- FbApiPrivate *priv = api->priv;
FbApiUser user;
- FbHttpParams *params;
FbJsonValues *values;
gboolean complete;
gchar *writeid = NULL;
@@ -1565,6 +1692,7 @@ fb_api_cb_contacts(PurpleHttpConnection
gpointer mptr;
GSList *users = NULL;
guint count = 0;
+ JsonNode *node;
JsonNode *root;
if (!fb_api_http_chk(api, con, res, &root)) {
@@ -1573,44 +1701,26 @@ fb_api_cb_contacts(PurpleHttpConnection
values = fb_json_values_new(root);
fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
- "$.represented_profile.id");
- fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
"$.graph_api_write_id");
- fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
- "$.represented_profile.friendship_status");
- fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
- "$.structured_name.text");
- fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE,
- "$.hugePictureUrl.uri");
fb_json_values_set_array(values, FALSE, "$.viewer.messenger_contacts"
".nodes");
while (fb_json_values_update(values, &err)) {
+ g_free(writeid);
+ count++;
+
+ writeid = fb_json_values_next_str_dup(values, NULL);
+ node = fb_json_values_get_root(values);
fb_api_user_reset(&user, FALSE);
- str = fb_json_values_next_str(values, NULL);
- user.uid = FB_ID_FROM_STR(str);
- count++;
-
- g_free(writeid);
- writeid = fb_json_values_next_str_dup(values, NULL);
- str = fb_json_values_next_str(values, NULL);
-
- if (!purple_strequal(str, "ARE_FRIENDS") &&
- (user.uid != priv->uid))
- {
- continue;
+
+ if (fb_api_contact_parse(api, &user, node, &err)) {
+ mptr = fb_api_user_dup(&user, FALSE);
+ users = g_slist_prepend(users, mptr);
}
- user.name = fb_json_values_next_str_dup(values, NULL);
- user.icon = fb_json_values_next_str_dup(values, NULL);
-
- params = fb_http_params_new_parse(user.icon, TRUE);
- str = fb_http_params_get_str(params, "oh", &err);
- user.csum = g_strdup(str);
- fb_http_params_free(params);
-
- mptr = fb_api_user_dup(&user, FALSE);
- users = g_slist_prepend(users, mptr);
+ if (G_UNLIKELY(err != NULL)) {
+ break;
+ }
}
complete = (writeid == NULL) || (count < FB_API_CONTACTS_COUNT);
diff --git a/libpurple/protocols/facebook/api.h b/libpurple/protocols/facebook/api.h
--- a/libpurple/protocols/facebook/api.h
+++ b/libpurple/protocols/facebook/api.h
@@ -49,6 +49,7 @@
#define FB_API_URL_THREADS FB_API_GHOST "/me/threads"
#define FB_API_URL_TOPIC FB_API_AHOST "/method/messaging.setthreadname"
+#define FB_API_QUERY_CONTACT 10153746900701729
#define FB_API_QUERY_CONTACTS 10153856456271729
#define FB_API_QUERY_CONTACTS_AFTER 10153856456281729
#define FB_API_QUERY_THREAD 10153919752036729
@@ -183,6 +184,9 @@ void
fb_api_auth(FbApi *api, const gchar *user, const gchar *pass);
void
+fb_api_contact(FbApi *api, FbId uid);
+
+void
fb_api_contacts(FbApi *api);
void
diff --git a/libpurple/protocols/facebook/data.c b/libpurple/protocols/facebook/data.c
--- a/libpurple/protocols/facebook/data.c
+++ b/libpurple/protocols/facebook/data.c
@@ -32,6 +32,7 @@ struct _FbDataPrivate
FbApi *api;
PurpleConnection *gc;
PurpleRoomlist *roomlist;
+ GQueue *msgs;
GHashTable *icons;
GHashTable *icona;
};
@@ -57,6 +58,7 @@ fb_data_dispose(GObject *obj)
g_object_unref(priv->api);
}
+ g_queue_free_full(priv->msgs, (GDestroyNotify) fb_api_message_free);
g_hash_table_destroy(priv->icons);
g_hash_table_destroy(priv->icona);
}
@@ -78,6 +80,7 @@ fb_data_init(FbData *fata)
priv = G_TYPE_INSTANCE_GET_PRIVATE(fata, FB_TYPE_DATA, FbDataPrivate);
fata->priv = priv;
+ priv->msgs = g_queue_new();
priv->icons = g_hash_table_new_full(g_direct_hash, g_direct_equal,
(GDestroyNotify) fb_data_icon_free,
NULL);
@@ -246,6 +249,45 @@ fb_data_set_roomlist(FbData *fata, Purpl
More information about the Commits
mailing list