/soc/2015/jgeboski/facebook: 143a4d8db15c: facebook: implemented...

James Geboski jgeboski at gmail.com
Thu Aug 6 13:42:57 EDT 2015


Changeset: 143a4d8db15c2907bca6d28cf1dfc7aac5784b36
Author:	 James Geboski <jgeboski at gmail.com>
Date:	 2015-08-06 13:42 -0400
Branch:	 facebook
URL: https://hg.pidgin.im/soc/2015/jgeboski/facebook/rev/143a4d8db15c

Description:

facebook: implemented self messages

diffstat:

 libpurple/protocols/facebook/api.c      |  52 ++++++++++++++++++++++++++++---
 libpurple/protocols/facebook/api.h      |   3 +-
 libpurple/protocols/facebook/facebook.c |  20 +++++------
 libpurple/protocols/facebook/util.c     |  53 +++++++++++++++++++++++++++++++++
 libpurple/protocols/facebook/util.h     |  10 ++++++
 5 files changed, 120 insertions(+), 18 deletions(-)

diffs (truncated from 324 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
@@ -59,6 +59,8 @@ struct _FbApiPrivate
 	gchar *stoken;
 	gchar *token;
 
+	GHashTable *msgids;
+
 };
 
 static void
@@ -147,6 +149,8 @@ fb_api_dispose(GObject *obj)
 		g_object_unref(priv->mqtt);
 	}
 
+	g_hash_table_destroy(priv->msgids);
+
 	g_free(priv->cid);
 	g_free(priv->did);
 	g_free(priv->stoken);
@@ -291,6 +295,9 @@ fb_api_init(FbApi *api)
 
 	priv = G_TYPE_INSTANCE_GET_PRIVATE(api, FB_TYPE_API, FbApiPrivate);
 	api->priv = priv;
+
+	priv->msgids = g_hash_table_new_full(g_int64_hash, g_int64_equal,
+	                                     g_free, NULL);
 }
 
 GQuark
@@ -770,6 +777,7 @@ static void
 fb_api_cb_publish_typing(FbApi *api, const GByteArray *pload)
 {
 	const gchar *str;
+	FbApiPrivate *priv = api->priv;
 	FbApiTyping typg;
 	FbJsonValues *values;
 	GError *err = NULL;
@@ -795,8 +803,11 @@ fb_api_cb_publish_typing(FbApi *api, con
 
 	if (g_ascii_strcasecmp(str, "typ") == 0) {
 		typg.uid = fb_json_values_next_int(values, 0);
-		typg.state = fb_json_values_next_int(values, 0);
-		g_signal_emit_by_name(api, "typing", &typg);
+
+		if (typg.uid != priv->uid) {
+			typg.state = fb_json_values_next_int(values, 0);
+			g_signal_emit_by_name(api, "typing", &typg);
+		}
 	}
 
 	fb_json_values_free(values);
@@ -926,6 +937,8 @@ fb_api_cb_publish_ms(FbApi *api, const G
 	FbApiMessage msg;
 	FbApiPrivate *priv = api->priv;
 	FbHttpParams *params;
+	FbId oid;
+	FbId uid;
 	FbJsonValues *values;
 	FbThrift *thft;
 	gchar *json;
@@ -987,9 +1000,15 @@ fb_api_cb_publish_ms(FbApi *api, const G
 
 	values = fb_json_values_new(root, "$.deltas");
 	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
+	                   "$.deltaNewMessage.messageMetadata"
+			    ".offlineThreadingId");
+	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
 	                   "$.deltaNewMessage.messageMetadata.actorFbId");
 	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
 	                   "$.deltaNewMessage.messageMetadata"
+	                    ".threadKey.otherUserFbId");
+	fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
+	                   "$.deltaNewMessage.messageMetadata"
 	                    ".threadKey.threadFbId");
 	fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
 	                   "$.deltaNewMessage.body");
@@ -997,11 +1016,27 @@ fb_api_cb_publish_ms(FbApi *api, const G
 	                   "$.deltaNewMessage.stickerId");
 
 	while (fb_json_values_update(values, &err)) {
+		id = fb_json_values_next_int(values, 0);
+
+		if (g_hash_table_remove(priv->msgids, &id)) {
+			g_print("GOT OUR OWN MESSAGE!\n");
+			continue;
+		}
+
 		fb_api_message_reset(&msg, FALSE);
-		msg.uid = fb_json_values_next_int(values, 0);
+		uid = fb_json_values_next_int(values, 0);
+		oid = fb_json_values_next_int(values, 0);
 		msg.tid = fb_json_values_next_int(values, 0);
 
-		if ((msg.uid == 0) || (msg.uid == priv->uid)) {
+		if (uid != priv->uid) {
+			msg.isself = FALSE;
+			msg.uid = uid;
+		} else {
+			msg.isself = TRUE;
+			msg.uid = oid;
+		}
+
+		if (msg.uid == 0) {
 			continue;
 		}
 
@@ -1485,6 +1520,7 @@ fb_api_message(FbApi *api, FbId id, gboo
 	const gchar *tpfx;
 	FbApiPrivate *priv;
 	gchar *json;
+	gpointer mptr;
 	guint64 msgid;
 	JsonBuilder *bldr;
 
@@ -1495,6 +1531,9 @@ fb_api_message(FbApi *api, FbId id, gboo
 	msgid = FB_API_MSGID(g_get_real_time() / 1000, g_random_int());
 	tpfx = thread ? "tfbid_" : "";
 
+	mptr = g_memdup(&msgid, sizeof msgid);
+	g_hash_table_replace(priv->msgids, mptr, mptr);
+
 	bldr = fb_json_bldr_new(JSON_NODE_OBJECT);
 	fb_json_bldr_add_int(bldr, "msgid", msgid);
 	fb_json_bldr_add_str(bldr, "body", msg);
@@ -1983,7 +2022,7 @@ fb_api_typing(FbApi *api, FbId uid, gboo
 }
 
 FbApiMessage *
-fb_api_message_new(FbId uid, FbId tid, const gchar *text)
+fb_api_message_new(FbId uid, FbId tid, const gchar *text, gboolean isself)
 {
 	FbApiMessage *msg;
 
@@ -1991,6 +2030,7 @@ fb_api_message_new(FbId uid, FbId tid, c
 	msg->uid = uid;
 	msg->tid = tid;
 	msg->text = g_strdup(text);
+	msg->isself = isself;
 
 	return msg;
 }
@@ -2001,7 +2041,7 @@ fb_api_message_dup(FbApiMessage *msg, gb
 	FbApiMessage *ret;
 
 	g_return_val_if_fail(msg != NULL, NULL);
-	ret = fb_api_message_new(msg->uid, msg->tid, NULL);
+	ret = fb_api_message_new(msg->uid, msg->tid, NULL, msg->isself);
 
 	if (deep) {
 		ret->text = g_strdup(msg->text);
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
@@ -113,6 +113,7 @@ struct _FbApiMessage
 	FbId uid;
 	FbId tid;
 	gchar *text;
+	gboolean isself;
 };
 
 struct _FbApiPresence
@@ -217,7 +218,7 @@ void
 fb_api_typing(FbApi *api, FbId uid, gboolean state);
 
 FbApiMessage *
-fb_api_message_new(FbId uid, FbId tid, const gchar *text);
+fb_api_message_new(FbId uid, FbId tid, const gchar *text, gboolean isself);
 
 FbApiMessage *
 fb_api_message_dup(FbApiMessage *msg, gboolean deep);
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
@@ -225,6 +225,7 @@ fb_cb_api_message(FbApi *api, GSList *ms
 	PurpleAccount *acct;
 	PurpleChatConversation *chat;
 	PurpleConnection *gc;
+	PurpleMessageFlags flags;
 
 	gc = fb_data_get_connection(fata);
 	acct = purple_connection_get_account(gc);
@@ -233,19 +234,18 @@ fb_cb_api_message(FbApi *api, GSList *ms
 
 	for (l = msgs; l != NULL; l = l->next) {
 		msg = l->data;
-		chat = NULL;
-
 		html = purple_markup_escape_text(msg->text, -1);
 		FB_ID_TO_STR(msg->uid, uid);
 
+		flags = (msg->isself) ? PURPLE_MESSAGE_SEND
+		                      : PURPLE_MESSAGE_RECV;
+
 		if (msg->tid == 0) {
-			if (mark) {
-				fb_api_read(api, msg->uid, TRUE);
+			if (mark && !msg->isself) {
+				fb_api_read(api, msg->uid, FALSE);
 			}
 
-			purple_serv_got_im(gc, uid, html,
-		                           PURPLE_MESSAGE_RECV,
-			                   time(NULL));
+			fb_util_serv_got_im(gc, uid, html, flags, time(NULL));
 			g_free(html);
 			continue;
 		}
@@ -266,13 +266,11 @@ fb_cb_api_message(FbApi *api, GSList *ms
 			id = purple_chat_conversation_get_id(chat);
 		}
 
-		if (mark) {
+		if (mark && !msg->isself) {
 			fb_api_read(api, msg->tid, TRUE);
 		}
 
-		purple_serv_got_chat_in(gc, id, uid,
-					PURPLE_MESSAGE_RECV,
-					html, time(NULL));
+		fb_util_serv_got_chat_in(gc, id, uid, html, flags, time(NULL));
 		g_free(html);
 	}
 }
diff --git a/libpurple/protocols/facebook/util.c b/libpurple/protocols/facebook/util.c
--- a/libpurple/protocols/facebook/util.c
+++ b/libpurple/protocols/facebook/util.c
@@ -27,8 +27,11 @@
 
 #include "blistnodetypes.h"
 #include "buddylist.h"
+#include "conversations.h"
 #include "glibcompat.h"
+#include "message.h"
 #include "request.h"
+#include "server.h"
 
 #include "util.h"
 
@@ -408,6 +411,56 @@ fb_util_request_buddy(PurpleConnection *
 				     cpar, mata);
 }
 
+void
+fb_util_serv_got_im(PurpleConnection *gc, const gchar *who, const gchar *text,
+                    PurpleMessageFlags flags, guint64 timestamp)
+{
+	const gchar *name;
+	PurpleAccount *acct;
+	PurpleIMConversation *conv;
+	PurpleMessage *msg;
+
+	if (!(flags & PURPLE_MESSAGE_SEND)) {
+		purple_serv_got_im(gc, who, text, flags, timestamp);
+		return;
+	}
+
+	acct = purple_connection_get_account(gc);
+	conv = purple_conversations_find_im_with_account(who, acct);
+
+	if (conv == NULL) {
+		conv = purple_im_conversation_new(acct, who);
+		purple_conversations_add(PURPLE_CONVERSATION(conv));
+	}
+
+	name = purple_account_get_username(acct);
+	msg = purple_message_new_outgoing(name, text, flags);
+	purple_conversation_write_message(PURPLE_CONVERSATION(conv), msg);
+}
+
+void
+fb_util_serv_got_chat_in(PurpleConnection *gc, gint id, const gchar *who,
+                         const gchar *text, PurpleMessageFlags flags,
+			 guint64 timestamp)
+{
+	const gchar *name;
+	PurpleAccount *acct;
+	PurpleChatConversation *conv;
+	PurpleMessage *msg;
+
+	if (!(flags & PURPLE_MESSAGE_SEND)) {
+		purple_serv_got_chat_in(gc, id, who, flags, text, timestamp);
+		return;
+	}
+
+	acct = purple_connection_get_account(gc);
+	conv = purple_conversations_find_chat(gc, id);
+
+	name = purple_account_get_username(acct);
+	msg = purple_message_new_outgoing(name, text, flags);
+	purple_conversation_write_message(PURPLE_CONVERSATION(conv), msg);
+}
+
 gboolean
 fb_util_str_is(const gchar *str, GAsciiType type)
 {
diff --git a/libpurple/protocols/facebook/util.h b/libpurple/protocols/facebook/util.h
--- a/libpurple/protocols/facebook/util.h
+++ b/libpurple/protocols/facebook/util.h



More information about the Commits mailing list