changeset 30648:1558900f47e5

Merged my changes that fix #11964 and #12593. Mark looked over them and said they looked good to him. applied changes from 7b998c02b684a694f1089bee715e4a3952bbcf08 through 563c6a79e1266b750fe4bd608890195cfbcd8a2c
author ivan.komarov@soc.pidgin.im
date Sat, 30 Oct 2010 21:53:38 +0000
parents 4297feb30ad1
children f9664876549f
files libpurple/protocols/oscar/family_icbm.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h libpurple/protocols/oscar/userinfo.c
diffstat 4 files changed, 74 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_icbm.c	Sat Oct 30 21:36:34 2010 +0000
+++ b/libpurple/protocols/oscar/family_icbm.c	Sat Oct 30 21:53:38 2010 +0000
@@ -1691,7 +1691,7 @@
 				purple_debug_misc("oscar", "X-Status: Received XML reply\n");
 				if (xml) {
 					GString *xstatus;
-					char *tmp1, *tmp2;
+					char *tmp1, *tmp2, *unescaped_xstatus;
 
 					/* purple_debug_misc("oscar", "X-Status: XML reply: %s\n", xml); */
 
@@ -1709,29 +1709,32 @@
 						tmp1 += 12;
 						tmp2 = strstr(tmp1, "</desc>");
 						if (tmp2 != NULL) {
-							if (xstatus->len > 0)
+							if (xstatus->len > 0 && tmp2 > tmp1)
 								g_string_append(xstatus, " - ");
 							g_string_append_len(xstatus, tmp1, tmp2 - tmp1);
 						}
 					}
-					if (xstatus->len > 0) {
-						purple_debug_misc("oscar", "X-Status reply: %s\n", xstatus->str);
+					unescaped_xstatus = purple_unescape_text(xstatus->str);
+					g_string_free(xstatus, TRUE);
+					if (*unescaped_xstatus) {
+						purple_debug_misc("oscar", "X-Status reply: %s\n", unescaped_xstatus);
 						account = purple_connection_get_account(od->gc);
 						buddy = purple_find_buddy(account, bn);
 						presence = purple_buddy_get_presence(buddy);
-						status = purple_presence_get_active_status(presence);
-						purple_prpl_got_user_status(account, bn,
-								purple_status_get_id(status),
-								"message", xstatus->str, NULL);
+						status = purple_presence_get_status(presence, "mood");
+						if (status) {
+							purple_prpl_got_user_status(account, bn,
+									"mood",
+									PURPLE_MOOD_NAME, purple_status_get_attr_string(status, PURPLE_MOOD_NAME),
+									PURPLE_MOOD_COMMENT, unescaped_xstatus, NULL);
+						}
 					}
-					g_string_free(xstatus, TRUE);
+					g_free(unescaped_xstatus);
 				} else {
 					purple_debug_misc("oscar", "X-Status: Can't get XML reply string\n");
 				}
 			} else {
 				purple_debug_misc("oscar", "X-Status: 0x0004, 0x000b not an xstatus reply\n");
-				/* if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
-					ret = userfunc(od, conn, frame, channel, sn, reason); */
 			}
 
 		}
--- a/libpurple/protocols/oscar/oscar.c	Sat Oct 30 21:36:34 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Sat Oct 30 21:53:38 2010 +0000
@@ -1304,6 +1304,8 @@
 {
 	PurpleConnection *gc;
 	PurpleAccount *account;
+	PurpleBuddy *buddy = NULL;
+	PurpleStatus *previous_status = NULL;
 	struct buddyinfo *bi;
 	time_t time_idle = 0, signon = 0;
 	int type = 0;
@@ -1313,8 +1315,6 @@
 	aim_userinfo_t *info;
 	char *message = NULL;
 	char *itmsurl = NULL;
-	char *tmp;
-	const char *tmp2;
 
 	gc = od->gc;
 	account = purple_connection_get_account(gc);
@@ -1326,6 +1326,11 @@
 	g_return_val_if_fail(info != NULL, 1);
 	g_return_val_if_fail(info->bn != NULL, 1);
 
+	buddy = purple_find_buddy(account, info->bn);
+	if (buddy) {
+		previous_status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));
+	}
+
 	/*
 	 * If this is an AIM buddy and their name has formatting, set their
 	 * server alias.
@@ -1389,40 +1394,33 @@
 			status_id = OSCAR_STATUS_ID_AVAILABLE;
 	}
 
-	if (info->flags & AIM_FLAG_WIRELESS)
-	{
+	if (info->flags & AIM_FLAG_WIRELESS) {
 		purple_prpl_got_user_status(account, info->bn, OSCAR_STATUS_ID_MOBILE, NULL);
 	} else {
 		purple_prpl_got_user_status_deactive(account, info->bn, OSCAR_STATUS_ID_MOBILE);
 	}
 
-	if (info->status != NULL && info->status[0] != '\0') {
-		/* Grab the available message */
-		message = oscar_encoding_to_utf8(info->status_encoding, info->status, info->status_len);
+	/* Empty status means we should unset the status message. NULL status means we should keep it from the previous active status.
+	 * Same goes for itmsurl (which is available only for the "available" status).
+	 */
+	if (info->status != NULL) {
+		message = (info->status_len > 0) ? oscar_encoding_to_utf8(info->status_encoding, info->status, info->status_len) : NULL;
+	} else if (previous_status != NULL) {
+		message = g_strdup(purple_status_get_attr_string(previous_status, "message"));
 	}
 
-	tmp2 = tmp = (message ? purple_markup_escape_text(message, -1) : NULL);
-
 	if (strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE) == 0) {
-		if (info->itmsurl_encoding && info->itmsurl && info->itmsurl_len) {
-			/* Grab the iTunes Music Store URL */
-			itmsurl = oscar_encoding_to_utf8(info->itmsurl_encoding, info->itmsurl, info->itmsurl_len);
+		if (info->itmsurl != NULL) {
+			itmsurl = (info->itmsurl_len > 0) ? oscar_encoding_to_utf8(info->itmsurl_encoding, info->itmsurl, info->itmsurl_len) : NULL;
+		} else if (previous_status != NULL && purple_status_is_available(previous_status)) {
+			itmsurl = g_strdup(purple_status_get_attr_string(previous_status, "itmsurl"));
 		}
-
-		if (tmp2 == NULL && itmsurl != NULL)
-			/*
-			 * The message can't be NULL because NULL means it was the
-			 * last attribute, so the itmsurl would get ignored below.
-			 */
-			tmp2 = "";
-
-		purple_prpl_got_user_status(account, info->bn, status_id,
-									"message", tmp2, "itmsurl", itmsurl, NULL);
+		purple_debug_info("oscar", "Activating status '%s' for buddy %s, message = '%s', itmsurl = '%s'\n", status_id, info->bn, message, itmsurl);
+		purple_prpl_got_user_status(account, info->bn, status_id, "message", message, "itmsurl", itmsurl, NULL);
+	} else {
+		purple_debug_info("oscar", "Activating status '%s' for buddy %s, message = '%s'\n", status_id, info->bn, message);
+		purple_prpl_got_user_status(account, info->bn, status_id, "message", message, NULL);
 	}
-	else
-		purple_prpl_got_user_status(account, info->bn, status_id, "message", tmp2, NULL);
-
-	g_free(tmp);
 
 	g_free(message);
 	g_free(itmsurl);
@@ -4581,7 +4579,7 @@
 	od = purple_connection_get_protocol_data(gc);
 	userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b));
 
-	oscar_user_info_append_status(gc, user_info, b, userinfo, /* strip_html_tags */ TRUE);
+	oscar_user_info_append_status(gc, user_info, b, userinfo, /* use_html_status */ FALSE);
 
 	if (full)
 		oscar_user_info_append_extra_info(gc, user_info, b, userinfo);
@@ -4619,13 +4617,9 @@
 		message = purple_status_get_attr_string(status, "message");
 		if (message != NULL)
 		{
-			gchar *tmp1, *tmp2;
-			tmp1 = purple_markup_strip_html(message);
-			purple_util_chrreplace(tmp1, '\n', ' ');
-			tmp2 = g_markup_escape_text(tmp1, -1);
-			ret = oscar_util_format_string(tmp2, purple_account_get_username(account));
-			g_free(tmp1);
-			g_free(tmp2);
+			gchar *tmp = oscar_util_format_string(message, purple_account_get_username(account));
+			ret = purple_markup_escape_text(tmp, -1);
+			g_free(tmp);
 		}
 		else if (purple_status_is_available(status))
 		{
--- a/libpurple/protocols/oscar/oscar.h	Sat Oct 30 21:36:34 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Sat Oct 30 21:53:38 2010 +0000
@@ -1304,7 +1304,7 @@
 
 /* userinfo.c - displaying user information */
 
-void oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean strip_html_tags);
+void oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean use_html_status);
 void oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo);
 void oscar_user_info_display_error(OscarData *od, guint16 error_reason, char *buddy);
 void oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info);
--- a/libpurple/protocols/oscar/userinfo.c	Sat Oct 30 21:36:34 2010 +0000
+++ b/libpurple/protocols/oscar/userinfo.c	Sat Oct 30 21:53:38 2010 +0000
@@ -173,17 +173,17 @@
  * @param user_info A PurpleNotifyUserInfo object to which status information will be added
  * @param b The PurpleBuddy whose status is desired. This or the aim_userinfo_t (or both) must be passed to oscar_user_info_append_status().
  * @param userinfo The aim_userinfo_t of the buddy whose status is desired. This or the PurpleBuddy (or both) must be passed to oscar_user_info_append_status().
- * @param strip_html_tags If strip_html_tags is TRUE, tags embedded in the status message will be stripped, returning a non-formatted string. The string will still be HTML escaped.
+ * @param use_html_status If TRUE, prefer HTML-formatted away message over plaintext available message.
  */
 void
-oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean strip_html_tags)
+oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean use_html_status)
 {
 	PurpleAccount *account = purple_connection_get_account(gc);
 	OscarData *od;
 	PurplePresence *presence = NULL;
 	PurpleStatus *status = NULL;
 	gchar *message = NULL, *itmsurl = NULL, *tmp;
-	gboolean is_away;
+	gboolean escaping_needed = TRUE;
 
 	od = purple_connection_get_protocol_data(gc);
 
@@ -205,9 +205,10 @@
 	   the "message" attribute of the status contains only the plaintext
 	   message. */
 	if (userinfo) {
-		if ((userinfo->flags & AIM_FLAG_AWAY) && userinfo->away_len > 0 && userinfo->away != NULL && userinfo->away_encoding != NULL) {
+		if ((userinfo->flags & AIM_FLAG_AWAY) && use_html_status && userinfo->away_len > 0 && userinfo->away != NULL && userinfo->away_encoding != NULL) {
 			/* Away message */
 			message = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len);
+			escaping_needed = FALSE;
 		} else {
 			/*
 			 * Available message or non-HTML away message (because that's
@@ -227,44 +228,26 @@
 		itmsurl = g_strdup(purple_status_get_attr_string(status, "itmsurl"));
 	}
 
-	is_away = ((status && !purple_status_is_available(status)) ||
-			   (userinfo && (userinfo->flags & AIM_FLAG_AWAY)));
-
-	if (strip_html_tags) {
-		/* Away messages are HTML, but available messages were originally plain text.
-		 * We therefore need to strip away messages but not available messages if we're asked to remove HTML tags.
-		 */
-		/*
-		 * It seems like the above comment no longer applies.  All messages need
-		 * to be escaped.
-		 */
-		if (message) {
-			gchar *tmp2;
-			tmp = purple_markup_strip_html(message);
-			g_free(message);
-			tmp2 = g_markup_escape_text(tmp, -1);
-			g_free(tmp);
-			message = tmp2;
-		}
-
-	} else {
-		if (itmsurl) {
-			tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
-								  itmsurl, message);
+	if (message) {
+		tmp = oscar_util_format_string(message, purple_account_get_username(account));
+		g_free(message);
+		message = tmp;
+		if (escaping_needed) {
+			tmp = purple_markup_escape_text(message, -1);
 			g_free(message);
 			message = tmp;
 		}
 	}
-	g_free(itmsurl);
 
-	if (message) {
-		tmp = oscar_util_format_string(message, purple_account_get_username(account));
+	if (use_html_status && itmsurl) {
+		tmp = g_strdup_printf("<a href=\"%s\">%s</a>", itmsurl, message);
 		g_free(message);
 		message = tmp;
 	}
 
 	if (b) {
 		if (purple_presence_is_online(presence)) {
+			gboolean is_away = ((status && !purple_status_is_available(status)) || (userinfo && (userinfo->flags & AIM_FLAG_AWAY)));
 			if (oscar_util_valid_name_icq(purple_buddy_get_name(b)) || is_away || !message || !(*message)) {
 				/* Append the status name for online ICQ statuses, away AIM statuses, and for all buddies with no message.
 				 * If the status name and the message are the same, only show one. */
@@ -299,12 +282,22 @@
 
 	if (presence) {
 		const char *mood;
-		const char *description;
+		const char *comment;
+		char *description;
 		status = purple_presence_get_status(presence, "mood");
-		mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
-		description = icq_get_custom_icon_description(mood);
-		if (description && *description)
-			purple_notify_user_info_add_pair(user_info, _("Mood"), _(description));
+		mood = icq_get_custom_icon_description(purple_status_get_attr_string(status, PURPLE_MOOD_NAME));
+		if (mood) {
+			comment = purple_status_get_attr_string(status, PURPLE_MOOD_COMMENT);
+			if (comment) {
+				char *escaped_comment = purple_markup_escape_text(comment, -1);
+				description = g_strdup_printf("%s (%s)", _(mood), escaped_comment);
+				g_free(escaped_comment);
+			} else {
+				description = g_strdup(_(mood));
+			}
+			purple_notify_user_info_add_pair(user_info, _("Mood"), description);
+			g_free(description);
+		}
 	}
 
 	purple_notify_user_info_add_pair(user_info, _("Status"), message);
@@ -458,7 +451,7 @@
 	}
 	oscar_user_info_convert_and_add_hyperlink(account, od, user_info, _("Personal Web Page"), info->email, "");
 	if (buddy != NULL)
-		oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* strip_html_tags */ FALSE);
+		oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* use_html_status */ TRUE);
 
 	oscar_user_info_convert_and_add(account, od, user_info, _("Additional Information"), info->info);
 	purple_notify_user_info_add_section_break(user_info);
@@ -504,7 +497,7 @@
 	PurpleNotifyUserInfo *user_info = purple_notify_user_info_new();
 	gchar *tmp = NULL, *info_utf8 = NULL, *base_profile_url = NULL;
 
-	oscar_user_info_append_status(gc, user_info, /* PurpleBuddy */ NULL, userinfo, /* strip_html_tags */ FALSE);
+	oscar_user_info_append_status(gc, user_info, /* PurpleBuddy */ NULL, userinfo, /* use_html_status */ TRUE);
 
 	if ((userinfo->present & AIM_USERINFO_PRESENT_IDLE) && userinfo->idletime != 0) {
 		tmp = purple_str_seconds_to_string(userinfo->idletime*60);