comparison libpurple/protocols/yahoo/yahoo_aliases.c @ 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 ef5f0cde8d74
children 7980a2bbad35
comparison
equal deleted inserted replaced
27454:1b580473e753 27455:07d09a987b86
27 #include "account.h" 27 #include "account.h"
28 #include "accountopt.h" 28 #include "accountopt.h"
29 #include "blist.h" 29 #include "blist.h"
30 #include "debug.h" 30 #include "debug.h"
31 #include "util.h" 31 #include "util.h"
32 #include "request.h"
32 #include "version.h" 33 #include "version.h"
33 #include "libymsg.h" 34 #include "libymsg.h"
34 #include "yahoo_aliases.h" 35 #include "yahoo_aliases.h"
35 #include "yahoo_friend.h" 36 #include "yahoo_friend.h"
36 #include "yahoo_packet.h" 37 #include "yahoo_packet.h"
50 PurpleConnection *gc; 51 PurpleConnection *gc;
51 gchar *id; 52 gchar *id;
52 gchar *who; 53 gchar *who;
53 }; 54 };
54 55
56 void yahoo_personal_details_reset(YahooPersonalDetails *ypd)
57 {
58 g_free(ypd->id);
59 g_free(ypd->names.first);
60 g_free(ypd->names.last);
61 g_free(ypd->names.middle);
62 g_free(ypd->names.nick);
63 g_free(ypd->phone.work);
64 g_free(ypd->phone.home);
65 g_free(ypd->phone.mobile);
66 }
55 67
56 /************************************************************************** 68 /**************************************************************************
57 * Alias Fetch Functions 69 * Alias Fetch Functions
58 **************************************************************************/ 70 **************************************************************************/
59 71
60 static void 72 static void
61 yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message) 73 yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message)
62 { 74 {
63 struct callback_data *cb = user_data; 75 PurpleConnection *gc = user_data;
64 PurpleConnection *gc = cb->gc;
65 struct yahoo_data *yd = gc->proto_data; 76 struct yahoo_data *yd = gc->proto_data;
66 77
67 yd->url_datas = g_slist_remove(yd->url_datas, url_data); 78 yd->url_datas = g_slist_remove(yd->url_datas, url_data);
68 79
69 if (len == 0) { 80 if (len == 0) {
70 purple_debug_info("yahoo", "No Aliases to process.%s%s\n", 81 purple_debug_info("yahoo", "No Aliases to process.%s%s\n",
71 error_message ? " Error:" : "", error_message ? error_message : ""); 82 error_message ? " Error:" : "", error_message ? error_message : "");
72 } else { 83 } else {
73 gchar *full_name, *nick_name; 84 gchar *full_name, *nick_name;
74 const char *yid, *id, *fn, *ln, *nn, *alias; 85 const char *yid, *id, *fn, *ln, *nn, *alias, *mn;
86 const char *hp, *wp, *mo;
75 YahooFriend *f; 87 YahooFriend *f;
76 PurpleBuddy *b; 88 PurpleBuddy *b;
77 xmlnode *item, *contacts; 89 xmlnode *item, *contacts;
78 90 PurpleAccount *account;
91
92 account = purple_connection_get_account(gc);
79 /* Put our web response into a xmlnode for easy management */ 93 /* Put our web response into a xmlnode for easy management */
80 contacts = xmlnode_from_str(url_text, -1); 94 contacts = xmlnode_from_str(url_text, -1);
81 95
82 if (contacts == NULL) { 96 if (contacts == NULL) {
83 purple_debug_error("yahoo", "Badly formed Alias XML\n"); 97 purple_debug_error("yahoo", "Badly formed Alias XML\n");
84 g_free(cb->who);
85 g_free(cb->id);
86 g_free(cb);
87 return; 98 return;
88 } 99 }
89 purple_debug_info("yahoo", "Fetched %" G_GSIZE_FORMAT 100 purple_debug_info("yahoo", "Fetched %" G_GSIZE_FORMAT
90 " bytes of alias data\n", len); 101 " bytes of alias data\n", len);
91 102
95 if ((yid = xmlnode_get_attrib(item, "yi"))) { 106 if ((yid = xmlnode_get_attrib(item, "yi"))) {
96 /* Grab all the bits of information we can */ 107 /* Grab all the bits of information we can */
97 fn = xmlnode_get_attrib(item, "fn"); 108 fn = xmlnode_get_attrib(item, "fn");
98 ln = xmlnode_get_attrib(item, "ln"); 109 ln = xmlnode_get_attrib(item, "ln");
99 nn = xmlnode_get_attrib(item, "nn"); 110 nn = xmlnode_get_attrib(item, "nn");
111 mn = xmlnode_get_attrib(item, "mn");
100 id = xmlnode_get_attrib(item, "id"); 112 id = xmlnode_get_attrib(item, "id");
113
114 hp = xmlnode_get_attrib(item, "hp");
115 wp = xmlnode_get_attrib(item, "wp");
116 mo = xmlnode_get_attrib(item, "mo");
101 117
102 full_name = nick_name = NULL; 118 full_name = nick_name = NULL;
103 alias = NULL; 119 alias = NULL;
104 120
105 /* Yahoo stores first and last names separately, lets put them together into a full name */ 121 /* Yahoo stores first and last names separately, lets put them together into a full name */
113 alias = nick_name; /* If we have a nickname from Yahoo, let's use it */ 129 alias = nick_name; /* If we have a nickname from Yahoo, let's use it */
114 else if (strlen(full_name) != 0) 130 else if (strlen(full_name) != 0)
115 alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */ 131 alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */
116 132
117 /* Find the local buddy that matches */ 133 /* Find the local buddy that matches */
118 f = yahoo_friend_find(cb->gc, yid); 134 f = yahoo_friend_find(gc, yid);
119 b = purple_find_buddy(cb->gc->account, yid); 135 b = purple_find_buddy(account, yid);
120 136
121 /* If we don't find a matching buddy, ignore the alias !! */ 137 /* If we don't find a matching buddy, ignore the alias !! */
122 if (f != NULL && b != NULL) { 138 if (f != NULL && b != NULL) {
123 const char *buddy_alias = purple_buddy_get_alias(b); 139 const char *buddy_alias = purple_buddy_get_alias(b);
124 yahoo_friend_set_alias_id(f, id); 140 yahoo_friend_set_alias_id(f, id);
125 141
126 /* Finally, if we received an alias, we better update the buddy list */ 142 /* Finally, if we received an alias, we better update the buddy list */
127 if (alias != NULL) { 143 if (alias != NULL) {
128 serv_got_alias(cb->gc, yid, alias); 144 serv_got_alias(gc, yid, alias);
129 purple_debug_info("yahoo", "Fetched alias '%s' (%s)\n", alias, id); 145 purple_debug_info("yahoo", "Fetched alias '%s' (%s)\n", alias, id);
130 } else if (buddy_alias != NULL && strcmp(buddy_alias, "") != 0) { 146 } else if (buddy_alias != NULL && strcmp(buddy_alias, "") != 0) {
131 /* Or if we have an alias that Yahoo doesn't, send it up */ 147 /* Or if we have an alias that Yahoo doesn't, send it up */
132 yahoo_update_alias(cb->gc, yid, buddy_alias); 148 yahoo_update_alias(gc, yid, buddy_alias);
133 purple_debug_info("yahoo", "Sent updated alias '%s'\n", buddy_alias); 149 purple_debug_info("yahoo", "Sent updated alias '%s'\n", buddy_alias);
150 }
151 } else {
152 /* May be the alias is for the account? */
153 const char *yidn = purple_normalize(account, yid);
154 if (purple_strequal(yidn, purple_connection_get_display_name(gc))) {
155 yahoo_personal_details_reset(&yd->ypd);
156
157 yd->ypd.id = g_strdup(id);
158
159 yd->ypd.names.first = g_strdup(fn);
160 yd->ypd.names.middle = g_strdup(mn);
161 yd->ypd.names.last = g_strdup(ln);
162 yd->ypd.names.nick = g_strdup(nn);
163
164 yd->ypd.phone.work = g_strdup(wp);
165 yd->ypd.phone.home = g_strdup(hp);
166 yd->ypd.phone.mobile = g_strdup(mo);
134 } 167 }
135 } 168 }
136 169
137 g_free(full_name); 170 g_free(full_name);
138 g_free(nick_name); 171 g_free(nick_name);
139 } 172 }
140 } 173 }
141 xmlnode_free(contacts); 174 xmlnode_free(contacts);
142 } 175 }
143
144 g_free(cb->who);
145 g_free(cb->id);
146 g_free(cb);
147 } 176 }
148 177
149 void 178 void
150 yahoo_fetch_aliases(PurpleConnection *gc) 179 yahoo_fetch_aliases(PurpleConnection *gc)
151 { 180 {
152 struct yahoo_data *yd = gc->proto_data; 181 struct yahoo_data *yd = gc->proto_data;
153 struct callback_data *cb;
154 const char *url; 182 const char *url;
155 gchar *request, *webpage, *webaddress; 183 gchar *request, *webpage, *webaddress;
156 PurpleUtilFetchUrlData *url_data; 184 PurpleUtilFetchUrlData *url_data;
157 185
158 /* use whole URL if using HTTP Proxy */ 186 /* use whole URL if using HTTP Proxy */
159 gboolean use_whole_url = yahoo_account_use_http_proxy(gc); 187 gboolean use_whole_url = yahoo_account_use_http_proxy(gc);
160
161 /* Using callback_data so I have access to gc in the callback function */
162 cb = g_new0(struct callback_data, 1);
163 cb->gc = gc;
164 188
165 /* Build all the info to make the web request */ 189 /* Build all the info to make the web request */
166 url = yd->jp ? YAHOOJP_ALIAS_FETCH_URL : YAHOO_ALIAS_FETCH_URL; 190 url = yd->jp ? YAHOOJP_ALIAS_FETCH_URL : YAHOO_ALIAS_FETCH_URL;
167 purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL); 191 purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL);
168 request = g_strdup_printf("GET %s%s/%s HTTP/1.1\r\n" 192 request = g_strdup_printf("GET %s%s/%s HTTP/1.1\r\n"
175 webaddress); 199 webaddress);
176 200
177 /* We have a URL and some header information, let's connect and get some aliases */ 201 /* We have a URL and some header information, let's connect and get some aliases */
178 url_data = purple_util_fetch_url_request_len_with_account(purple_connection_get_account(gc), 202 url_data = purple_util_fetch_url_request_len_with_account(purple_connection_get_account(gc),
179 url, use_whole_url, NULL, TRUE, request, FALSE, -1, 203 url, use_whole_url, NULL, TRUE, request, FALSE, -1,
180 yahoo_fetch_aliases_cb, cb); 204 yahoo_fetch_aliases_cb, gc);
181 if (url_data != NULL) 205 if (url_data != NULL)
182 yd->url_datas = g_slist_prepend(yd->url_datas, url_data); 206 yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
183 207
184 g_free(webaddress); 208 g_free(webaddress);
185 g_free(webpage); 209 g_free(webpage);
357 g_free(webaddress); 381 g_free(webaddress);
358 g_free(content); 382 g_free(content);
359 g_free(request); 383 g_free(request);
360 } 384 }
361 385
386
387 /**************************************************************************
388 * User Info Update Functions
389 **************************************************************************/
390
391 static void
392 yahoo_set_userinfo_cb(PurpleConnection *gc, PurpleRequestFields *fields)
393 {
394 xmlnode *node = xmlnode_new("ab");
395 xmlnode *ct = xmlnode_new_child(node, "ct");
396 struct yahoo_data *yd = purple_connection_get_protocol_data(gc);
397 PurpleAccount *account;
398 PurpleUtilFetchUrlData *url_data;
399 char *webaddress, *webpage;
400 char *request, *content;
401 int len;
402 int i;
403 char * yfields[] = { "fn", "ln", "nn", "mn", "hp", "wp", "mo", NULL };
404
405 account = purple_connection_get_account(gc);
406
407 xmlnode_set_attrib(node, "k", purple_connection_get_display_name(gc));
408 xmlnode_set_attrib(node, "cc", "1"); /* XXX: ? */
409
410 xmlnode_set_attrib(ct, "e", "1");
411 xmlnode_set_attrib(ct, "yi", purple_connection_get_display_name(gc));
412 xmlnode_set_attrib(ct, "id", yd->ypd.id);
413 xmlnode_set_attrib(ct, "pr", "0");
414
415 for (i = 0; yfields[i]; i++) {
416 const char *v = purple_request_fields_get_string(fields, yfields[i]);
417 xmlnode_set_attrib(ct, yfields[i], v ? v : "");
418 }
419
420 content = xmlnode_to_formatted_str(node, &len);
421 purple_url_parse(yd->jp ? YAHOOJP_USERINFO_URL : YAHOO_USERINFO_URL, &webaddress, NULL, &webpage, NULL, NULL);
422
423 request = g_strdup_printf("POST %s HTTP/1.1\r\n"
424 "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n"
425 "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s;\r\n"
426 "Host: %s\r\n"
427 "Content-Length: %" G_GSIZE_FORMAT "\r\n"
428 "Cache-Control: no-cache\r\n\r\n"
429 "%s\r\n\r\n",
430 webpage,
431 yd->cookie_t, yd->cookie_y,
432 webaddress,
433 len + 4,
434 content);
435
436 url_data = purple_util_fetch_url_request_len_with_account(account, webaddress, FALSE,
437 YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1,
438 yahoo_fetch_aliases_cb, gc);
439 if (url_data != NULL)
440 yd->url_datas = g_slist_prepend(yd->url_datas, url_data);
441
442 g_free(webaddress);
443 g_free(webpage);
444 g_free(content);
445 g_free(request);
446 xmlnode_free(node);
447 }
448
449 void yahoo_set_userinfo(PurpleConnection *gc)
450 {
451 PurpleRequestFields *fields;
452 PurpleRequestFieldGroup *group;
453 PurpleRequestField *field;
454 struct yahoo_data *yd = purple_connection_get_protocol_data(gc);
455 int i;
456 struct {
457 char *id;
458 char *text;
459 char *value;
460 } yfields[] = {
461 {"fn", N_("First Name"), yd->ypd.names.first},
462 {"ln", N_("Last Name"), yd->ypd.names.last},
463 {"nn", N_("Nickname"), yd->ypd.names.nick},
464 {"mn", N_("Middle Name"), yd->ypd.names.middle},
465 {"hp", N_("Home Phone Number"), yd->ypd.phone.home},
466 {"wp", N_("Work Phone Number"), yd->ypd.phone.work},
467 {"mo", N_("Mobile Phone Number"), yd->ypd.phone.mobile},
468 {NULL, NULL, NULL}
469 };
470
471 fields = purple_request_fields_new();
472 group = purple_request_field_group_new(NULL);
473 purple_request_fields_add_group(fields, group);
474
475 for (i = 0; yfields[i].id; i++) {
476 field = purple_request_field_string_new(yfields[i].id, _(yfields[i].text),
477 yfields[i].value, FALSE);
478 purple_request_field_group_add_field(group, field);
479 }
480
481 purple_request_fields(gc, NULL, _("Set User Info"), NULL, fields,
482 _("OK"), G_CALLBACK(yahoo_set_userinfo_cb),
483 _("Cancel"), NULL,
484 purple_connection_get_account(gc), NULL, NULL, gc);
485 }
486