diff libpurple/protocols/jabber/si.c @ 29820:0fe92a64771d

propagate from branch 'im.pidgin.pidgin' (head a9876c2b74baddb4b0fd99eede7daef1d346604b) to branch 'im.pidgin.cpw.malu.ft_thumbnails' (head d743e98354f375947f68cf4e770a48bb0593b0b5)
author Marcus Lundblad <ml@update.uu.se>
date Wed, 10 Mar 2010 05:40:47 +0000
parents b680a9f2b641
children 25a53c299713
line wrap: on
line diff
--- a/libpurple/protocols/jabber/si.c	Wed Mar 10 05:15:01 2010 +0000
+++ b/libpurple/protocols/jabber/si.c	Wed Mar 10 05:40:47 2010 +0000
@@ -32,6 +32,7 @@
 #include "notify.h"
 
 #include "buddy.h"
+#include "data.h"
 #include "disco.h"
 #include "jabber.h"
 #include "ibb.h"
@@ -1245,7 +1246,8 @@
 	char buf[32];
 
 	xfer->filename = g_path_get_basename(xfer->local_filename);
-
+	purple_xfer_prepare_thumbnail(xfer);
+	
 	iq = jabber_iq_new(jsx->js, JABBER_IQ_SET);
 	xmlnode_set_attrib(iq->node, "to", xfer->who);
 	si = xmlnode_new_child(iq->node, "si");
@@ -1263,6 +1265,21 @@
 	xmlnode_set_attrib(file, "size", buf);
 	/* maybe later we'll do hash and date attribs */
 
+	/* add thumbnail, if appropriate */
+	if (purple_xfer_get_thumbnail_data(xfer)) {
+		JabberData *thumbnail_data = 
+			jabber_data_create_from_data(purple_xfer_get_thumbnail_data(xfer),
+				purple_xfer_get_thumbnail_size(xfer), "image/png", TRUE,
+				jsx->js);
+		xmlnode *thumbnail = xmlnode_new_child(file, "thumbnail");
+		xmlnode_set_namespace(thumbnail, NS_THUMBS);
+		xmlnode_set_attrib(thumbnail, "cid", 
+			jabber_data_get_cid(thumbnail_data));
+		xmlnode_set_attrib(thumbnail, "mime-type", "image/png");
+		/* cache data */
+		jabber_data_associate_local(thumbnail_data, NULL);
+	}
+						  
 	feature = xmlnode_new_child(si, "feature");
 	xmlnode_set_namespace(feature, "http://jabber.org/protocol/feature-neg");
 	x = xmlnode_new_child(feature, "x");
@@ -1641,12 +1658,37 @@
 		purple_xfer_request(xfer);
 }
 
+static void
+jabber_si_thumbnail_cb(JabberStream *js, const char *from, JabberIqType type, 
+	const char *id, xmlnode *packet, gpointer data)
+{
+	PurpleXfer *xfer = (PurpleXfer *) data;
+	xmlnode *data_element = xmlnode_get_child(packet, "data");
+	xmlnode *item_not_found = xmlnode_get_child(packet, "item-not-found");
+
+	if (data_element) {
+		JabberData *data = jabber_data_create_from_xml(data_element);
+
+		if (data) {
+			purple_xfer_set_thumbnail(xfer, jabber_data_get_data(data),
+				jabber_data_get_size(data));
+			jabber_data_destroy(data);
+		}
+	} else if (item_not_found) {
+		purple_debug_info("jabber",
+			"Responder didn't recognize requested data\n");
+	} else {
+		purple_debug_error("jabber", "Unknown response to data request\n");
+	}
+	purple_xfer_request(xfer);
+}
+
 void jabber_si_parse(JabberStream *js, const char *from, JabberIqType type,
                      const char *id, xmlnode *si)
 {
 	JabberSIXfer *jsx;
 	PurpleXfer *xfer;
-	xmlnode *file, *feature, *x, *field, *option, *value;
+	xmlnode *file, *feature, *x, *field, *option, *value, *thumbnail;
 	const char *stream_id, *filename, *filesize_c, *profile;
 	size_t filesize = 0;
 
@@ -1728,10 +1770,30 @@
 	purple_xfer_set_request_denied_fnc(xfer, jabber_si_xfer_request_denied);
 	purple_xfer_set_cancel_recv_fnc(xfer, jabber_si_xfer_cancel_recv);
 	purple_xfer_set_end_fnc(xfer, jabber_si_xfer_end);
-
+				   
 	js->file_transfers = g_list_append(js->file_transfers, xfer);
 
-	purple_xfer_request(xfer);
+	/* if there is a thumbnail, we should request it... */
+	if ((thumbnail = xmlnode_get_child_with_namespace(file, "thumbnail",
+		NS_THUMBS))) {
+		const char *cid = xmlnode_get_attrib(thumbnail, "cid");
+		if (cid) {
+			JabberIq *request = 
+				jabber_iq_new(jsx->js, JABBER_IQ_GET);
+
+			purple_debug_info("jabber", "got file thumbnail, request it\n");
+			xmlnode_insert_child(request->node, 
+				jabber_data_get_xml_request(cid));
+			xmlnode_set_attrib(request->node, "to", 
+				purple_xfer_get_remote_user(xfer));
+			jabber_iq_set_callback(request, jabber_si_thumbnail_cb, xfer);
+			jabber_iq_send(request);
+		} else {
+			purple_xfer_request(xfer);
+		}
+	} else {
+		purple_xfer_request(xfer);
+	}
 }
 
 void