/soc/2015/jgeboski/facebook: 168a859417f6: facebook: implemented...

James Geboski jgeboski at gmail.com
Sun Jul 26 14:56:26 EDT 2015


Changeset: 168a859417f69f54f4338583586c6916669c622b
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-07-26 14:56 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/168a859417f6

Description:

facebook: implemented marking threads as read

diffstat:

 libpurple/protocols/facebook/api.c      |  77 ++++++++++++++++++++++++++++----
 libpurple/protocols/facebook/api.h      |   3 +
 libpurple/protocols/facebook/facebook.c |  18 +++++++
 3 files changed, 87 insertions(+), 11 deletions(-)

diffs (222 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
@@ -50,6 +50,7 @@ struct _FbApiPrivate
 	FbMqtt *mqtt;
 
 	FbId uid;
+	gint64 sid;
 	guint64 mid;
 	gchar *cid;
 	gchar *did;
@@ -551,7 +552,6 @@ fb_api_cb_seqid(PurpleHttpConnection *co
 	gchar *json;
 	gchar *str;
 	GError *err = NULL;
-	gint64 nid;
 	JsonBuilder *bldr;
 	JsonNode *root;
 
@@ -565,7 +565,7 @@ fb_api_cb_seqid(PurpleHttpConnection *co
 	str = fb_json_node_get_str(root, expr, &err);
 	json_node_free(root);
 	FB_API_ERROR_CHK(api, err, return);
-	nid = g_ascii_strtoll(str, NULL, 10);
+	priv->sid = g_ascii_strtoll(str, NULL, 10);
 	g_free(str);
 
 	bldr = fb_json_bldr_new(JSON_NODE_OBJECT);
@@ -575,7 +575,8 @@ fb_api_cb_seqid(PurpleHttpConnection *co
 	fb_json_bldr_add_str(bldr, "encoding", "JSON");
 
 	if (priv->stoken == NULL) {
-		fb_json_bldr_add_int(bldr, "initial_titan_sequence_id", nid);
+		fb_json_bldr_add_int(bldr, "initial_titan_sequence_id",
+		                     priv->sid);
 		fb_json_bldr_add_str(bldr, "device_id", priv->did);
 		fb_json_bldr_obj_begin(bldr, "device_params");
 		fb_json_bldr_obj_end(bldr);
@@ -587,7 +588,7 @@ fb_api_cb_seqid(PurpleHttpConnection *co
 		return;
 	}
 
-	fb_json_bldr_add_int(bldr, "last_seq_id", nid);
+	fb_json_bldr_add_int(bldr, "last_seq_id", priv->sid);
 	fb_json_bldr_add_str(bldr, "sync_token", priv->stoken);
 
 	json = fb_json_bldr_close(bldr, JSON_NODE_OBJECT, NULL);
@@ -643,7 +644,25 @@ fb_api_cb_mqtt_connect(FbMqtt *mqtt, gpo
 }
 
 static void
-fb_api_cb_publish_tn(FbApi *api, const GByteArray *pload)
+fb_api_cb_publish_mark(FbApi *api, const GByteArray *pload)
+{
+	gboolean res;
+	JsonNode *root;
+
+	if (!fb_api_json_chk(api, pload->data, pload->len, &root)) {
+		return;
+	}
+
+	if (fb_json_node_chk_bool(root, "$.succeeded", &res) && !res) {
+		fb_api_error(api, FB_API_ERROR_GENERAL,
+		             _("Failed to mark thread as read"));
+	}
+
+	json_node_free(root);
+}
+
+static void
+fb_api_cb_publish_typing(FbApi *api, const GByteArray *pload)
 {
 	FbApiTyping typg;
 	gboolean res;
@@ -712,6 +731,8 @@ fb_api_cb_publish_ms(FbApi *api, const G
 		goto finish;
 	}
 
+	fb_json_node_chk_int(root, "$.lastIssuedSeqId", &priv->sid);
+
 	arr = fb_json_node_get_arr(root, "$.deltas", &err);
 	FB_API_ERROR_CHK(api, err, goto finish);
 	elms = json_array_get_elements(arr);
@@ -863,6 +884,17 @@ fb_api_cb_mqtt_publish(FbMqtt *mqtt, con
 	FbApi *api = data;
 	gboolean comp;
 	GByteArray *bytes;
+	guint i;
+
+	static const struct {
+		const gchar *topic;
+		void (*func) (FbApi *api, const GByteArray *pload);
+	} parsers[] = {
+		{"/mark_thread_response", fb_api_cb_publish_mark},
+		{"/orca_typing_notifications", fb_api_cb_publish_typing},
+		{"/t_ms", fb_api_cb_publish_ms},
+		{"/t_p", fb_api_cb_publish_p}
+	};
 
 	comp = fb_util_zcompressed(pload);
 
@@ -882,12 +914,11 @@ fb_api_cb_mqtt_publish(FbMqtt *mqtt, con
 	                      "Reading message (topic: %s)",
 			      topic);
 
-	if (g_ascii_strcasecmp(topic, "/orca_typing_notifications") == 0) {
-		fb_api_cb_publish_tn(api, bytes);
-	} else if (g_ascii_strcasecmp(topic, "/t_ms") == 0) {
-		fb_api_cb_publish_ms(api, bytes);
-	} else if (g_ascii_strcasecmp(topic, "/t_p") == 0) {
-		fb_api_cb_publish_p(api, bytes);
+	for (i = 0; i < G_N_ELEMENTS(parsers); i++) {
+		if (g_ascii_strcasecmp(topic, parsers[i].topic) == 0) {
+			parsers[i].func(api, bytes);
+			break;
+		}
 	}
 
 	if (G_LIKELY(comp)) {
@@ -1242,6 +1273,30 @@ fb_api_publish(FbApi *api, const gchar *
 	g_byte_array_free(bytes, TRUE);
 }
 
+void
+fb_api_read(FbApi *api, FbId id, gboolean thread)
+{
+	const gchar *key;
+	FbApiPrivate *priv;
+	gchar *json;
+	JsonBuilder *bldr;
+
+	g_return_if_fail(FB_IS_API(api));
+	priv = api->priv;
+
+	bldr = fb_json_bldr_new(JSON_NODE_OBJECT);
+	fb_json_bldr_add_bool(bldr, "state", TRUE);
+	fb_json_bldr_add_int(bldr, "syncSeqId", priv->sid);
+	fb_json_bldr_add_str(bldr, "mark", "read");
+
+	key = thread ? "threadFbId" : "otherUserFbId";
+	fb_json_bldr_add_strf(bldr, key, "%" FB_ID_FORMAT, id);
+
+	json = fb_json_bldr_close(bldr, JSON_NODE_OBJECT, NULL);
+	fb_api_publish(api, "/mark_thread", "%s", json);
+	g_free(json);
+}
+
 static void
 fb_api_cb_thread_create(PurpleHttpConnection *con, PurpleHttpResponse *res,
                         gpointer data)
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
@@ -183,6 +183,9 @@ fb_api_publish(FbApi *api, const gchar *
                G_GNUC_PRINTF(3, 4);
 
 void
+fb_api_read(FbApi *api, FbId id, gboolean thread);
+
+void
 fb_api_thread_create(FbApi *api, GSList *uids);
 
 void
diff --git a/libpurple/protocols/facebook/facebook.c b/libpurple/protocols/facebook/facebook.c
--- a/libpurple/protocols/facebook/facebook.c
+++ b/libpurple/protocols/facebook/facebook.c
@@ -194,6 +194,7 @@ fb_cb_api_message(FbApi *api, GSList *ms
 {
 	FbApiMessage *msg;
 	FbData *fata = data;
+	gboolean mark;
 	gchar *html;
 	gchar tid[FB_ID_STRMAX];
 	gchar uid[FB_ID_STRMAX];
@@ -205,6 +206,7 @@ fb_cb_api_message(FbApi *api, GSList *ms
 
 	gc = fb_data_get_connection(fata);
 	acct = purple_connection_get_account(gc);
+	mark = purple_account_get_bool(acct, "mark-read", TRUE);
 
 	for (l = msgs; l != NULL; l = l->next) {
 		msg = l->data;
@@ -214,6 +216,10 @@ fb_cb_api_message(FbApi *api, GSList *ms
 		FB_ID_TO_STR(msg->uid, uid);
 
 		if (msg->tid == 0) {
+			if (mark) {
+				fb_api_read(api, msg->uid, TRUE);
+			}
+
 			purple_serv_got_im(gc, uid, html,
 		                           PURPLE_MESSAGE_RECV,
 			                   time(NULL));
@@ -225,6 +231,10 @@ fb_cb_api_message(FbApi *api, GSList *ms
 		chat = purple_conversations_find_chat_with_account(tid, acct);
 
 		if (chat != NULL) {
+			if (mark) {
+				fb_api_read(api, msg->tid, TRUE);
+			}
+
 			id = purple_chat_conversation_get_id(chat);
 			purple_serv_got_chat_in(gc, id, uid,
 			                        PURPLE_MESSAGE_RECV,
@@ -901,9 +911,17 @@ fb_cmd_leave(PurpleConversation *conv, c
 static void
 facebook_protocol_init(PurpleProtocol *protocol)
 {
+	GList *opts = NULL;
+	PurpleAccountOption *opt;
+
 	protocol->id      = "prpl-facebook";
 	protocol->name    = "Facebook";
 	protocol->options = OPT_PROTO_CHAT_TOPIC;
+
+	opt = purple_account_option_bool_new(_("Mark messages as read"),
+	                                     "mark-read", TRUE);
+	opts = g_list_prepend(opts, opt);
+	protocol->account_options = g_list_reverse(opts);
 }
 
 static void



More information about the Commits mailing list