diff libpurple/protocols/jabber/buddy.c @ 28112:1ea1aee71848

jabber: Fix setting Google Talk avatar at login. Google Talk (at some point) started returning IQ errors when setting the avatar in the first 10 seconds of login. This was reported by Bill Lovett to the jdev mailing list and he included the 10-second "magic number".
author Paul Aurich <paul@darkrain42.org>
date Sat, 01 Aug 2009 01:53:02 +0000
parents 82ac0bef7d89
children eb2d17945ce3 b6a1ade72555
line wrap: on
line diff
--- a/libpurple/protocols/jabber/buddy.c	Fri Jul 31 14:40:03 2009 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Sat Aug 01 01:53:02 2009 +0000
@@ -463,6 +463,11 @@
 	if(!js->vcard_fetched)
 		return;
 
+	if (js->vcard_timer) {
+		purple_timeout_remove(js->vcard_timer);
+		js->vcard_timer = 0;
+	}
+
 	g_free(js->avatar_hash);
 	js->avatar_hash = NULL;
 
@@ -854,12 +859,26 @@
 	}
 }
 
+static gboolean
+set_own_vcard_cb(gpointer data)
+{
+	JabberStream *js = data;
+	PurpleAccount *account = purple_connection_get_account(js->gc);
+
+	js->vcard_timer = 0;
+
+	jabber_set_info(js->gc, purple_account_get_user_info(account));
+
+	return FALSE;
+}
+
 static void jabber_vcard_save_mine(JabberStream *js, const char *from,
                                    JabberIqType type, const char *id,
                                    xmlnode *packet, gpointer data)
 {
 	xmlnode *vcard, *photo, *binval;
 	char *txt, *vcard_hash = NULL;
+	PurpleAccount *account;
 
 	if (type == JABBER_IQ_ERROR) {
 		xmlnode *error;
@@ -870,12 +889,13 @@
 			return;
 	}
 
+	account = purple_connection_get_account(js->gc);
+
 	if((vcard = xmlnode_get_child(packet, "vCard")) ||
 			(vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp")))
 	{
 		txt = xmlnode_to_str(vcard, NULL);
-		purple_account_set_user_info(purple_connection_get_account(js->gc), txt);
-
+		purple_account_set_user_info(account, txt);
 		g_free(txt);
 	} else {
 		/* if we have no vCard, then lets not overwrite what we might have locally */
@@ -898,8 +918,17 @@
 
 	/* Republish our vcard if the photo is different than the server's */
 	if (!purple_strequal(vcard_hash, js->initial_avatar_hash)) {
-		PurpleAccount *account = purple_connection_get_account(js->gc);
-		jabber_set_info(js->gc, purple_account_get_user_info(account));
+		/*
+		 * Google Talk has developed the behavior that it will not accept
+		 * a vcard set in the first 10 seconds (or so) of the connection;
+		 * it returns an error (namespaces trimmed):
+		 * <error code="500" type="wait"><internal-server-error/></error>.
+		 */
+		if (js->googletalk)
+			js->vcard_timer = purple_timeout_add_seconds(10, set_own_vcard_cb,
+			                                             js);
+		else
+			jabber_set_info(js->gc, purple_account_get_user_info(account));
 	} else if (js->initial_avatar_hash) {
 		/* Our photo is in the vcard, so advertise vcard-temp updates */
 		js->avatar_hash = g_strdup(js->initial_avatar_hash);