Request avatar data if not present
authorMyhailo Danylenko <isbear@ukrpost.net>
Wed, 11 Nov 2009 14:00:56 +0200
changeset 6 a0231d43ae53
parent 5 f7a9dc93bc73
child 7 b33256405413
Request avatar data if not present * avatar data reqest will be sent if avatar is not present * only one metadata handler * forgot 'static' on some routines
TODO
avatar.c
--- a/TODO	Fri Nov 06 15:58:45 2009 +0200
+++ b/TODO	Wed Nov 11 14:00:56 2009 +0200
@@ -2,7 +2,5 @@
 Add avatar_aa_options?
 Handle url avatars? (needs common image loading library (sdl-image? imlib?) and web-retrieving library (curl?))
 Report no-avatar
-Retrieve avatar manually via idless pubsub query?
-Check handlers
 Add method to inform other software chunks about avatar change? (external command / custom hook)
 
--- a/avatar.c	Fri Nov 06 15:58:45 2009 +0200
+++ b/avatar.c	Wed Nov 11 14:00:56 2009 +0200
@@ -50,7 +50,13 @@
 
 static guint avatar_cid = 0;
 
-GSList *reply_handlers = NULL;
+static GSList *reply_handlers = NULL;
+
+static LmMessageHandler *avatar_metadata_reply_handler = NULL;
+
+// predeclarations
+
+static LmHandlerResult avatar_retrieve_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata);
 
 // png stuff
 
@@ -463,10 +469,8 @@
 
 // reply handler for metadata publish request
 // just prints error message if unsuccessful
-LmHandlerResult avatar_publish_metadata_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
+static LmHandlerResult avatar_publish_metadata_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
 {
-	reply_handlers = g_slist_remove (reply_handlers, handler);
-
 	switch (lm_message_get_sub_type (message)) {
 	case LM_MESSAGE_SUB_TYPE_RESULT:
 		break;
@@ -500,7 +504,7 @@
 
 // reply handler for data publish request
 // sends metadata update request or prints error message
-LmHandlerResult avatar_publish_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
+static LmHandlerResult avatar_publish_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
 {
 	LmMessage *request = (LmMessage *) userdata;
 
@@ -509,17 +513,8 @@
 	switch (lm_message_get_sub_type (message)) {
 	case LM_MESSAGE_SUB_TYPE_RESULT:
 
-		{
-			// XXX we may use only one instance of this...
-			LmMessageHandler *mhandler = lm_message_handler_new (avatar_publish_metadata_reply_handler, NULL, NULL);
-
-			reply_handlers = g_slist_append (reply_handlers, mhandler);
-
-			lm_connection_send_with_reply (connection, request, mhandler, NULL);
-
-			lm_message_handler_unref (mhandler);
-			lm_message_unref (request);
-		}
+		lm_connection_send_with_reply (connection, request, avatar_metadata_reply_handler, NULL);
+		lm_message_unref (request);
 
 		break;
 
@@ -566,12 +561,36 @@
 		struct stat buf;
 
 		if (stat (file, &buf) == -1) {
-			gchar *bjid = jidtodisp (jid);
+			gchar            *bjid = jidtodisp (jid);
+			LmMessage        *request;
+			LmMessageNode    *node;
+			LmMessageHandler *dhandler;
+
+			scr_WriteIncomingMessage (bjid, "No avatar for this buddy yet, sending request.", 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); // NO conversion from utf-8
+
+			// create data request
+			request = lm_message_new_with_sub_type (bjid, LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_GET);
+			node = lm_message_get_node (request);
+			lm_message_node_set_attribute (node, "from", lm_connection_get_jid (lconnection));
+
+			node = lm_message_node_add_child (node, "pubsub", NULL);
+			lm_message_node_set_attribute (node, "xmlns", NS_PUBSUB);
 
-			scr_WriteIncomingMessage (bjid, "No avatar for this buddy yet.", 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); // NO conversion from utf-8
+			node = lm_message_node_add_child (node, "items", NULL);
+			lm_message_node_set_attribute (node, "node", NS_AVATAR_DATA);
+
+			node = lm_message_node_add_child (node, "item", NULL);
 
-			g_free (bjid);
+			// create handler
+			dhandler = lm_message_handler_new (avatar_retrieve_data_reply_handler, bjid, g_free);
+			reply_handlers = g_slist_append (reply_handlers, dhandler);
 
+			// send
+			lm_connection_send_with_reply (lconnection, request, dhandler, NULL);
+
+			lm_message_handler_unref (dhandler);
+			lm_message_unref (request);
+			// bjid will be freed on handler destruction
 			return TRUE;
 		}
 	}
@@ -652,7 +671,7 @@
 
 // reply handler for image/png data request
 // saves image and prints it to buddy buffer
-LmHandlerResult avatar_retrieve_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
+static LmHandlerResult avatar_retrieve_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
 {
 	gchar *from = (gchar *) userdata;
 
@@ -824,19 +843,19 @@
 		lm_message_node_set_attributes (node, "bytes", bytes, "id", id, "type", "image/png", NULL);
 
 		g_free (bytes);
-	}
+
+		// create handler
+		LmMessageHandler *handler = lm_message_handler_new (avatar_publish_data_reply_handler, (gpointer) datarequest, (GDestroyNotify) lm_message_unref /* custom, remove from queue? */);
+		reply_handlers = g_slist_append (reply_handlers, handler);
 
-	// create handler
-	if (len) 
-		handler = lm_message_handler_new (avatar_publish_data_reply_handler, (gpointer) datarequest, (GDestroyNotify) lm_message_unref /* custom, remove from queue? */);
-	else 
-		handler = lm_message_handler_new (avatar_publish_metadata_reply_handler, NULL, NULL);
-	reply_handlers = g_slist_append (reply_handlers, handler);
+		// send
+		lm_connection_send_with_reply (lconnection, request, handler, NULL);
 
-	// send
-	lm_connection_send_with_reply (lconnection, request, handler, NULL);
+		lm_message_handler_unref (handler);
+	} else 
+		// send
+		lm_connection_send_with_reply (lconnection, request, avatar_metadata_reply_handler, NULL);
 
-	lm_message_handler_unref (handler);
 	lm_message_unref (request);
 }
 
@@ -1017,10 +1036,10 @@
 {
 	GSList *hel;
 
-	// let's hope, that after invalidation, lm will remove and free unreffed by us handler
 	for (hel = reply_handlers; hel; hel = hel->next) {
 		LmMessageHandler *handler = (LmMessageHandler *) hel->data;
 		lm_message_handler_invalidate (handler);
+		// it is already unreffed
 	}
 
 	g_slist_free (reply_handlers);
@@ -1043,6 +1062,7 @@
 const gchar *g_module_check_init (GModule *module)
 {
 	pep_register_xmlns_handler (NS_AVATAR_METADATA, avatar_handler, NULL, NULL);
+	avatar_metadata_reply_handler = lm_message_handler_new (avatar_publish_metadata_reply_handler, NULL, NULL);
 
 	cmd_add ("avatar", "", COMPL_FILENAME, 0, do_avatar, NULL);
 	
@@ -1056,16 +1076,21 @@
 
 void g_module_unload (GModule *module)
 {
-	pep_unregister_xmlns_handler (NS_AVATAR_METADATA);
-
-	avatar_free_reply_handlers ();
+	xmpp_del_feature (NS_AVATAR_METADATA);
+	xmpp_del_feature (NS_AVATAR_METADATA_NOTIFY);
 
 	hk_del_handler (avatar_hh, NULL);
 
 	cmd_del ("avatar");
 
-	xmpp_del_feature (NS_AVATAR_METADATA);
-	xmpp_del_feature (NS_AVATAR_METADATA_NOTIFY);
+	pep_unregister_xmlns_handler (NS_AVATAR_METADATA);
+
+	avatar_free_reply_handlers ();
+
+	if (avatar_metadata_reply_handler) {
+		lm_message_handler_invalidate (avatar_metadata_reply_handler);
+		lm_message_handler_unref (avatar_metadata_reply_handler);
+	}
 }
 
-/* vim: se ts=4: */
+/* vim: se ts=4 sw=4: */