/soc/2015/jgeboski/facebook: 2d832af0f400: facebook: fetch URLs ...

James Geboski jgeboski at gmail.com
Fri Aug 21 00:41:48 EDT 2015


Changeset: 2d832af0f400693559e3c96793b55c11533891b3
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-08-21 00:41 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/2d832af0f400

Description:

facebook: fetch URLs for all messages attachments

diffstat:

 libpurple/protocols/facebook/api.c |  249 ++++++++++++++++++++----------------
 libpurple/protocols/facebook/api.h |    8 +
 2 files changed, 143 insertions(+), 114 deletions(-)

diffs (truncated from 451 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
@@ -62,7 +62,7 @@ struct _FbApiPrivate
 	gchar *stoken;
 	gchar *token;
 
-	GHashTable *msgids;
+	GHashTable *mids;
 	gboolean invisible;
 	guint unread;
 
@@ -75,6 +75,9 @@ struct _FbApiData
 };
 
 static void
+fb_api_attach(FbApi *api, FbId aid, const gchar *msgid, FbApiMessage *msg);
+
+static void
 fb_api_contacts_after(FbApi *api, const gchar *writeid);
 
 static void
@@ -173,7 +176,7 @@ fb_api_dispose(GObject *obj)
 	}
 
 	g_hash_table_destroy(priv->data);
-	g_hash_table_destroy(priv->msgids);
+	g_hash_table_destroy(priv->mids);
 
 	g_free(priv->cid);
 	g_free(priv->did);
@@ -484,8 +487,8 @@ fb_api_init(FbApi *api)
 
 	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);
+	priv->mids = g_hash_table_new_full(g_int64_hash, g_int64_equal,
+	                                   g_free, NULL);
 }
 
 GQuark
@@ -943,18 +946,6 @@ fb_api_connect_queue(FbApi *api)
 		fb_json_bldr_add_str(bldr, "device_id", priv->did);
 		fb_json_bldr_add_int(bldr, "entity_fbid", priv->uid);
 
-		fb_json_bldr_obj_begin(bldr, "device_params");
-		fb_json_bldr_add_str(bldr, "animated_image_format", "GIF");
-
-		fb_json_bldr_obj_begin(bldr, "animated_image_sizes");
-		fb_json_bldr_add_str(bldr, "0", "9001x9001");
-		fb_json_bldr_obj_end(bldr);
-
-		fb_json_bldr_obj_begin(bldr, "image_sizes");
-		fb_json_bldr_add_str(bldr, "0", "9001x9001");
-		fb_json_bldr_obj_end(bldr);
-		fb_json_bldr_obj_end(bldr);
-
 		fb_json_bldr_obj_begin(bldr, "queue_params");
 		fb_json_bldr_add_str(bldr, "buzz_on_deltas_enabled", "false");
 
@@ -966,8 +957,6 @@ fb_api_connect_queue(FbApi *api)
 		fb_json_bldr_obj_begin(bldr, "graphql_query_params");
 		fb_json_bldr_obj_begin(bldr, G_STRINGIFY(FB_API_QUERY_XMA));
 		fb_json_bldr_add_str(bldr, "xma_id", "<ID>");
-		fb_json_bldr_add_str(bldr, "small_preview_size", "9001");
-		fb_json_bldr_add_str(bldr, "large_preview_size", "9001");
 		fb_json_bldr_obj_end(bldr);
 		fb_json_bldr_obj_end(bldr);
 		fb_json_bldr_obj_end(bldr);
@@ -1279,12 +1268,13 @@ fb_api_xma_parse(FbApi *api, const gchar
 }
 
 static GSList *
-fb_api_message_parse_attach(FbApi *api, FbApiMessage *msg, GSList *msgs,
-                            const gchar *body, JsonNode *root, GError **error)
+fb_api_message_parse_attach(FbApi *api, const gchar *mid, FbApiMessage *msg,
+                            GSList *msgs, const gchar *body, JsonNode *root,
+                            GError **error)
 {
 	const gchar *str;
-	const gchar *url;
 	FbApiMessage *dmsg;
+	FbId id;
 	FbJsonValues *values;
 	gchar *xma;
 	GError *err = NULL;
@@ -1292,64 +1282,41 @@ fb_api_message_parse_attach(FbApi *api, 
 	JsonNode *xode;
 
 	values = fb_json_values_new(root);
-	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, "$.mimeType");
-	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
-	                   "$.imageMetadata.imageURIMap.0");
 	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, "$.xmaGraphQL");
-	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, "$.filename");
+	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE, "$.fbid");
 	fb_json_values_set_array(values, FALSE, "$.deltaNewMessage"
 	                                         ".attachments");
 
 	while (fb_json_values_update(values, &err)) {
 		str = fb_json_values_next_str(values, NULL);
-		url = fb_json_values_next_str(values, NULL);
-
-		if ((str != NULL) && g_str_has_prefix(str, "image/")) {
+
+		if (str == NULL) {
+			id = fb_json_values_next_int(values, 0);
 			dmsg = fb_api_message_dup(msg, FALSE);
-			dmsg->flags |= FB_API_MESSAGE_FLAG_IMAGE;
-			dmsg->text = g_strdup(url);
-			msgs = g_slist_prepend(msgs, dmsg);
+			fb_api_attach(api, id, mid, dmsg);
 			continue;
 		}
 
-		str = fb_json_values_next_str(values, NULL);
-
-		if (str != NULL) {
-			node = fb_json_node_new(str, -1, &err);
-
-			if (G_UNLIKELY(err != NULL)) {
-				break;
-			}
-
-			xode = fb_json_node_get_nth(node, 0);
-			xma = fb_api_xma_parse(api, body, xode, &err);
-
-			if (xma != NULL) {
-				dmsg = fb_api_message_dup(msg, FALSE);
-				dmsg->text = xma;
-				msgs = g_slist_prepend(msgs, dmsg);
-			}
-
-			json_node_free(node);
-
-			if (G_UNLIKELY(err != NULL)) {
-				break;
-			}
-
-			continue;
+		node = fb_json_node_new(str, -1, &err);
+
+		if (G_UNLIKELY(err != NULL)) {
+			break;
 		}
 
-		str = fb_json_values_next_str(values, NULL);
-
-		if (G_UNLIKELY(str == NULL)) {
-			str = _("unknown attachment");
+		xode = fb_json_node_get_nth(node, 0);
+		xma = fb_api_xma_parse(api, body, xode, &err);
+
+		if (xma != NULL) {
+			dmsg = fb_api_message_dup(msg, FALSE);
+			dmsg->text = xma;
+			msgs = g_slist_prepend(msgs, dmsg);
 		}
 
-		dmsg = fb_api_message_dup(msg, FALSE);
-		dmsg->text = g_strdup_printf("%s/%" FB_ID_FORMAT " [%s]",
-		                             FB_API_URL_MESSAGES,
-		                             msg->uid, str);
-		msgs = g_slist_prepend(msgs, dmsg);
+		json_node_free(node);
+
+		if (G_UNLIKELY(err != NULL)) {
+			break;
+		}
 	}
 
 	if (G_UNLIKELY(err != NULL)) {
@@ -1365,6 +1332,7 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr
 {
 	const gchar *body;
 	const gchar *data;
+	const gchar *str;
 	FbApiMessage *dmsg;
 	FbApiMessage msg;
 	FbApiPrivate *priv = api->priv;
@@ -1373,10 +1341,8 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr
 	FbId uid;
 	FbJsonValues *values;
 	FbThrift *thft;
-	gchar *json;
 	gchar *stoken;
 	GError *err = NULL;
-	GRegex *regex;
 	GSList *msgs = NULL;
 	guint size;
 	JsonNode *root;
@@ -1388,22 +1354,13 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr
 	g_object_unref(thft);
 
 	g_return_if_fail(size < pload->len);
-
 	data = (gchar *) pload->data + size;
 	size = pload->len - size;
 
-	/* Ugly hack to fix broken JSON from Facebook */
-	regex = g_regex_new("(\\d+)(:\")", 0, 0, &err);
-	json = g_regex_replace(regex, data, size, 0, "\"\\1\"\\2", 0, &err);
-	g_regex_unref(regex);
-	FB_API_ERROR_EMIT(api, err, return);
-
-	if (!fb_api_json_chk(api, json, -1, &root)) {
-		g_free(json);
+	if (!fb_api_json_chk(api, data, size, &root)) {
 		return;
 	}
 
-	g_free(json);
 	values = fb_json_values_new(root);
 	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
 	                   "$.lastIssuedSeqId");
@@ -1444,12 +1401,14 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr
 	                   "$.deltaNewMessage.body");
 	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
 	                   "$.deltaNewMessage.stickerId");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
+	                   "$.deltaNewMessage.messageMetadata.messageId");
 	fb_json_values_set_array(values, TRUE, "$.deltas");
 
 	while (fb_json_values_update(values, &err)) {
 		id = fb_json_values_next_int(values, 0);
 
-		if (g_hash_table_remove(priv->msgids, &id)) {
+		if (g_hash_table_remove(priv->mids, &id)) {
 			continue;
 		}
 
@@ -1484,8 +1443,14 @@ fb_api_cb_publish_ms(FbApi *api, GByteAr
 			fb_api_sticker(api, id, dmsg);
 		}
 
+		str = fb_json_values_next_str(values, NULL);
+
+		if (str == NULL) {
+			continue;
+		}
+
 		node = fb_json_values_get_root(values);
-		msgs = fb_api_message_parse_attach(api, &msg, msgs, body,
+		msgs = fb_api_message_parse_attach(api, str, &msg, msgs, body,
 		                                   node, &err);
 
 		if (G_UNLIKELY(err != NULL)) {
@@ -1735,6 +1700,75 @@ fb_api_error_emit(FbApi *api, GError *er
 }
 
 static void
+fb_api_cb_attach(PurpleHttpConnection *con, PurpleHttpResponse *res,
+                 gpointer data)
+{
+	const gchar *str;
+	FbApi *api = data;
+	FbApiMessage *msg;
+	FbJsonValues *values;
+	gchar *name;
+	GError *err = NULL;
+	GSList *msgs = NULL;
+	guint i;
+	JsonNode *root;
+
+	static const gchar *imgexts[] = {".jpg", ".png", ".gif"};
+
+	if (!fb_api_http_chk(api, con, res, &root)) {
+		return;
+	}
+
+	values = fb_json_values_new(root);
+	fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE, "$.filename");
+	fb_json_values_add(values, FB_JSON_TYPE_STR, TRUE, "$.redirect_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);
+	str = fb_json_values_next_str(values, NULL);
+	name = g_ascii_strdown(str, -1);
+
+	for (i = 0; i < G_N_ELEMENTS(imgexts); i++) {
+		if (g_str_has_suffix(name, imgexts[i])) {
+			msg->flags |= FB_API_MESSAGE_FLAG_IMAGE;
+			break;
+		}
+	}
+
+	g_free(name);
+	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);



More information about the Commits mailing list