/soc/2015/jgeboski/facebook: ebcd09a1a124: facebook: display sti...
James Geboski
jgeboski at gmail.com
Fri Aug 21 00:18:02 EDT 2015
Changeset: ebcd09a1a124032cd6c31a5d2716b5d87d71c1e4
Author: James Geboski <jgeboski at gmail.com>
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
More information about the Commits
mailing list