changeset 30320:e9fbbfe1ab70

merge of '5b9ae21a0927d9a160964bfb1cad7a43253fba0d' and '874c07e0346e899fe81f0ecd50471f478e1161c9'
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sat, 31 Jul 2010 23:43:37 +0000
parents 76049fde7ad2 (diff) fa6bf2431ff0 (current diff)
children 00851eae12c7
files
diffstat 7 files changed, 156 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Jul 31 22:25:13 2010 +0000
+++ b/ChangeLog	Sat Jul 31 23:43:37 2010 +0000
@@ -22,6 +22,10 @@
 	IRC:
 	* Fix non-ASCII arguments to /mode et al.  (thanks to Max Ulidtko)
 
+	MSN:
+	* Support for web-based buddy icons, used when a buddy logs in to the
+	  messenger on the Live website.
+
 	MXit:
 	* Fix filename for the Shocked emoticon. (#12364)
 	* Implement the new naming conventions where possible. (MXitId, etc)
--- a/libpurple/protocols/msn/msn.c	Sat Jul 31 22:25:13 2010 +0000
+++ b/libpurple/protocols/msn/msn.c	Sat Jul 31 23:43:37 2010 +0000
@@ -2204,6 +2204,7 @@
 		const gchar *url_text, size_t len, const gchar *error_message)
 {
 	MsnGetInfoData *info_data = (MsnGetInfoData *)data;
+	MsnSession *session;
 	PurpleNotifyUserInfo *user_info;
 	char *stripped, *p, *q, *tmp;
 	char *user_url = NULL;
@@ -2221,15 +2222,8 @@
 
 	purple_debug_info("msn", "In msn_got_info,url_text:{%s}\n",url_text);
 
-	/* Make sure the connection is still valid */
-	/* TODO: Instead of this, we should be canceling this when we disconnect */
-	if (g_list_find(purple_connections_get_all(), info_data->gc) == NULL)
-	{
-		purple_debug_warning("msn", "invalid connection. ignoring buddy info.\n");
-		g_free(info_data->name);
-		g_free(info_data);
-		return;
-	}
+	session = purple_connection_get_protocol_data(info_data->gc);
+	session->url_datas = g_slist_remove(session->url_datas, url_data);
 
 	user_info = purple_notify_user_info_new();
 	has_tooltip_text = msn_tooltip_extract_info_text(user_info, info_data);
@@ -2614,13 +2608,14 @@
 	/* Try to put the photo in there too, if there's one */
 	if (photo_url_text)
 	{
-		purple_util_fetch_url_len(photo_url_text, FALSE, NULL, FALSE, MAX_HTTP_BUDDYICON_BYTES, msn_got_photo,
-					   info2_data);
+		url_data = purple_util_fetch_url_len(photo_url_text, FALSE, NULL, FALSE,
+		                                     MAX_HTTP_BUDDYICON_BYTES,
+		                                     msn_got_photo, info2_data);
+		session->url_datas = g_slist_prepend(session->url_datas, url_data);
 	}
 	else
 	{
-		/* Emulate a callback */
-		/* TODO: Huh? */
+		/* Finish the Get Info and show the user something */
 		msn_got_photo(NULL, info2_data, NULL, 0, NULL);
 	}
 }
@@ -2639,10 +2634,12 @@
 	PurpleNotifyUserInfo *user_info = info2_data->user_info;
 	char *photo_url_text = info2_data->photo_url_text;
 
-	/* Make sure the connection is still valid if we got here by fetching a photo url */
-	/* TODO: Instead of this, we should be canceling this when we disconnect */
-	if (url_text && (error_message != NULL ||
-					 g_list_find(purple_connections_get_all(), info_data->gc) == NULL))
+	if (url_data) {
+		MsnSession *session = purple_connection_get_protocol_data(info_data->gc);
+		session->url_datas = g_slist_remove(session->url_datas, url_data);
+	}
+
+	if (url_text && error_message)
 	{
 		purple_debug_warning("msn", "invalid connection. ignoring buddy photo info.\n");
 		g_free(stripped);
@@ -2697,8 +2694,10 @@
 static void
 msn_get_info(PurpleConnection *gc, const char *name)
 {
+	MsnSession *session = purple_connection_get_protocol_data(gc);
 	MsnGetInfoData *data;
 	char *url;
+	PurpleUtilFetchUrlData *url_data;
 
 	data       = g_new0(MsnGetInfoData, 1);
 	data->gc   = gc;
@@ -2706,9 +2705,10 @@
 
 	url = g_strdup_printf("%s%s", PROFILE_URL, name);
 
-	purple_util_fetch_url(url, FALSE,
-				   "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
-				   TRUE, msn_got_info, data);
+	url_data = purple_util_fetch_url(url, FALSE,
+	                                 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
+	                                 TRUE, msn_got_info, data);
+	session->url_datas = g_slist_prepend(session->url_datas, url_data);
 
 	g_free(url);
 }
--- a/libpurple/protocols/msn/object.c	Sat Jul 31 22:25:13 2010 +0000
+++ b/libpurple/protocols/msn/object.c	Sat Jul 31 23:43:37 2010 +0000
@@ -96,15 +96,29 @@
 	GET_STRING_TAG(friendly, "Friendly");
 	GET_STRING_TAG(sha1d,    "SHA1D");
 	GET_STRING_TAG(sha1c,    "SHA1C");
+	GET_STRING_TAG(url,      "Url");
+	GET_STRING_TAG(url1,     "Url1");
 
 	/* If we are missing any of the required elements then discard the object */
-	/* SHA1C is not always sent anymore */
 	if (obj->creator == NULL || obj->size == 0 || obj->type == 0
-			|| obj->location == NULL || obj->friendly == NULL
-			|| obj->sha1d == NULL /*|| obj->sha1c == NULL*/) {
+	 || obj->sha1d == NULL) {
 		purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
 		msn_object_destroy(obj);
-		obj = NULL;
+		return NULL;
+	}
+
+	if (obj->location == NULL || obj->friendly == NULL) {
+		/* Location/friendly are required for non-buddyicon objects */
+		if (obj->type != MSN_OBJECT_USERTILE) {
+			purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
+			msn_object_destroy(obj);
+			return NULL;
+		/* Buddy icon object can contain Url/Url1 instead */
+		} else if (obj->url == NULL || obj->url1 == NULL) {
+			purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
+			msn_object_destroy(obj);
+			return NULL;
+		}
 	}
 
 	return obj;
@@ -284,6 +298,24 @@
 	obj->sha1c = g_strdup(sha1c);
 }
 
+void
+msn_object_set_url(MsnObject *obj, const char *url)
+{
+	g_return_if_fail(obj != NULL);
+
+	g_free(obj->url);
+	obj->url = g_strdup(url);
+}
+
+void
+msn_object_set_url1(MsnObject *obj, const char *url)
+{
+	g_return_if_fail(obj != NULL);
+
+	g_free(obj->url1);
+	obj->url1 = g_strdup(url);
+}
+
 const char *
 msn_object_get_creator(const MsnObject *obj)
 {
@@ -352,6 +384,22 @@
 	}
 }
 
+const char *
+msn_object_get_url(const MsnObject *obj)
+{
+	g_return_val_if_fail(obj != NULL, NULL);
+
+	return obj->url;
+}
+
+const char *
+msn_object_get_url1(const MsnObject *obj)
+{
+	g_return_val_if_fail(obj != NULL, NULL);
+
+	return obj->url1;
+}
+
 static MsnObject *
 msn_object_find_local(const char *sha1)
 {
--- a/libpurple/protocols/msn/object.h	Sat Jul 31 22:25:13 2010 +0000
+++ b/libpurple/protocols/msn/object.h	Sat Jul 31 23:43:37 2010 +0000
@@ -50,6 +50,8 @@
 	char *friendly;
 	char *sha1d;
 	char *sha1c;
+	char *url;
+	char *url1;
 } MsnObject;
 
 /**
@@ -155,6 +157,20 @@
 void msn_object_set_image(MsnObject *obj, PurpleStoredImage *img);
 
 /**
+ * Sets the url field in a MsnObject.
+ *
+ * @param url The url value.
+ */
+void msn_object_set_url(MsnObject *obj, const char *url);
+
+/**
+ * Sets the url1 field in a MsnObject.
+ *
+ * @param url1 The url1 value.
+ */
+void msn_object_set_url1(MsnObject *obj, const char *url);
+
+/**
  * Returns a MsnObject's creator value.
  *
  * @param obj The object.
@@ -235,6 +251,24 @@
  */
 PurpleStoredImage *msn_object_get_image(const MsnObject *obj);
 
+/**
+ * Returns a MsnObject's url value.
+ *
+ * @param obj The object.
+ *
+ * @return The url value.
+ */
+const char *msn_object_get_url(const MsnObject *obj);
+
+/**
+ * Returns a MsnObject's url1 value.
+ *
+ * @param obj The object.
+ *
+ * @return The url1 value.
+ */
+const char *msn_object_get_url1(const MsnObject *obj);
+
 void msn_object_set_local(MsnObject *obj);
 
 #endif /* MSN_OBJECT_H */
--- a/libpurple/protocols/msn/session.c	Sat Jul 31 22:25:13 2010 +0000
+++ b/libpurple/protocols/msn/session.c	Sat Jul 31 23:43:37 2010 +0000
@@ -57,6 +57,11 @@
 
 	session->destroying = TRUE;
 
+	while (session->url_datas) {
+		purple_util_fetch_url_cancel(session->url_datas->data);
+		session->url_datas = g_slist_delete_link(session->url_datas, session->url_datas);
+	}
+
 	if (session->connected)
 		msn_session_disconnect(session);
 
--- a/libpurple/protocols/msn/session.h	Sat Jul 31 22:25:13 2010 +0000
+++ b/libpurple/protocols/msn/session.h	Sat Jul 31 23:43:37 2010 +0000
@@ -122,6 +122,8 @@
 
 	GHashTable *soap_table;
 	guint soap_cleanup_handle;
+
+	GSList *url_datas; /**< PurpleUtilFetchUrlData to be cancelled on exit */
 };
 
 /**
--- a/libpurple/protocols/msn/slp.c	Sat Jul 31 22:25:13 2010 +0000
+++ b/libpurple/protocols/msn/slp.c	Sat Jul 31 23:43:37 2010 +0000
@@ -39,6 +39,11 @@
 
 static void request_user_display(MsnUser *user);
 
+typedef struct {
+	MsnSession *session;
+	const char *remote_user;
+	const char *sha1;
+} MsnFetchUserDisplayData;
 
 /**************************************************************************
  * Util
@@ -1405,6 +1410,26 @@
 }
 
 static void
+fetched_user_display(PurpleUtilFetchUrlData *url_data, gpointer user_data,
+	const gchar *url_text, gsize len, const gchar *error_message)
+{
+	MsnFetchUserDisplayData *data = user_data;
+	MsnSession *session = data->session;
+
+	session->url_datas = g_slist_remove(session->url_datas, url_data);
+
+	if (url_text) {
+		purple_buddy_icons_set_for_user(session->account, data->remote_user,
+		                                g_memdup(url_text, len), len,
+		                                data->sha1);
+	}
+
+	end_user_display(NULL, session);
+
+	g_free(user_data);
+}
+
+static void
 request_user_display(MsnUser *user)
 {
 	PurpleAccount *account;
@@ -1425,8 +1450,20 @@
 	if (g_ascii_strcasecmp(user->passport,
 						   purple_account_get_username(account)))
 	{
-		msn_slplink_request_object(slplink, info, got_user_display,
-								   end_user_display, obj);
+		const char *url = msn_object_get_url1(obj);
+		if (url) {
+			MsnFetchUserDisplayData *data = g_new0(MsnFetchUserDisplayData, 1);
+			PurpleUtilFetchUrlData *url_data;
+			data->session = session;
+			data->remote_user = user->passport;
+			data->sha1 = info;
+			url_data = purple_util_fetch_url_len(url, TRUE, NULL, TRUE, 200*1024,
+			                                     fetched_user_display, data);
+			session->url_datas = g_slist_prepend(session->url_datas, url_data);
+		} else {
+			msn_slplink_request_object(slplink, info, got_user_display,
+			                           end_user_display, obj);
+		}
 	}
 	else
 	{