/soc/2015/koosha/main: b7032e60b614: libpurple: add sending side...

Koosha Khajehmoogahi <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: b7032e60b614faea1893737c977c384bf06663e1
Author:	 Koosha Khajehmoogahi <[email protected]>
Date:	 2015-06-27 01:56 +0200
Branch:	 default
URL: https://hg.pidgin.im/soc/2015/koosha/main/rev/b7032e60b614

Description:

libpurple: add sending side support for XEP-0308 (Last Message Correction)

diffstat:

 libpurple/plugins/signals-test.c        |  11 ++++-
 libpurple/protocols/jabber/disco.c      |   2 +
 libpurple/protocols/jabber/jabber.c     |  80 ++++++++++++++++++++++++++++++++-
 libpurple/protocols/jabber/jabber.h     |   1 +
 libpurple/protocols/jabber/message.c    |  18 +++++++
 libpurple/protocols/jabber/message.h    |   2 +
 libpurple/protocols/jabber/namespaces.h |   3 +
 7 files changed, 115 insertions(+), 2 deletions(-)

diffs (224 lines):

diff --git a/libpurple/plugins/signals-test.c b/libpurple/plugins/signals-test.c
--- a/libpurple/plugins/signals-test.c
+++ b/libpurple/plugins/signals-test.c
@@ -695,7 +695,14 @@ jabber_watched_iq(PurpleConnection *pc, 
 static void
 jabber_message_delivered(PurpleConnection *pc, const char *id)
 {
-	purple_debug_misc("signals test", "jabber message delivered (id=%s)\n", id);
+	purple_debug_misc("signals test", "jabber-message-delivered (id=%s)\n", id);
+}
+
+static void
+jabber_replacing_message(PurpleConnection *pc, const char *old_id, const char *new_body)
+{
+	purple_debug_misc("signals test", "jabber-replacing-message (id=%s) with new body (%s)\n",
+				old_id, new_body);
 }
 
 /**************************************************************************
@@ -896,6 +903,8 @@ plugin_load(PurplePlugin *plugin, GError
 		                      PURPLE_CALLBACK(jabber_watched_iq), NULL);
 		purple_signal_connect(jabber_handle, "jabber-message-delivered", plugin,
 		                      PURPLE_CALLBACK(jabber_message_delivered), NULL);
+		purple_signal_connect(jabber_handle, "jabber-replacing-message", plugin,
+		                      PURPLE_CALLBACK(jabber_replacing_message), NULL);
 	}
 
 	return TRUE;
diff --git a/libpurple/protocols/jabber/disco.c b/libpurple/protocols/jabber/disco.c
--- a/libpurple/protocols/jabber/disco.c
+++ b/libpurple/protocols/jabber/disco.c
@@ -304,6 +304,8 @@ static void jabber_disco_info_cb(JabberS
 				}
 				else if(!strcmp(var, NS_MSG_DELIVERY))
 					capabilities |= JABBER_MSG_DELIVERY;
+				else if(!strcmp(var, NS_MSG_REPLACE))
+					capabilities |= JABBER_MSG_REPLACE;
 			}
 		}
 
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -3198,6 +3198,70 @@ static PurpleCmdRet jabber_cmd_buzz(Purp
 	return _jabber_send_buzz(js, who, error)  ? PURPLE_CMD_RET_OK : PURPLE_CMD_RET_FAILED;
 }
 
+static PurpleCmdRet
+jabber_cmd_replace(PurpleConversation *conv, const char *cmd,
+			char **args, char **error, void *data)
+{
+	PurpleAccount *account;
+	PurpleBuddy *buddy;
+	PurpleConnection *conn;
+	PurpleXmlNode *body, *replace, *msg;
+	JabberStream *js;
+	JabberBuddy *jb;
+	JabberBuddyResource *jbr;
+	const char *last_id, *username, *alias;
+	gchar *to, *id;
+
+	account = purple_conversation_get_account(conv);
+	conn = purple_conversation_get_connection(conv);
+	js = purple_connection_get_protocol_data(conn);
+	username = purple_conversation_get_name(conv);
+	buddy = purple_blist_find_buddy(account, username);
+	alias = buddy ? purple_buddy_get_contact_alias(buddy) : username;
+
+	if (!args || !args[0])
+		return PURPLE_CMD_RET_FAILED;
+
+	last_id = jabber_get_last_sent_im_id(js);
+
+	if (last_id == NULL) {
+		*error = g_strdup_printf(_("You have not sent any message yet to replace."));
+		return PURPLE_CMD_RET_FAILED;
+	}
+
+	jb = jabber_buddy_find(js, username, FALSE);
+	jbr = jabber_buddy_find_resource(jb, NULL);
+	if (!jabber_resource_has_capability(jbr, NS_MSG_REPLACE)) {
+		*error = g_strdup_printf(_("%s does not seem to have support for message corrections."), alias );
+		return PURPLE_CMD_RET_FAILED;
+	}
+
+	msg = purple_xmlnode_new("message");
+
+	to = g_strdup_printf("%s/%s", username, jbr->name);
+	purple_xmlnode_set_attrib(msg, "to", to);
+	g_free(to);
+
+	id = jabber_get_next_id(js);
+	purple_xmlnode_set_attrib(msg, "id", id);
+	g_free(id);
+
+	body = purple_xmlnode_new_child(msg, "body");
+	purple_xmlnode_insert_data(body, args[0], -1);
+
+	replace = purple_xmlnode_new_child(msg, "replace");
+	purple_xmlnode_set_attrib(replace, "id", last_id);
+	purple_xmlnode_set_namespace(replace, NS_MSG_REPLACE);
+
+	jabber_send(js, msg);
+	purple_xmlnode_free(msg);
+
+	purple_signal_emit(purple_connection_get_protocol(conn), "jabber-replacing-message",
+			conn, last_id, args[0]);
+
+	return PURPLE_CMD_RET_OK;
+}
+
 GList *jabber_attention_types(PurpleAccount *account)
 {
 	static GList *types = NULL;
@@ -3722,7 +3786,13 @@ jabber_register_commands(PurpleProtocol 
 	id = purple_cmd_register("buzz", "w", PURPLE_CMD_P_PROTOCOL,
 		PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
 		PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, proto_id, jabber_cmd_buzz,
-		_("buzz: Buzz a user to get their attention"), NULL);
+		_("buzz: Buzz a user to get their attention."), NULL);
+	commands = g_slist_prepend(commands, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("replace", "S", PURPLE_CMD_P_PROTOCOL,
+		PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
+		proto_id, jabber_cmd_replace,
+		_("replace: Replace the last message with a newer one."), NULL);
 	commands = g_slist_prepend(commands, GUINT_TO_POINTER(id));
 
 	id = purple_cmd_register("mood", "ws", PURPLE_CMD_P_PROTOCOL,
@@ -3942,6 +4012,7 @@ jabber_do_init(void)
 	jabber_add_feature(NS_XHTML_IM, NULL);
 	jabber_add_feature(NS_PING, NULL);
 	jabber_add_feature(NS_MSG_DELIVERY, NULL);
+	jabber_add_feature(NS_MSG_REPLACE, NULL);
 
 	/* Buzz/Attention */
 	jabber_add_feature(NS_ATTENTION, jabber_buzz_isenabled);
@@ -4128,6 +4199,13 @@ static void jabber_init_protocol(PurpleP
 			G_TYPE_NONE, 2,
 			PURPLE_TYPE_CONNECTION,
 			G_TYPE_STRING); /* id */
+
+	purple_signal_register(protocol, "jabber-replacing-message",
+			purple_marshal_VOID__POINTER_POINTER_POINTER,
+			G_TYPE_NONE, 3,
+			PURPLE_TYPE_CONNECTION,
+			G_TYPE_STRING,  /* old id */
+			G_TYPE_STRING); /* new body */
 }
 
 static void jabber_uninit_protocol(PurpleProtocol *protocol)
diff --git a/libpurple/protocols/jabber/jabber.h b/libpurple/protocols/jabber/jabber.h
--- a/libpurple/protocols/jabber/jabber.h
+++ b/libpurple/protocols/jabber/jabber.h
@@ -51,6 +51,7 @@ typedef enum {
 
 	JABBER_CAP_FACEBOOK       = 1 << 16,
 	JABBER_MSG_DELIVERY       = 1 << 17,
+	JABBER_MSG_REPLACE        = 1 << 18,
 	JABBER_CAP_RETRIEVED      = 1 << 31
 } JabberCapabilities;
 
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
@@ -1195,6 +1195,20 @@ jabber_xhtml_plain_equal(const char *xht
 	return ret;
 }
 
+static GHashTable *last_im_ids = NULL;
+const char *jabber_get_last_sent_im_id(JabberStream *js)
+{
+	const char *id;
+	if (!js)
+		return NULL;
+
+	if (!last_im_ids)
+		last_im_ids = g_hash_table_new(NULL, NULL);
+
+	id = (const char *)g_hash_table_lookup(last_im_ids, js);
+	return id;
+}
+
 int jabber_message_send_im(PurpleConnection *gc, PurpleMessage *msg)
 {
 	JabberMessage *jm;
@@ -1255,8 +1269,12 @@ int jabber_message_send_im(PurpleConnect
 			jm->xhtml = g_strdup_printf("<html xmlns='" NS_XHTML_IM "'><body xmlns='" NS_XHTML "'><p>%s</p></body></html>", xhtml);
 	}
 
+	if (!last_im_ids)
+		last_im_ids = g_hash_table_new_full(NULL, NULL, NULL, g_free);
+
 	g_free(xhtml);
 
+	g_hash_table_insert(last_im_ids, jm->js, g_strdup(jm->id));
 	jabber_message_send(jm);
 	jabber_message_free(jm);
 	return 1;
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
@@ -74,6 +74,8 @@ void jabber_message_parse(JabberStream *
 int jabber_message_send_im(PurpleConnection *gc, PurpleMessage *msg);
 int jabber_message_send_chat(PurpleConnection *gc, int id, PurpleMessage *msg);
 
+const char *jabber_get_last_sent_im_id(JabberStream *js);
+
 unsigned int jabber_send_typing(PurpleConnection *gc, const char *who, PurpleIMTypingState state);
 
 gboolean jabber_buzz_isenabled(JabberStream *js, const gchar *namespace);
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
@@ -98,6 +98,9 @@
 /* XEP-0264 File Transfer Thumbnails (Thumbs) */
 #define NS_THUMBS "urn:xmpp:thumbs:0"
 
+/* XEP-0308 Last Message Correction */
+#define NS_MSG_REPLACE "urn:xmpp:message-correct:0"
+
 /* Google extensions */
 #define NS_GOOGLE_CAMERA "http://www.google.com/xmpp/protocol/camera/v1"
 #define NS_GOOGLE_VIDEO "http://www.google.com/xmpp/protocol/video/v1"

_______________________________________________
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.