changeset 27455:07d09a987b86

Allow setting some personal information for an account. Currently the name and phone number(s) can be set. It's possible to set a lot of information about a Yahoo! account that can be set for an XMPP account, but the list looked too huge for me. So I just picked the ones that I thought could be useful. Someone might want to know about the birthdays too ... I don't know. Someone should test this on Yahoo! JAPAN (why not 'Japan', by the way?)
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Fri, 10 Jul 2009 15:18:09 +0000
parents 1b580473e753
children 048550ab13a4
files libpurple/protocols/yahoo/libymsg.c libpurple/protocols/yahoo/libymsg.h libpurple/protocols/yahoo/yahoo_aliases.c libpurple/protocols/yahoo/yahoo_aliases.h libpurple/protocols/yahoo/yahoo_friend.h libpurple/protocols/yahoo/yahoo_packet.c
diffstat 6 files changed, 181 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/yahoo/libymsg.c	Fri Jul 10 06:37:13 2009 +0000
+++ b/libpurple/protocols/yahoo/libymsg.c	Fri Jul 10 15:18:09 2009 +0000
@@ -3538,6 +3538,8 @@
 	g_free(yd->pending_chat_goto);
 	g_strfreev(yd->profiles);
 
+	yahoo_personal_details_reset(&yd->ypd);
+
 	g_free(yd->current_list15_grp);
 
 	g_free(yd);
@@ -4012,9 +4014,13 @@
 				   "Unable to request mail login token; forwarding to login screen.");
 		purple_notify_uri(gc, yahoo_mail_url);
 	}
-
 }
 
+static void
+yahoo_set_userinfo_fn(PurplePluginAction *action)
+{
+	yahoo_set_userinfo(action->context);
+}
 
 static void yahoo_show_act_id(PurplePluginAction *action)
 {
@@ -4061,6 +4067,10 @@
 	GList *m = NULL;
 	PurplePluginAction *act;
 
+	act = purple_plugin_action_new(_("Set User Info..."),
+			yahoo_set_userinfo_fn);
+	m = g_list_append(m, act);
+
 	act = purple_plugin_action_new(_("Activate ID..."),
 			yahoo_show_act_id);
 	m = g_list_append(m, act);
--- a/libpurple/protocols/yahoo/libymsg.h	Fri Jul 10 06:37:13 2009 +0000
+++ b/libpurple/protocols/yahoo/libymsg.h	Fri Jul 10 15:18:09 2009 +0000
@@ -65,6 +65,9 @@
 
 #define YAHOO_SMS_CARRIER_URL "http://lookup.msg.vip.mud.yahoo.com"
 
+#define YAHOO_USERINFO_URL "http://address.yahoo.com/yab/us?v=XM&sync=1&tags=short&useutf8=1&noclear=1&legenc=codepage-1252"
+#define YAHOOJP_USERINFO_URL "http://address.yahoo.co.jp/yab/jp?v=XM&sync=1&tags=short&useutf8=1&noclear=1&legenc=codepage-1252"
+
 #define YAHOO_PICURL_SETTING "picture_url"
 #define YAHOO_PICCKSUM_SETTING "picture_checksum"
 #define YAHOO_PICEXPIRE_SETTING "picture_expire"
@@ -147,6 +150,23 @@
 
 struct _YchtConn;
 
+typedef struct _YahooPersonalDetails {
+	char *id;
+
+	struct {
+		char *first;
+		char *last;
+		char *middle;
+		char *nick;
+	} names;
+
+	struct {
+		char *work;
+		char *home;
+		char *mobile;
+	} phone;
+} YahooPersonalDetails;
+
 struct yahoo_data {
 	PurpleConnection *gc;
 	int fd;
@@ -157,6 +177,7 @@
 	GHashTable *friends;
 
 	char **profiles;  /* Multiple profiles can be associated with an account */
+	YahooPersonalDetails ypd;
 
 	/**
 	 * This is used to keep track of the IMVironment chosen
--- a/libpurple/protocols/yahoo/yahoo_aliases.c	Fri Jul 10 06:37:13 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_aliases.c	Fri Jul 10 15:18:09 2009 +0000
@@ -29,6 +29,7 @@
 #include "blist.h"
 #include "debug.h"
 #include "util.h"
+#include "request.h"
 #include "version.h"
 #include "libymsg.h"
 #include "yahoo_aliases.h"
@@ -52,6 +53,17 @@
 	gchar *who;
 };
 
+void yahoo_personal_details_reset(YahooPersonalDetails *ypd)
+{
+	g_free(ypd->id);
+	g_free(ypd->names.first);
+	g_free(ypd->names.last);
+	g_free(ypd->names.middle);
+	g_free(ypd->names.nick);
+	g_free(ypd->phone.work);
+	g_free(ypd->phone.home);
+	g_free(ypd->phone.mobile);
+}
 
 /**************************************************************************
  * Alias Fetch Functions
@@ -60,8 +72,7 @@
 static void
 yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
 {
-	struct callback_data *cb = user_data;
-	PurpleConnection *gc = cb->gc;
+	PurpleConnection *gc = user_data;
 	struct yahoo_data *yd = gc->proto_data;
 
 	yd->url_datas = g_slist_remove(yd->url_datas, url_data);
@@ -71,19 +82,19 @@
 						  error_message ? " Error:" : "", error_message ? error_message : "");
 	} else {
 		gchar *full_name, *nick_name;
-		const char *yid, *id, *fn, *ln, *nn, *alias;
+		const char *yid, *id, *fn, *ln, *nn, *alias, *mn;
+		const char *hp, *wp, *mo;
 		YahooFriend *f;
 		PurpleBuddy *b;
 		xmlnode *item, *contacts;
+		PurpleAccount *account;
 
+		account = purple_connection_get_account(gc);
 		/* Put our web response into a xmlnode for easy management */
 		contacts = xmlnode_from_str(url_text, -1);
 
 		if (contacts == NULL) {
 			purple_debug_error("yahoo", "Badly formed Alias XML\n");
-			g_free(cb->who);
-			g_free(cb->id);
-			g_free(cb);
 			return;
 		}
 		purple_debug_info("yahoo", "Fetched %" G_GSIZE_FORMAT
@@ -97,8 +108,13 @@
 				fn = xmlnode_get_attrib(item, "fn");
 				ln = xmlnode_get_attrib(item, "ln");
 				nn = xmlnode_get_attrib(item, "nn");
+				mn = xmlnode_get_attrib(item, "mn");
 				id = xmlnode_get_attrib(item, "id");
 
+				hp = xmlnode_get_attrib(item, "hp");
+				wp = xmlnode_get_attrib(item, "wp");
+				mo = xmlnode_get_attrib(item, "mo");
+
 				full_name = nick_name = NULL;
 				alias = NULL;
 
@@ -115,8 +131,8 @@
 					alias = full_name;  /* If no Yahoo nickname, we can use the full_name created above */
 
 				/*  Find the local buddy that matches */
-				f = yahoo_friend_find(cb->gc, yid);
-				b = purple_find_buddy(cb->gc->account, yid);
+				f = yahoo_friend_find(gc, yid);
+				b = purple_find_buddy(account, yid);
 
 				/*  If we don't find a matching buddy, ignore the alias !!  */
 				if (f != NULL && b != NULL) {
@@ -125,13 +141,30 @@
 
 					/* Finally, if we received an alias, we better update the buddy list */
 					if (alias != NULL) {
-						serv_got_alias(cb->gc, yid, alias);
+						serv_got_alias(gc, yid, alias);
 						purple_debug_info("yahoo", "Fetched alias '%s' (%s)\n", alias, id);
 					} else if (buddy_alias != NULL && strcmp(buddy_alias, "") != 0) {
 					/* Or if we have an alias that Yahoo doesn't, send it up */
-						yahoo_update_alias(cb->gc, yid, buddy_alias);
+						yahoo_update_alias(gc, yid, buddy_alias);
 						purple_debug_info("yahoo", "Sent updated alias '%s'\n", buddy_alias);
 					}
+				} else {
+					/* May be the alias is for the account? */
+					const char *yidn = purple_normalize(account, yid);
+					if (purple_strequal(yidn, purple_connection_get_display_name(gc))) {
+						yahoo_personal_details_reset(&yd->ypd);
+
+						yd->ypd.id = g_strdup(id);
+
+						yd->ypd.names.first = g_strdup(fn);
+						yd->ypd.names.middle = g_strdup(mn);
+						yd->ypd.names.last = g_strdup(ln);
+						yd->ypd.names.nick = g_strdup(nn);
+
+						yd->ypd.phone.work = g_strdup(wp);
+						yd->ypd.phone.home = g_strdup(hp);
+						yd->ypd.phone.mobile = g_strdup(mo);
+					}
 				}
 
 				g_free(full_name);
@@ -140,17 +173,12 @@
 		}
 		xmlnode_free(contacts);
 	}
-
-	g_free(cb->who);
-	g_free(cb->id);
-	g_free(cb);
 }
 
 void
 yahoo_fetch_aliases(PurpleConnection *gc)
 {
 	struct yahoo_data *yd = gc->proto_data;
-	struct callback_data *cb;
 	const char *url;
 	gchar *request, *webpage, *webaddress;
 	PurpleUtilFetchUrlData *url_data;
@@ -158,10 +186,6 @@
 	/* use whole URL if using HTTP Proxy */
 	gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
 
-	/* Using callback_data so I have access to gc in the callback function */
-	cb = g_new0(struct callback_data, 1);
-	cb->gc = gc;
-
 	/*  Build all the info to make the web request */
 	url = yd->jp ? YAHOOJP_ALIAS_FETCH_URL : YAHOO_ALIAS_FETCH_URL;
 	purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL);
@@ -177,7 +201,7 @@
 	/* We have a URL and some header information, let's connect and get some aliases  */
 	url_data = purple_util_fetch_url_request_len_with_account(purple_connection_get_account(gc),
 				url, use_whole_url, NULL, TRUE, request, FALSE, -1,
-				yahoo_fetch_aliases_cb, cb);
+				yahoo_fetch_aliases_cb, gc);
 	if (url_data != NULL)
 		yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
 
@@ -359,3 +383,104 @@
 	g_free(request);
 }
 
+
+/**************************************************************************
+ * User Info Update Functions
+ **************************************************************************/
+
+static void
+yahoo_set_userinfo_cb(PurpleConnection *gc, PurpleRequestFields *fields)
+{
+	xmlnode *node = xmlnode_new("ab");
+	xmlnode *ct = xmlnode_new_child(node, "ct");
+	struct yahoo_data *yd = purple_connection_get_protocol_data(gc);
+	PurpleAccount *account;
+	PurpleUtilFetchUrlData *url_data;
+	char *webaddress, *webpage;
+	char *request, *content;
+	int len;
+	int i;
+	char * yfields[] = { "fn", "ln", "nn", "mn", "hp", "wp", "mo", NULL };
+
+	account = purple_connection_get_account(gc);
+
+	xmlnode_set_attrib(node, "k", purple_connection_get_display_name(gc));
+	xmlnode_set_attrib(node, "cc", "1");		/* XXX: ? */
+
+	xmlnode_set_attrib(ct, "e", "1");
+	xmlnode_set_attrib(ct, "yi", purple_connection_get_display_name(gc));
+	xmlnode_set_attrib(ct, "id", yd->ypd.id);
+	xmlnode_set_attrib(ct, "pr", "0");
+
+	for (i = 0; yfields[i]; i++) {
+		const char *v = purple_request_fields_get_string(fields, yfields[i]);
+		xmlnode_set_attrib(ct, yfields[i], v ? v : "");
+	}
+
+	content = xmlnode_to_formatted_str(node, &len);
+	purple_url_parse(yd->jp ? YAHOOJP_USERINFO_URL : YAHOO_USERINFO_URL, &webaddress, NULL, &webpage, NULL, NULL);
+
+	request = g_strdup_printf("POST %s HTTP/1.1\r\n"
+				  "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
+				  "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s;\r\n"
+				  "Host: %s\r\n"
+				  "Content-Length: %" G_GSIZE_FORMAT "\r\n"
+				  "Cache-Control: no-cache\r\n\r\n"
+				  "%s\r\n\r\n",
+				  webpage,
+				  yd->cookie_t, yd->cookie_y,
+				  webaddress,
+				  len + 4,
+				  content);
+
+	url_data = purple_util_fetch_url_request_len_with_account(account, webaddress, FALSE,
+			YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
+			yahoo_fetch_aliases_cb, gc);
+	if (url_data != NULL)
+		yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
+
+	g_free(webaddress);
+	g_free(webpage);
+	g_free(content);
+	g_free(request);
+	xmlnode_free(node);
+}
+
+void yahoo_set_userinfo(PurpleConnection *gc)
+{
+	PurpleRequestFields *fields;
+	PurpleRequestFieldGroup *group;
+	PurpleRequestField *field;
+	struct yahoo_data *yd = purple_connection_get_protocol_data(gc);
+	int i;
+	struct {
+		char *id;
+		char *text;
+		char *value;
+	} yfields[] = {
+		{"fn", N_("First Name"), yd->ypd.names.first},
+		{"ln", N_("Last Name"), yd->ypd.names.last},
+		{"nn", N_("Nickname"), yd->ypd.names.nick},
+		{"mn", N_("Middle Name"), yd->ypd.names.middle},
+		{"hp", N_("Home Phone Number"), yd->ypd.phone.home},
+		{"wp", N_("Work Phone Number"), yd->ypd.phone.work},
+		{"mo", N_("Mobile Phone Number"), yd->ypd.phone.mobile},
+		{NULL, NULL, NULL}
+	};
+
+	fields = purple_request_fields_new();
+	group = purple_request_field_group_new(NULL);
+	purple_request_fields_add_group(fields, group);
+
+	for (i = 0; yfields[i].id; i++) {
+		field = purple_request_field_string_new(yfields[i].id, _(yfields[i].text),
+				yfields[i].value, FALSE);
+		purple_request_field_group_add_field(group, field);
+	}
+
+	purple_request_fields(gc, NULL, _("Set User Info"), NULL, fields,
+			_("OK"), G_CALLBACK(yahoo_set_userinfo_cb),
+			_("Cancel"), NULL,
+			purple_connection_get_account(gc), NULL, NULL, gc);
+}
+
--- a/libpurple/protocols/yahoo/yahoo_aliases.h	Fri Jul 10 06:37:13 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_aliases.h	Fri Jul 10 15:18:09 2009 +0000
@@ -35,4 +35,6 @@
 
 void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias);
 void yahoo_fetch_aliases(PurpleConnection *gc);
+void yahoo_set_userinfo(PurpleConnection *gc);
+void yahoo_personal_details_reset(YahooPersonalDetails *ypd);
 
--- a/libpurple/protocols/yahoo/yahoo_friend.h	Fri Jul 10 06:37:13 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_friend.h	Fri Jul 10 15:18:09 2009 +0000
@@ -56,7 +56,7 @@
 	YahooPresenceVisibility presence;
 	int protocol; /* 1=LCS, 2=MSN*/
 	long int version_id;
-	gchar *alias_id;
+	gchar *alias_id;		/* XXX: stick in a YahooPersonalDetails instead? */
 	YahooP2PStatus p2p_status;
 	gboolean p2p_packet_sent;	/* 0:not sent, 1=sent */
 	gint session_id;	/* session id of friend */
--- a/libpurple/protocols/yahoo/yahoo_packet.c	Fri Jul 10 06:37:13 2009 +0000
+++ b/libpurple/protocols/yahoo/yahoo_packet.c	Fri Jul 10 15:18:09 2009 +0000
@@ -187,7 +187,7 @@
 			pos = x;
 			pkt->hash = g_slist_prepend(pkt->hash, pair);
 
-			if (purple_debug_is_verbose()) {
+			if (purple_debug_is_verbose() || g_getenv("PURPLE_YAHOO_DEBUG")) {
 				char *esc;
 				esc = g_strescape(pair->value, NULL);
 				purple_debug_misc("yahoo", "Key: %d  \tValue: %s\n", pair->key, esc);