Mercurial > pidgin
comparison libpurple/protocols/oscar/userinfo.c @ 30361:9881f18b95b1
Got rid of family_icq.c -> oscar.c callbacks. Now it will be possible
to add an error handler for SNAC_FAMILY_ICQ right inside family_icq.c,
since all the necessary functions are there.
I made a pretty large refactoring along the way, moving the
authorization- and userinfo-related functions to separate files and
renaming some of them. Hopefully, this will make oscar.c less of mess.
author | ivan.komarov@soc.pidgin.im |
---|---|
date | Sun, 30 May 2010 13:53:45 +0000 |
parents | |
children | 879baaf87aa2 |
comparison
equal
deleted
inserted
replaced
30360:2f25002c9464 | 30361:9881f18b95b1 |
---|---|
1 /* | |
2 * Purple's oscar protocol plugin | |
3 * This file is the legal property of its developers. | |
4 * Please see the AUTHORS file distributed alongside this file. | |
5 * | |
6 * This library is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2 of the License, or (at your option) any later version. | |
10 * | |
11 * This library is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with this library; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
19 */ | |
20 | |
21 /* | |
22 * Displaying various information about buddies. | |
23 */ | |
24 | |
25 #include "oscar.h" | |
26 | |
27 static gchar * | |
28 oscar_caps_to_string(guint64 caps) | |
29 { | |
30 GString *str; | |
31 const gchar *tmp; | |
32 guint64 bit = 1; | |
33 | |
34 str = g_string_new(""); | |
35 | |
36 if (!caps) { | |
37 return NULL; | |
38 } else while (bit <= OSCAR_CAPABILITY_LAST) { | |
39 if (bit & caps) { | |
40 switch (bit) { | |
41 case OSCAR_CAPABILITY_BUDDYICON: | |
42 tmp = _("Buddy Icon"); | |
43 break; | |
44 case OSCAR_CAPABILITY_TALK: | |
45 tmp = _("Voice"); | |
46 break; | |
47 case OSCAR_CAPABILITY_DIRECTIM: | |
48 tmp = _("AIM Direct IM"); | |
49 break; | |
50 case OSCAR_CAPABILITY_CHAT: | |
51 tmp = _("Chat"); | |
52 break; | |
53 case OSCAR_CAPABILITY_GETFILE: | |
54 tmp = _("Get File"); | |
55 break; | |
56 case OSCAR_CAPABILITY_SENDFILE: | |
57 tmp = _("Send File"); | |
58 break; | |
59 case OSCAR_CAPABILITY_GAMES: | |
60 case OSCAR_CAPABILITY_GAMES2: | |
61 tmp = _("Games"); | |
62 break; | |
63 case OSCAR_CAPABILITY_XTRAZ: | |
64 case OSCAR_CAPABILITY_NEWCAPS: | |
65 tmp = _("ICQ Xtraz"); | |
66 break; | |
67 case OSCAR_CAPABILITY_ADDINS: | |
68 tmp = _("Add-Ins"); | |
69 break; | |
70 case OSCAR_CAPABILITY_SENDBUDDYLIST: | |
71 tmp = _("Send Buddy List"); | |
72 break; | |
73 case OSCAR_CAPABILITY_ICQ_DIRECT: | |
74 tmp = _("ICQ Direct Connect"); | |
75 break; | |
76 case OSCAR_CAPABILITY_APINFO: | |
77 tmp = _("AP User"); | |
78 break; | |
79 case OSCAR_CAPABILITY_ICQRTF: | |
80 tmp = _("ICQ RTF"); | |
81 break; | |
82 case OSCAR_CAPABILITY_EMPTY: | |
83 tmp = _("Nihilist"); | |
84 break; | |
85 case OSCAR_CAPABILITY_ICQSERVERRELAY: | |
86 tmp = _("ICQ Server Relay"); | |
87 break; | |
88 case OSCAR_CAPABILITY_UNICODEOLD: | |
89 tmp = _("Old ICQ UTF8"); | |
90 break; | |
91 case OSCAR_CAPABILITY_TRILLIANCRYPT: | |
92 tmp = _("Trillian Encryption"); | |
93 break; | |
94 case OSCAR_CAPABILITY_UNICODE: | |
95 tmp = _("ICQ UTF8"); | |
96 break; | |
97 case OSCAR_CAPABILITY_HIPTOP: | |
98 tmp = _("Hiptop"); | |
99 break; | |
100 case OSCAR_CAPABILITY_SECUREIM: | |
101 tmp = _("Security Enabled"); | |
102 break; | |
103 case OSCAR_CAPABILITY_VIDEO: | |
104 tmp = _("Video Chat"); | |
105 break; | |
106 /* Not actually sure about this one... WinAIM doesn't show anything */ | |
107 case OSCAR_CAPABILITY_ICHATAV: | |
108 tmp = _("iChat AV"); | |
109 break; | |
110 case OSCAR_CAPABILITY_LIVEVIDEO: | |
111 tmp = _("Live Video"); | |
112 break; | |
113 case OSCAR_CAPABILITY_CAMERA: | |
114 tmp = _("Camera"); | |
115 break; | |
116 case OSCAR_CAPABILITY_ICHAT_SCREENSHARE: | |
117 tmp = _("Screen Sharing"); | |
118 break; | |
119 default: | |
120 tmp = NULL; | |
121 break; | |
122 } | |
123 if (tmp) | |
124 g_string_append_printf(str, "%s%s", (*(str->str) == '\0' ? "" : ", "), tmp); | |
125 } | |
126 bit <<= 1; | |
127 } | |
128 | |
129 return g_string_free(str, FALSE); | |
130 } | |
131 | |
132 static void | |
133 oscar_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *name, const char *value) | |
134 { | |
135 if (value && value[0]) { | |
136 purple_notify_user_info_add_pair(user_info, name, value); | |
137 } | |
138 } | |
139 | |
140 static void | |
141 oscar_user_info_convert_and_add(PurpleAccount *account, OscarData *od, PurpleNotifyUserInfo *user_info, | |
142 const char *name, const char *value) | |
143 { | |
144 gchar *utf8; | |
145 | |
146 if (value && value[0] && (utf8 = oscar_utf8_try_convert(account, od, value))) { | |
147 purple_notify_user_info_add_pair(user_info, name, utf8); | |
148 g_free(utf8); | |
149 } | |
150 } | |
151 | |
152 /** | |
153 * @brief Append the status information to a user_info struct | |
154 * | |
155 * The returned information is HTML-ready, appropriately escaped, as all information in a user_info struct should be HTML. | |
156 * | |
157 * @param gc The PurpleConnection | |
158 * @param user_info A PurpleNotifyUserInfo object to which status information will be added | |
159 * @param b The PurpleBuddy whose status is desired. This or the aim_userinfo_t (or both) must be passed to oscar_user_info_append_status(). | |
160 * @param userinfo The aim_userinfo_t of the buddy whose status is desired. This or the PurpleBuddy (or both) must be passed to oscar_user_info_append_status(). | |
161 * @param strip_html_tags If strip_html_tags is TRUE, tags embedded in the status message will be stripped, returning a non-formatted string. The string will still be HTML escaped. | |
162 */ | |
163 void | |
164 oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo, gboolean strip_html_tags) | |
165 { | |
166 PurpleAccount *account = purple_connection_get_account(gc); | |
167 OscarData *od; | |
168 PurplePresence *presence = NULL; | |
169 PurpleStatus *status = NULL; | |
170 gchar *message = NULL, *itmsurl = NULL, *tmp; | |
171 gboolean is_away; | |
172 | |
173 od = purple_connection_get_protocol_data(gc); | |
174 | |
175 if (b == NULL && userinfo == NULL) | |
176 return; | |
177 | |
178 if (b == NULL) | |
179 b = purple_find_buddy(purple_connection_get_account(gc), userinfo->bn); | |
180 else | |
181 userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b)); | |
182 | |
183 if (b) { | |
184 presence = purple_buddy_get_presence(b); | |
185 status = purple_presence_get_active_status(presence); | |
186 } | |
187 | |
188 /* If we have both b and userinfo we favor userinfo, because if we're | |
189 viewing someone's profile then we want the HTML away message, and | |
190 the "message" attribute of the status contains only the plaintext | |
191 message. */ | |
192 if (userinfo) { | |
193 if ((userinfo->flags & AIM_FLAG_AWAY) | |
194 && userinfo->away_len > 0 | |
195 && userinfo->away != NULL | |
196 && userinfo->away_encoding != NULL) | |
197 { | |
198 /* Away message */ | |
199 tmp = oscar_encoding_extract(userinfo->away_encoding); | |
200 message = oscar_encoding_to_utf8(account, | |
201 tmp, userinfo->away, userinfo->away_len); | |
202 g_free(tmp); | |
203 } else { | |
204 /* | |
205 * Available message or non-HTML away message (because that's | |
206 * all we have right now. | |
207 */ | |
208 if ((userinfo->status != NULL) && userinfo->status[0] != '\0') { | |
209 message = oscar_encoding_to_utf8(account, | |
210 userinfo->status_encoding, userinfo->status, | |
211 userinfo->status_len); | |
212 } | |
213 #if defined (_WIN32) || defined (__APPLE__) | |
214 if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0')) | |
215 itmsurl = oscar_encoding_to_utf8(account, userinfo->itmsurl_encoding, | |
216 userinfo->itmsurl, userinfo->itmsurl_len); | |
217 #endif | |
218 } | |
219 } else { | |
220 message = g_strdup(purple_status_get_attr_string(status, "message")); | |
221 itmsurl = g_strdup(purple_status_get_attr_string(status, "itmsurl")); | |
222 } | |
223 | |
224 is_away = ((status && !purple_status_is_available(status)) || | |
225 (userinfo && (userinfo->flags & AIM_FLAG_AWAY))); | |
226 | |
227 if (strip_html_tags) { | |
228 /* Away messages are HTML, but available messages were originally plain text. | |
229 * We therefore need to strip away messages but not available messages if we're asked to remove HTML tags. | |
230 */ | |
231 /* | |
232 * It seems like the above comment no longer applies. All messages need | |
233 * to be escaped. | |
234 */ | |
235 if (message) { | |
236 gchar *tmp2; | |
237 tmp = purple_markup_strip_html(message); | |
238 g_free(message); | |
239 tmp2 = g_markup_escape_text(tmp, -1); | |
240 g_free(tmp); | |
241 message = tmp2; | |
242 } | |
243 | |
244 } else { | |
245 if (itmsurl) { | |
246 tmp = g_strdup_printf("<a href=\"%s\">%s</a>", | |
247 itmsurl, message); | |
248 g_free(message); | |
249 message = tmp; | |
250 } | |
251 } | |
252 g_free(itmsurl); | |
253 | |
254 if (message) { | |
255 tmp = oscar_util_format_string(message, purple_account_get_username(account)); | |
256 g_free(message); | |
257 message = tmp; | |
258 } | |
259 | |
260 if (b) { | |
261 if (purple_presence_is_online(presence)) { | |
262 if (oscar_util_valid_name_icq(purple_buddy_get_name(b)) || is_away || !message || !(*message)) { | |
263 /* Append the status name for online ICQ statuses, away AIM statuses, and for all buddies with no message. | |
264 * If the status name and the message are the same, only show one. */ | |
265 const char *status_name = purple_status_get_name(status); | |
266 if (status_name && message && !strcmp(status_name, message)) | |
267 status_name = NULL; | |
268 | |
269 tmp = g_strdup_printf("%s%s%s", | |
270 status_name ? status_name : "", | |
271 ((status_name && message) && *message) ? ": " : "", | |
272 (message && *message) ? message : ""); | |
273 g_free(message); | |
274 message = tmp; | |
275 } | |
276 | |
277 } else if (aim_ssi_waitingforauth(od->ssi.local, | |
278 aim_ssi_itemlist_findparentname(od->ssi.local, purple_buddy_get_name(b)), | |
279 purple_buddy_get_name(b))) | |
280 { | |
281 /* Note if an offline buddy is not authorized */ | |
282 tmp = g_strdup_printf("%s%s%s", | |
283 _("Not Authorized"), | |
284 (message && *message) ? ": " : "", | |
285 (message && *message) ? message : ""); | |
286 g_free(message); | |
287 message = tmp; | |
288 } else { | |
289 g_free(message); | |
290 message = g_strdup(_("Offline")); | |
291 } | |
292 } | |
293 | |
294 if (presence) { | |
295 const char *mood; | |
296 const char *description; | |
297 status = purple_presence_get_status(presence, "mood"); | |
298 mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME); | |
299 description = icq_get_custom_icon_description(mood); | |
300 if (description && *description) | |
301 purple_notify_user_info_add_pair(user_info, _("Mood"), _(description)); | |
302 } | |
303 | |
304 purple_notify_user_info_add_pair(user_info, _("Status"), message); | |
305 g_free(message); | |
306 } | |
307 | |
308 void | |
309 oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo) | |
310 { | |
311 OscarData *od; | |
312 PurpleAccount *account; | |
313 PurplePresence *presence = NULL; | |
314 PurpleStatus *status = NULL; | |
315 PurpleGroup *g = NULL; | |
316 struct buddyinfo *bi = NULL; | |
317 char *tmp; | |
318 const char *bname = NULL, *gname = NULL; | |
319 | |
320 od = purple_connection_get_protocol_data(gc); | |
321 account = purple_connection_get_account(gc); | |
322 | |
323 if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL))) | |
324 return; | |
325 | |
326 if (userinfo == NULL) | |
327 userinfo = aim_locate_finduserinfo(od, purple_buddy_get_name(b)); | |
328 | |
329 if (b == NULL) | |
330 b = purple_find_buddy(account, userinfo->bn); | |
331 | |
332 if (b != NULL) { | |
333 bname = purple_buddy_get_name(b); | |
334 g = purple_buddy_get_group(b); | |
335 gname = purple_group_get_name(g); | |
336 presence = purple_buddy_get_presence(b); | |
337 status = purple_presence_get_active_status(presence); | |
338 } | |
339 | |
340 if (userinfo != NULL) | |
341 bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->bn)); | |
342 | |
343 if ((bi != NULL) && (bi->ipaddr != 0)) { | |
344 tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", | |
345 (bi->ipaddr & 0xff000000) >> 24, | |
346 (bi->ipaddr & 0x00ff0000) >> 16, | |
347 (bi->ipaddr & 0x0000ff00) >> 8, | |
348 (bi->ipaddr & 0x000000ff)); | |
349 oscar_user_info_add_pair(user_info, _("IP Address"), tmp); | |
350 g_free(tmp); | |
351 } | |
352 | |
353 if ((userinfo != NULL) && (userinfo->warnlevel != 0)) { | |
354 tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5)); | |
355 oscar_user_info_add_pair(user_info, _("Warning Level"), tmp); | |
356 g_free(tmp); | |
357 } | |
358 | |
359 if ((b != NULL) && (bname != NULL) && (g != NULL) && (gname != NULL)) { | |
360 tmp = aim_ssi_getcomment(od->ssi.local, gname, bname); | |
361 if (tmp != NULL) { | |
362 char *tmp2 = g_markup_escape_text(tmp, strlen(tmp)); | |
363 g_free(tmp); | |
364 | |
365 oscar_user_info_convert_and_add(account, od, user_info, _("Buddy Comment"), tmp2); | |
366 g_free(tmp2); | |
367 } | |
368 } | |
369 } | |
370 | |
371 void | |
372 oscar_user_info_display_error(OscarData *od, guint16 error_reason, char *buddy) | |
373 { | |
374 PurpleNotifyUserInfo *user_info = purple_notify_user_info_new(); | |
375 gchar *buf = g_strdup_printf(_("User information not available: %s"), oscar_get_msgerr_reason(error_reason)); | |
376 purple_notify_user_info_add_pair(user_info, NULL, buf); | |
377 purple_notify_userinfo(od->gc, buddy, user_info, NULL, NULL); | |
378 purple_notify_user_info_destroy(user_info); | |
379 purple_conv_present_error(buddy, purple_connection_get_account(od->gc), buf); | |
380 g_free(buf); | |
381 } | |
382 | |
383 void | |
384 oscar_user_info_display_icq(OscarData *od, struct aim_icq_info *info) | |
385 { | |
386 PurpleConnection *gc = od->gc; | |
387 PurpleAccount *account = purple_connection_get_account(gc); | |
388 PurpleBuddy *buddy; | |
389 struct buddyinfo *bi; | |
390 gchar who[16]; | |
391 PurpleNotifyUserInfo *user_info; | |
392 gchar *utf8; | |
393 gchar *buf; | |
394 const gchar *alias; | |
395 | |
396 if (!info->uin) | |
397 return; | |
398 | |
399 user_info = purple_notify_user_info_new(); | |
400 | |
401 g_snprintf(who, sizeof(who), "%u", info->uin); | |
402 buddy = purple_find_buddy(account, who); | |
403 if (buddy != NULL) | |
404 bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, purple_buddy_get_name(buddy))); | |
405 else | |
406 bi = NULL; | |
407 | |
408 purple_notify_user_info_add_pair(user_info, _("UIN"), who); | |
409 oscar_user_info_convert_and_add(account, od, user_info, _("Nick"), info->nick); | |
410 if ((bi != NULL) && (bi->ipaddr != 0)) { | |
411 char *tstr = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", | |
412 (bi->ipaddr & 0xff000000) >> 24, | |
413 (bi->ipaddr & 0x00ff0000) >> 16, | |
414 (bi->ipaddr & 0x0000ff00) >> 8, | |
415 (bi->ipaddr & 0x000000ff)); | |
416 purple_notify_user_info_add_pair(user_info, _("IP Address"), tstr); | |
417 g_free(tstr); | |
418 } | |
419 oscar_user_info_convert_and_add(account, od, user_info, _("First Name"), info->first); | |
420 oscar_user_info_convert_and_add(account, od, user_info, _("Last Name"), info->last); | |
421 if (info->email && info->email[0] && (utf8 = oscar_utf8_try_convert(account, od, info->email))) { | |
422 buf = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", utf8, utf8); | |
423 purple_notify_user_info_add_pair(user_info, _("Email Address"), buf); | |
424 g_free(buf); | |
425 g_free(utf8); | |
426 } | |
427 if (info->numaddresses && info->email2) { | |
428 int i; | |
429 for (i = 0; i < info->numaddresses; i++) { | |
430 if (info->email2[i] && info->email2[i][0] && (utf8 = oscar_utf8_try_convert(account, od, info->email2[i]))) { | |
431 buf = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", utf8, utf8); | |
432 purple_notify_user_info_add_pair(user_info, _("Email Address"), buf); | |
433 g_free(buf); | |
434 g_free(utf8); | |
435 } | |
436 } | |
437 } | |
438 oscar_user_info_convert_and_add(account, od, user_info, _("Mobile Phone"), info->mobile); | |
439 | |
440 if (info->gender != 0) | |
441 purple_notify_user_info_add_pair(user_info, _("Gender"), (info->gender == 1 ? _("Female") : _("Male"))); | |
442 | |
443 if ((info->birthyear > 1900) && (info->birthmonth > 0) && (info->birthday > 0)) { | |
444 /* Initialize the struct properly or strftime() will crash | |
445 * under some conditions (e.g. Debian sarge w/ LANG=en_HK). */ | |
446 time_t t = time(NULL); | |
447 struct tm *tm = localtime(&t); | |
448 | |
449 tm->tm_mday = (int)info->birthday; | |
450 tm->tm_mon = (int)info->birthmonth - 1; | |
451 tm->tm_year = (int)info->birthyear - 1900; | |
452 | |
453 /* To be 100% sure that the fields are re-normalized. | |
454 * If you're sure strftime() ALWAYS does this EVERYWHERE, | |
455 * feel free to remove it. --rlaager */ | |
456 mktime(tm); | |
457 | |
458 oscar_user_info_convert_and_add(account, od, user_info, _("Birthday"), purple_date_format_short(tm)); | |
459 } | |
460 if ((info->age > 0) && (info->age < 255)) { | |
461 char age[5]; | |
462 snprintf(age, sizeof(age), "%hhd", info->age); | |
463 purple_notify_user_info_add_pair(user_info, _("Age"), age); | |
464 } | |
465 if (info->personalwebpage && info->personalwebpage[0] && (utf8 = oscar_utf8_try_convert(account, od, info->personalwebpage))) { | |
466 buf = g_strdup_printf("<a href=\"%s\">%s</a>", utf8, utf8); | |
467 purple_notify_user_info_add_pair(user_info, _("Personal Web Page"), buf); | |
468 g_free(buf); | |
469 g_free(utf8); | |
470 } | |
471 | |
472 if (buddy != NULL) | |
473 oscar_user_info_append_status(gc, user_info, buddy, /* aim_userinfo_t */ NULL, /* strip_html_tags */ FALSE); | |
474 | |
475 oscar_user_info_convert_and_add(account, od, user_info, _("Additional Information"), info->info); | |
476 purple_notify_user_info_add_section_break(user_info); | |
477 | |
478 if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) { | |
479 purple_notify_user_info_add_section_header(user_info, _("Home Address")); | |
480 | |
481 oscar_user_info_convert_and_add(account, od, user_info, _("Address"), info->homeaddr); | |
482 oscar_user_info_convert_and_add(account, od, user_info, _("City"), info->homecity); | |
483 oscar_user_info_convert_and_add(account, od, user_info, _("State"), info->homestate); | |
484 oscar_user_info_convert_and_add(account, od, user_info, _("Zip Code"), info->homezip); | |
485 } | |
486 if ((info->workaddr && info->workaddr[0]) || (info->workcity && info->workcity[0]) || (info->workstate && info->workstate[0]) || (info->workzip && info->workzip[0])) { | |
487 purple_notify_user_info_add_section_header(user_info, _("Work Address")); | |
488 | |
489 oscar_user_info_convert_and_add(account, od, user_info, _("Address"), info->workaddr); | |
490 oscar_user_info_convert_and_add(account, od, user_info, _("City"), info->workcity); | |
491 oscar_user_info_convert_and_add(account, od, user_info, _("State"), info->workstate); | |
492 oscar_user_info_convert_and_add(account, od, user_info, _("Zip Code"), info->workzip); | |
493 } | |
494 if ((info->workcompany && info->workcompany[0]) || (info->workdivision && info->workdivision[0]) || (info->workposition && info->workposition[0]) || (info->workwebpage && info->workwebpage[0])) { | |
495 purple_notify_user_info_add_section_header(user_info, _("Work Information")); | |
496 | |
497 oscar_user_info_convert_and_add(account, od, user_info, _("Company"), info->workcompany); | |
498 oscar_user_info_convert_and_add(account, od, user_info, _("Division"), info->workdivision); | |
499 oscar_user_info_convert_and_add(account, od, user_info, _("Position"), info->workposition); | |
500 | |
501 if (info->workwebpage && info->workwebpage[0] && (utf8 = oscar_utf8_try_convert(account, od, info->workwebpage))) { | |
502 char *webpage = g_strdup_printf("<a href=\"%s\">%s</a>", utf8, utf8); | |
503 purple_notify_user_info_add_pair(user_info, _("Web Page"), webpage); | |
504 g_free(webpage); | |
505 g_free(utf8); | |
506 } | |
507 } | |
508 | |
509 if (buddy != NULL) | |
510 alias = purple_buddy_get_alias(buddy); | |
511 else | |
512 alias = who; | |
513 purple_notify_userinfo(gc, who, user_info, NULL, NULL); | |
514 purple_notify_user_info_destroy(user_info); | |
515 } | |
516 | |
517 void | |
518 oscar_user_info_display_aim(OscarData *od, aim_userinfo_t *userinfo) | |
519 { | |
520 PurpleConnection *gc = od->gc; | |
521 PurpleAccount *account = purple_connection_get_account(gc); | |
522 PurpleNotifyUserInfo *user_info = purple_notify_user_info_new(); | |
523 gchar *tmp = NULL, *info_utf8 = NULL, *base_profile_url = NULL; | |
524 | |
525 oscar_user_info_append_status(gc, user_info, /* PurpleBuddy */ NULL, userinfo, /* strip_html_tags */ FALSE); | |
526 | |
527 if ((userinfo->present & AIM_USERINFO_PRESENT_IDLE) && userinfo->idletime != 0) { | |
528 tmp = purple_str_seconds_to_string(userinfo->idletime*60); | |
529 oscar_user_info_add_pair(user_info, _("Idle"), tmp); | |
530 g_free(tmp); | |
531 } | |
532 | |
533 oscar_user_info_append_extra_info(gc, user_info, NULL, userinfo); | |
534 | |
535 if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !oscar_util_valid_name_sms(userinfo->bn)) { | |
536 /* An SMS contact is always online; its Online Since value is not useful */ | |
537 time_t t = userinfo->onlinesince; | |
538 oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t))); | |
539 } | |
540 | |
541 if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) { | |
542 time_t t = userinfo->membersince; | |
543 oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t))); | |
544 } | |
545 | |
546 if (userinfo->capabilities != 0) { | |
547 tmp = oscar_caps_to_string(userinfo->capabilities); | |
548 oscar_user_info_add_pair(user_info, _("Capabilities"), tmp); | |
549 g_free(tmp); | |
550 } | |
551 | |
552 /* Info */ | |
553 if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) { | |
554 tmp = oscar_encoding_extract(userinfo->info_encoding); | |
555 info_utf8 = oscar_encoding_to_utf8(account, tmp, userinfo->info, | |
556 userinfo->info_len); | |
557 g_free(tmp); | |
558 if (info_utf8 != NULL) { | |
559 tmp = oscar_util_format_string(info_utf8, purple_account_get_username(account)); | |
560 purple_notify_user_info_add_section_break(user_info); | |
561 oscar_user_info_add_pair(user_info, _("Profile"), tmp); | |
562 g_free(tmp); | |
563 g_free(info_utf8); | |
564 } | |
565 } | |
566 | |
567 purple_notify_user_info_add_section_break(user_info); | |
568 base_profile_url = oscar_util_valid_name_icq(userinfo->bn) ? "http://www.icq.com/people" : "http://profiles.aim.com"; | |
569 tmp = g_strdup_printf("<a href=\"%s/%s\">%s</a>", | |
570 base_profile_url, purple_normalize(account, userinfo->bn), _("View web profile")); | |
571 purple_notify_user_info_add_pair(user_info, NULL, tmp); | |
572 g_free(tmp); | |
573 | |
574 purple_notify_userinfo(gc, userinfo->bn, user_info, NULL, NULL); | |
575 purple_notify_user_info_destroy(user_info); | |
576 } |