/soc/2015/koosha/main: 9c71168e8a68: XEP-0280: parse incoming me...
Koosha Khajehmoogahi
koosha at posteo.de
Tue Aug 4 13:11:09 EDT 2015
Changeset: 9c71168e8a68c7c8debf5d152fc1842251c60a42
Author: Koosha Khajehmoogahi <koosha at posteo.de>
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);
More information about the Commits
mailing list