/soc/2015/jgeboski/facebook: e4d77bc25235: facebook: add and ali...
James Geboski <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: e4d77bc252352415fee25f467a2532410c4e085e Author: James Geboski <[email protected]> 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 _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits