/soc/2015/jgeboski/facebook: ebcd09a1a124: facebook: display sti...
James Geboski <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: ebcd09a1a124032cd6c31a5d2716b5d87d71c1e4 Author: James Geboski <[email protected]> Date: 2015-08-20 21:45 -0400 Branch: facebook URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/ebcd09a1a124 Description: facebook: display stickers in-line diffstat: libpurple/protocols/facebook/api.c | 152 ++++++++++++++++++++++++++++++++---- libpurple/protocols/facebook/api.h | 14 +- 2 files changed, 140 insertions(+), 26 deletions(-) diffs (truncated from 311 to 300 lines): 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 @@ -32,6 +32,8 @@ #include "thrift.h" #include "util.h" +typedef struct _FbApiData FbApiData; + enum { PROP_0, @@ -50,6 +52,7 @@ struct _FbApiPrivate { PurpleConnection *gc; FbMqtt *mqtt; + GHashTable *data; FbId uid; gint64 sid; @@ -65,9 +68,18 @@ struct _FbApiPrivate }; +struct _FbApiData +{ + gpointer data; + GDestroyNotify func; +}; + static void fb_api_contacts_after(FbApi *api, const gchar *writeid); +static void +fb_api_sticker(FbApi *api, FbId sid, FbApiMessage *msg); + G_DEFINE_TYPE(FbApi, fb_api, G_TYPE_OBJECT); static void @@ -141,7 +153,16 @@ fb_api_get_property(GObject *obj, guint static void fb_api_dispose(GObject *obj) { + FbApiData *fata; FbApiPrivate *priv = FB_API(obj)->priv; + GHashTableIter iter; + + g_hash_table_iter_init(&iter, priv->data); + + while (g_hash_table_iter_next(&iter, NULL, (gpointer) &fata)) { + fata->func(fata->data); + g_free(fata); + } if (G_LIKELY(priv->gc != NULL)) { purple_http_conn_cancel_all(priv->gc); @@ -151,6 +172,7 @@ fb_api_dispose(GObject *obj) g_object_unref(priv->mqtt); } + g_hash_table_destroy(priv->data); g_hash_table_destroy(priv->msgids); g_free(priv->cid); @@ -460,6 +482,8 @@ fb_api_init(FbApi *api) priv = G_TYPE_INSTANCE_GET_PRIVATE(api, FB_TYPE_API, FbApiPrivate); api->priv = priv; + priv->data = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, NULL); priv->msgids = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, NULL); } @@ -476,6 +500,38 @@ fb_api_error_quark(void) return q; } +static void +fb_api_data_set(FbApi *api, gpointer handle, gpointer data, + GDestroyNotify func) +{ + FbApiData *fata; + FbApiPrivate *priv = api->priv; + + fata = g_new0(FbApiData, 1); + fata->data = data; + fata->func = func; + g_hash_table_replace(priv->data, handle, fata); +} + +static gpointer +fb_api_data_take(FbApi *api, gconstpointer handle) +{ + FbApiData *fata; + FbApiPrivate *priv = api->priv; + gpointer data; + + fata = g_hash_table_lookup(priv->data, handle); + + if (fata == NULL) { + return NULL; + } + + data = fata->data; + g_hash_table_remove(priv->data, handle); + g_free(fata); + return data; +} + static gboolean fb_api_json_chk(FbApi *api, gconstpointer data, gssize size, JsonNode **node) { @@ -706,9 +762,9 @@ fb_api_http_req(FbApi *api, const gchar return ret; } -static void +static PurpleHttpConnection * fb_api_http_query(FbApi *api, gint64 query, JsonBuilder *builder, - PurpleHttpCallback callback) + PurpleHttpCallback hcb) { const gchar *name; FbHttpParams *prms; @@ -724,6 +780,9 @@ fb_api_http_query(FbApi *api, gint64 que case FB_API_QUERY_CONTACTS_AFTER: name = "FetchContactsFullWithAfterQuery"; break; + case FB_API_QUERY_STICKER: + name = "FetchStickersWithPreviewsQuery"; + break; case FB_API_QUERY_THREAD: name = "ThreadQuery"; break; @@ -734,8 +793,8 @@ fb_api_http_query(FbApi *api, gint64 que name = "XMAQuery"; break; default: - g_return_if_reached(); - return; + g_return_val_if_reached(NULL); + return NULL; } prms = fb_http_params_new(); @@ -743,9 +802,9 @@ fb_api_http_query(FbApi *api, gint64 que fb_http_params_set_strf(prms, "query_id", "%" G_GINT64_FORMAT, query); fb_http_params_set_str(prms, "query_params", json); - fb_api_http_req(api, FB_API_URL_GQL, name, "get", prms, callback); - g_free(json); + + return fb_api_http_req(api, FB_API_URL_GQL, name, "get", prms, hcb); } static void @@ -1309,7 +1368,7 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr FbApiMessage *dmsg; FbApiMessage msg; FbApiPrivate *priv = api->priv; - FbHttpParams *params; + FbId id; FbId oid; FbId uid; FbJsonValues *values; @@ -1317,7 +1376,6 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr gchar *json; gchar *stoken; GError *err = NULL; - gint64 id; GRegex *regex; GSList *msgs = NULL; guint size; @@ -1423,11 +1481,7 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr if (id != 0) { dmsg = fb_api_message_dup(&msg, FALSE); - params = fb_http_params_new(); - fb_http_params_set_int(params, "sticker_id", id); - dmsg->text = fb_http_params_close(params, - FB_API_URL_STICKER); - msgs = g_slist_prepend(msgs, dmsg); + fb_api_sticker(api, id, dmsg); } node = fb_json_values_get_root(values); @@ -2131,7 +2185,7 @@ fb_api_cb_unread_msgs(PurpleHttpConnecti FbApi *api = data; FbApiMessage *dmsg; FbApiMessage msg; - FbHttpParams *params; + FbId id; FbId tid; FbJsonValues *values; gchar *xma; @@ -2199,11 +2253,8 @@ fb_api_cb_unread_msgs(PurpleHttpConnecti if (str != NULL) { dmsg = fb_api_message_dup(&msg, FALSE); - params = fb_http_params_new(); - fb_http_params_set_str(params, "sticker_id", str); - dmsg->text = fb_http_params_close(params, - FB_API_URL_STICKER); - msgs = g_slist_prepend(msgs, dmsg); + id = FB_ID_FROM_STR(str); + fb_api_sticker(api, id, dmsg); } node = fb_json_values_get_root(values); @@ -2328,6 +2379,69 @@ fb_api_unread(FbApi *api) fb_api_cb_unread); } +static void +fb_api_cb_sticker(PurpleHttpConnection *con, PurpleHttpResponse *res, + gpointer data) +{ + FbApi *api = data; + FbApiMessage *msg; + FbJsonValues *values; + GError *err = NULL; + GSList *msgs = NULL; + JsonNode *node; + JsonNode *root; + + if (!fb_api_http_chk(api, con, res, &root)) { + return; + } + + node = fb_json_node_get_nth(root, 0); + values = fb_json_values_new(node); + fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE, + "$.thread_image.uri"); + fb_json_values_update(values, &err); + + FB_API_ERROR_EMIT(api, err, + g_object_unref(values); + json_node_free(root); + return; + ); + + msg = fb_api_data_take(api, con); + msg->flags |= FB_API_MESSAGE_FLAG_IMAGE; + msg->text = fb_json_values_next_str_dup(values, NULL); + msgs = g_slist_prepend(msgs, msg); + + g_signal_emit_by_name(api, "messages", msgs); + g_slist_free_full(msgs, (GDestroyNotify) fb_api_message_free); + g_object_unref(values); + json_node_free(root); +} + +static void +fb_api_sticker(FbApi *api, FbId sid, FbApiMessage *msg) +{ + JsonBuilder *bldr; + PurpleHttpConnection *http; + + /* Object key mapping: + * 0: sticker_ids + * 1: media_type + * 2: preview_size + * 3: scaling_factor + * 4: animated_media_type + */ + + bldr = fb_json_bldr_new(JSON_NODE_OBJECT); + fb_json_bldr_arr_begin(bldr, "0"); + fb_json_bldr_add_strf(bldr, NULL, "%" FB_ID_FORMAT, sid); + fb_json_bldr_arr_end(bldr); + + http = fb_api_http_query(api, FB_API_QUERY_STICKER, bldr, + fb_api_cb_sticker); + fb_api_data_set(api, http, msg, (GDestroyNotify) fb_api_message_free); +} + static gboolean fb_api_thread_parse(FbApi *api, FbApiThread *thrd, JsonNode *root, GError **error) 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 @@ -119,13 +119,6 @@ #define FB_API_URL_PARTS FB_API_GHOST "/participants" /** - * FB_API_URL_STICKER: - * - * The URL for linking stickers. - */ -#define FB_API_URL_STICKER FB_API_WHOST "/stickers/asset/" - -/** * FB_API_URL_THREADS: * * The URL for thread management requests. @@ -161,6 +154,13 @@ #define FB_API_QUERY_CONTACTS_AFTER 10153856456281729 _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits