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

Koosha Khajehmoogahi koosha at posteo.de
Fri Jun 26 19:58:17 EDT 2015


Changeset: b7032e60b614faea1893737c977c384bf06663e1
Author:	 Koosha Khajehmoogahi <koosha at posteo.de>
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"



More information about the Commits mailing list