# HG changeset patch # User Sadrul Habib Chowdhury # Date 1247239089 0 # Node ID 07d09a987b86a62b2a24eb164e4e049ccb3dda36 # Parent 1b580473e7533a9aa4f31c7a084581fe3d1ee9da 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?) diff -r 1b580473e753 -r 07d09a987b86 libpurple/protocols/yahoo/libymsg.c --- 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); diff -r 1b580473e753 -r 07d09a987b86 libpurple/protocols/yahoo/libymsg.h --- 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 diff -r 1b580473e753 -r 07d09a987b86 libpurple/protocols/yahoo/yahoo_aliases.c --- 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); +} + diff -r 1b580473e753 -r 07d09a987b86 libpurple/protocols/yahoo/yahoo_aliases.h --- 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); diff -r 1b580473e753 -r 07d09a987b86 libpurple/protocols/yahoo/yahoo_friend.h --- 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 */ diff -r 1b580473e753 -r 07d09a987b86 libpurple/protocols/yahoo/yahoo_packet.c --- 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);