Allow setting some personal information for an account.

Fri, 10 Jul 2009 15:18:09 +0000

author
Sadrul Habib Chowdhury <sadrul@pidgin.im>
date
Fri, 10 Jul 2009 15:18:09 +0000
changeset 27716
a3ed37ab91b8
parent 27713
9985f2f358c9
child 27717
7545a447a854

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?)

libpurple/protocols/yahoo/libymsg.c file | annotate | diff | comparison | revisions
libpurple/protocols/yahoo/libymsg.h file | annotate | diff | comparison | revisions
libpurple/protocols/yahoo/yahoo_aliases.c file | annotate | diff | comparison | revisions
libpurple/protocols/yahoo/yahoo_aliases.h file | annotate | diff | comparison | revisions
libpurple/protocols/yahoo/yahoo_friend.h file | annotate | diff | comparison | revisions
libpurple/protocols/yahoo/yahoo_packet.c file | annotate | diff | comparison | revisions
--- 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);

mercurial