/soc/2015/koosha/main: 9c71168e8a68: XEP-0280: parse incoming me...

Koosha Khajehmoogahi <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 9c71168e8a68c7c8debf5d152fc1842251c60a42
Author:	 Koosha Khajehmoogahi <[email protected]>
Date:	 2015-08-04 02:50 +0200
Branch:	 default
URL: https://hg.pidgin.im/soc/2015/koosha/main/rev/9c71168e8a68

Description:

XEP-0280: parse incoming messages and notify accordingly


This commit is essentially from the patch in https://developer.pidgin.im/ticket/15508
with some tweaks to make it compatible with the current code of libpurple

diffstat:

 libpurple/protocols/jabber/message.c    |  139 +++++++++++++++++++++----------
 libpurple/protocols/jabber/message.h    |    1 +
 libpurple/protocols/jabber/namespaces.h |    3 +
 libpurple/server.c                      |    5 -
 4 files changed, 99 insertions(+), 49 deletions(-)

diffs (262 lines):

diff --git a/libpurple/protocols/jabber/message.c b/libpurple/protocols/jabber/message.c
--- a/libpurple/protocols/jabber/message.c
+++ b/libpurple/protocols/jabber/message.c
@@ -118,7 +118,8 @@ static const char *jabber_get_last_recv_
 
 static void handle_chat(JabberMessage *jm)
 {
-	JabberID *jid = jabber_id_new(jm->from);
+	gchar *contact = jm->outgoing ? jm->to : jm->from;
+	JabberID *jid = jabber_id_new(contact);
 
 	PurpleConnection *gc;
 	PurpleAccount *account;
@@ -132,48 +133,50 @@ static void handle_chat(JabberMessage *j
 	gc = jm->js->gc;
 	account = purple_connection_get_account(gc);
 
-	jb = jabber_buddy_find(jm->js, jm->from, TRUE);
+	jb = jabber_buddy_find(jm->js, contact, TRUE);
 	jbr = jabber_buddy_find_resource(jb, jid->resource);
 	flags = 0;
 	if(!jm->xhtml && !jm->body) {
-		if (jbr && jm->chat_state != JM_STATE_NONE)
-			jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED;
+		if (!jm->outgoing) {
+			if (jbr && jm->chat_state != JM_STATE_NONE)
+				jbr->chat_states = JABBER_CHAT_STATES_SUPPORTED;
 
-		if(JM_STATE_COMPOSING == jm->chat_state) {
-			purple_serv_got_typing(gc, jm->from, 0, PURPLE_IM_TYPING);
-		} else if(JM_STATE_PAUSED == jm->chat_state) {
-			purple_serv_got_typing(gc, jm->from, 0, PURPLE_IM_TYPED);
-		} else if(JM_STATE_GONE == jm->chat_state) {
-			PurpleIMConversation *im = purple_conversations_find_im_with_account(
-					jm->from, account);
-			if (im && jid->node && jid->domain) {
-				char buf[256];
-				PurpleBuddy *buddy;
+			if(JM_STATE_COMPOSING == jm->chat_state) {
+				purple_serv_got_typing(gc, contact, 0, PURPLE_IM_TYPING);
+			} else if(JM_STATE_PAUSED == jm->chat_state) {
+				purple_serv_got_typing(gc, contact, 0, PURPLE_IM_TYPED);
+			} else if(JM_STATE_GONE == jm->chat_state) {
+				PurpleIMConversation *im = purple_conversations_find_im_with_account(
+						contact, account);
+				if (im && jid->node && jid->domain) {
+					char buf[256];
+					PurpleBuddy *buddy;
 
-				g_snprintf(buf, sizeof(buf), "%s@%s", jid->node, jid->domain);
+					g_snprintf(buf, sizeof(buf), "%s@%s", jid->node, jid->domain);
 
-				if ((buddy = purple_blist_find_buddy(account, buf))) {
-					const char *who;
-					char *escaped;
+					if ((buddy = purple_blist_find_buddy(account, buf))) {
+						const char *who;
+						char *escaped;
 
-					who = purple_buddy_get_alias(buddy);
-					escaped = g_markup_escape_text(who, -1);
+						who = purple_buddy_get_alias(buddy);
+						escaped = g_markup_escape_text(who, -1);
 
-					g_snprintf(buf, sizeof(buf),
-					           _("%s has left the conversation."), escaped);
-					g_free(escaped);
+						g_snprintf(buf, sizeof(buf),
+							   _("%s has left the conversation."), escaped);
+						g_free(escaped);
 
-					/* At some point when we restructure PurpleConversation,
-					 * this should be able to be implemented by removing the
-					 * user from the conversation like we do with chats now. */
-					purple_conversation_write_system_message(
-						PURPLE_CONVERSATION(im), buf, 0);
+						/* At some point when we restructure PurpleConversation,
+						 * this should be able to be implemented by removing the
+						 * user from the conversation like we do with chats now. */
+						purple_conversation_write_system_message(
+							PURPLE_CONVERSATION(im), buf, 0);
+					}
 				}
+				purple_serv_got_typing_stopped(gc, contact);
+
+			} else {
+				purple_serv_got_typing_stopped(gc, contact);
 			}
-			purple_serv_got_typing_stopped(gc, jm->from);
-
-		} else {
-			purple_serv_got_typing_stopped(gc, jm->from);
 		}
 	} else {
 		if (jid->resource) {
@@ -188,12 +191,12 @@ static void handle_chat(JabberMessage *j
 			 */
 			PurpleIMConversation *im;
 
-			im = purple_conversations_find_im_with_account(jm->from, account);
-			if (im && !g_str_equal(jm->from,
+			im = purple_conversations_find_im_with_account(contact, account);
+			if (im && !g_str_equal(contact,
 					purple_conversation_get_name(PURPLE_CONVERSATION(im)))) {
 				purple_debug_info("jabber", "Binding conversation to %s\n",
-				                  jm->from);
-				purple_conversation_set_name(PURPLE_CONVERSATION(im), jm->from);
+				                  contact);
+				purple_conversation_set_name(PURPLE_CONVERSATION(im), contact);
 			}
 		}
 
@@ -227,7 +230,9 @@ static void handle_chat(JabberMessage *j
 			jm->body = jabber_google_format_to_html(jm->body);
 			g_free(tmp);
 		}
-		purple_serv_got_im(gc, jm->from, jm->xhtml ? jm->xhtml : jm->body, flags, jm->sent);
+
+		flags |= jm->outgoing ? PURPLE_MESSAGE_SEND : PURPLE_MESSAGE_RECV;
+		purple_serv_got_im(gc, contact, jm->xhtml ? jm->xhtml : jm->body, flags, jm->sent);
 	}
 
 	jabber_id_free(jid);
@@ -623,7 +628,47 @@ void jabber_message_parse(JabberStream *
 	JabberMessage *jm;
 	const char *id, *from, *to, *type;
 	PurpleXmlNode *child;
-	gboolean signal_return;
+	gboolean signal_return, is_outgoing = FALSE;
+	time_t message_timestamp = time(NULL);
+	gboolean delayed = FALSE;
+
+	/* Check if this is a carbon-copy of a message.
+	 * If so, use that instead for the rest of this function,
+	 * but keep track of whether the 'from' and 'to' must be swapped.
+	 */
+	from = purple_xmlnode_get_attrib(packet, "from");
+
+	if (jabber_is_own_account(js, from)) {
+		PurpleXmlNode *received = purple_xmlnode_get_child_with_namespace(packet, "received", NS_CARBONS);
+		PurpleXmlNode *sent = purple_xmlnode_get_child_with_namespace(packet, "sent", NS_CARBONS);
+
+		if (sent)
+			is_outgoing = TRUE;
+
+		if (received || sent) {
+			PurpleXmlNode *forwarded = purple_xmlnode_get_child_with_namespace(received ?
+					received : sent, "forwarded", NS_FORWARD);
+
+			if (forwarded) {
+				PurpleXmlNode *message = purple_xmlnode_get_child_with_namespace(forwarded, "message", NS_XMPP_CLIENT);
+				PurpleXmlNode *delay = purple_xmlnode_get_child_with_namespace(forwarded, "delay", NS_DELAYED_DELIVERY);
+
+				if (message) {
+					purple_debug_info("jabber", "It's a carbon-copy message, using the wrapped message instead.\n");
+					packet = message;
+
+					if (delay) {
+						const char *timestamp = purple_xmlnode_get_attrib(delay, "stamp");
+						if(timestamp) {
+							purple_debug_info("jabber", "Found a delay stamp: %s\n", timestamp);
+							delayed = TRUE;
+							message_timestamp = purple_str_to_time(timestamp, TRUE, NULL, NULL, NULL);
+						}
+					}
+				}
+			}
+		}
+	}
 
 	from = purple_xmlnode_get_attrib(packet, "from");
 	id   = purple_xmlnode_get_attrib(packet, "id");
@@ -637,10 +682,11 @@ void jabber_message_parse(JabberStream *
 
 	jm = g_new0(JabberMessage, 1);
 	jm->js = js;
-	jm->sent = time(NULL);
-	jm->delayed = FALSE;
+	jm->sent = message_timestamp;
+	jm->delayed = delayed;
 	jm->receipt = FALSE;
 	jm->chat_state = JM_STATE_NONE;
+	jm->outgoing = is_outgoing;
 
 	if(type) {
 		if(!strcmp(type, "normal"))
@@ -749,11 +795,13 @@ void jabber_message_parse(JabberStream *
 						} else if (jm->type == JABBER_MESSAGE_NORMAL ||
 						           jm->type == JABBER_MESSAGE_CHAT) {
 							conv =
-								purple_conversations_find_with_account(from, account);
+								purple_conversations_find_with_account(
+										is_outgoing ? to : from, account);
 							if (!conv) {
 								/* we need to create the conversation here */
 								conv = PURPLE_CONVERSATION(
-									purple_im_conversation_new(account, from));
+									purple_im_conversation_new(account,
+										is_outgoing ? to : from));
 							}
 						}
 					}
@@ -826,6 +874,9 @@ void jabber_message_parse(JabberStream *
 			if (msg_id && *msg_id && last_id && g_strcmp0(msg_id, last_id) == 0)
 				jm->replace_last = TRUE;
 		} else if(!strcmp(child->name, "delay") && !strcmp(xmlns, NS_DELAYED_DELIVERY)) {
+			/* Carbons/Stanza fowarding might have already set jm->delayed.
+			   However, this timestamp was certainly applied earlier, so it overrides Carbons.
+			 */
 			const char *timestamp = purple_xmlnode_get_attrib(child, "stamp");
 			jm->delayed = TRUE;
 			if(timestamp)
@@ -923,8 +974,8 @@ void jabber_message_parse(JabberStream *
 
 static gboolean
 jabber_conv_support_custom_smileys(JabberStream *js,
-								   PurpleConversation *conv,
-								   const gchar *who)
+				   PurpleConversation *conv,
+				   const gchar *who)
 {
 	JabberBuddy *jb;
 	JabberChat *chat;
diff --git a/libpurple/protocols/jabber/message.h b/libpurple/protocols/jabber/message.h
--- a/libpurple/protocols/jabber/message.h
+++ b/libpurple/protocols/jabber/message.h
@@ -45,6 +45,7 @@ typedef struct _JabberMessage {
 	gboolean hasBuzz;
 	gboolean receipt;
 	gboolean replace_last;
+	gboolean outgoing;
 	char *id;
 	char *from;
 	char *to;
diff --git a/libpurple/protocols/jabber/namespaces.h b/libpurple/protocols/jabber/namespaces.h
--- a/libpurple/protocols/jabber/namespaces.h
+++ b/libpurple/protocols/jabber/namespaces.h
@@ -101,6 +101,9 @@
 /* XEP-0280 Message Carbons */
 #define NS_CARBONS "urn:xmpp:carbons:2"
 
+/* XEP-0297 Stanza Forwarding */
+#define NS_FORWARD "urn:xmpp:forward:0"
+
 /* XEP-0308 Last Message Correction */
 #define NS_MSG_REPLACE "urn:xmpp:message-correct:0"
 
diff --git a/libpurple/server.c b/libpurple/server.c
--- a/libpurple/server.c
+++ b/libpurple/server.c
@@ -492,11 +492,6 @@ void purple_serv_got_im(PurpleConnection
 		mtime = time(NULL);
 	}
 
-	/*
-	 * XXX: Should we be setting this here, or relying on protocols to set it?
-	 */
-	flags |= PURPLE_MESSAGE_RECV;
-
 	if (!purple_account_privacy_check(account, who)) {
 		purple_signal_emit(purple_conversations_get_handle(), "blocked-im-msg",
 				account, who, msg, flags, (unsigned int)mtime);

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.