pidgin: c79c76ef: Allow setting some personal information ...

sadrul at pidgin.im sadrul at pidgin.im
Fri Jul 10 15:30:28 EDT 2009


-----------------------------------------------------------------
Revision: c79c76ef54b9b6ee38720172c7cc655dcee22893
Ancestor: 3f9611885d2286d341ad36a8b0fe8386fc14277b
Author: sadrul at pidgin.im
Date: 2009-07-10T15:18:09
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/c79c76ef54b9b6ee38720172c7cc655dcee22893

Modified 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

ChangeLog: 

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

-------------- next part --------------
============================================================
--- libpurple/protocols/yahoo/libymsg.c	79130fd4a2810eb0eee56e0654185eae514f6721
+++ libpurple/protocols/yahoo/libymsg.c	e120879968c13e0dfce6ed7f791eea0dbc2a9168
@@ -3538,6 +3538,8 @@ void yahoo_close(PurpleConnection *gc) {
 	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,10 +4014,14 @@ static void yahoo_show_inbox(PurplePlugi
 				   "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)
 {
 	PurpleRequestFields *fields;
@@ -4061,6 +4067,10 @@ GList *yahoo_actions(PurplePlugin *plugi
 	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);
============================================================
--- libpurple/protocols/yahoo/libymsg.h	571540c0f32899c58e33bb64bf6bbc0ce1872f64
+++ libpurple/protocols/yahoo/libymsg.h	5c28842a3f1336b1a1bc231ec938676b3d4bbfb6
@@ -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;
 
 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 @@ struct yahoo_data {
 	GHashTable *friends;
 
 	char **profiles;  /* Multiple profiles can be associated with an account */
+	YahooPersonalDetails ypd;
 
 	/**
 	 * This is used to keep track of the IMVironment chosen
============================================================
--- libpurple/protocols/yahoo/yahoo_aliases.c	39c21248f1ea86e4b338a47c12ac0ed7eed706aa
+++ libpurple/protocols/yahoo/yahoo_aliases.c	aa7d97e66640eeca9ce551cbca7e45028a206de1
@@ -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 @@ struct callback_data {
 	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 @@ yahoo_fetch_aliases_cb(PurpleUtilFetchUr
 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 @@ yahoo_fetch_aliases_cb(PurpleUtilFetchUr
 						  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 @@ yahoo_fetch_aliases_cb(PurpleUtilFetchUr
 				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 @@ yahoo_fetch_aliases_cb(PurpleUtilFetchUr
 					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 @@ yahoo_fetch_aliases_cb(PurpleUtilFetchUr
 
 					/* 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 @@ yahoo_fetch_aliases_cb(PurpleUtilFetchUr
 		}
 		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 @@ yahoo_fetch_aliases(PurpleConnection *gc
 	/* 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 @@ yahoo_fetch_aliases(PurpleConnection *gc
 	/* 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 @@ yahoo_update_alias(PurpleConnection *gc,
 	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);
+}
+
============================================================
--- libpurple/protocols/yahoo/yahoo_aliases.h	ed2e8dd84f5290495b42540a4b095bdb997edf81
+++ libpurple/protocols/yahoo/yahoo_aliases.h	2f78edc635d0cdea40797e3ae6b2130cfded9f4e
@@ -35,4 +35,6 @@ void yahoo_fetch_aliases(PurpleConnectio
 
 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);
 
============================================================
--- libpurple/protocols/yahoo/yahoo_friend.h	414de59f0c7b17533819799f403e50d58aa3ce86
+++ libpurple/protocols/yahoo/yahoo_friend.h	ce5c0137b79e1a10fa8a4aad152cd1a6b21a47b3
@@ -56,7 +56,7 @@ typedef struct _YahooFriend {
 	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 */
============================================================
--- libpurple/protocols/yahoo/yahoo_packet.c	7a1c1a101321b2e10fd0e8a3e9d5a5b1b760c4dc
+++ libpurple/protocols/yahoo/yahoo_packet.c	73b3e054bfac9cf171335b28c7979d8c28e7f5f6
@@ -187,7 +187,7 @@ void yahoo_packet_read(struct yahoo_pack
 			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);


More information about the Commits mailing list