comparison libpurple/protocols/oscar/oscar.c @ 23232:56b39f1a15bf

Refactored and cleaned up the addition of status information to user info / tooltips in oscar prpl. * For consistency with other services, we call the away/available message 'Status' and put it first. * We prepend the status name if there is no message or it's an ICQ buddy. * We make use of the previously UTF8-decoded strings when possible rather than re-decoding with each access. * Properly escape available messages, which are plain text, for the Get Info window * Don't include 'online since' for SMS buddies, as they are always online
author Evan Schoenberg <evan.s@dreskin.net>
date Thu, 29 May 2008 11:39:42 +0000
parents 66a60f01e8a0
children 6c22faa7f919
comparison
equal deleted inserted replaced
23231:cb241bc04f9b 23232:56b39f1a15bf
770 purple_notify_user_info_add_pair(user_info, name, utf8); 770 purple_notify_user_info_add_pair(user_info, name, utf8);
771 g_free(utf8); 771 g_free(utf8);
772 } 772 }
773 } 773 }
774 774
775 static void oscar_string_append_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo) 775 static void oscar_user_info_append_status(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo)
776 {
777 PurpleAccount *account = purple_connection_get_account(gc);
778 OscarData *od;
779 PurplePresence *presence = NULL;
780 PurpleStatus *status = NULL;
781 gchar *message, *itmsurl, *tmp;
782
783 od = gc->proto_data;
784
785 if (userinfo == NULL)
786 userinfo = aim_locate_finduserinfo(od, b->name);
787
788 if ((user_info == NULL) || ((b == NULL) && (userinfo == NULL)))
789 return;
790
791 if (b == NULL)
792 b = purple_find_buddy(purple_connection_get_account(gc), userinfo->sn);
793
794 if (b) {
795 presence = purple_buddy_get_presence(b);
796 status = purple_presence_get_active_status(presence);
797
798 message = g_strdup(purple_status_get_attr_string(status, "message"));
799 itmsurl = g_strdup(purple_status_get_attr_string(status, "itmsurl"));
800
801 } else {
802 /* This is an OSCAR contact for whom we don't have a PurpleBuddy but do have information. */
803 if ((userinfo->flags & AIM_FLAG_AWAY)) {
804 /* Away message? */
805 if ((userinfo->flags & AIM_FLAG_AWAY) && (userinfo->away_len > 0) && (userinfo->away != NULL) && (userinfo->away_encoding != NULL)) {
806 gchar *away_utf8;
807
808 tmp = oscar_encoding_extract(userinfo->away_encoding);
809 away_utf8 = oscar_encoding_to_utf8(account, tmp, userinfo->away,
810 userinfo->away_len);
811 g_free(tmp);
812 if (away_utf8 != NULL) {
813 message = purple_str_sub_away_formatters(away_utf8, purple_account_get_username(account));
814 g_free(away_utf8);
815 }
816 }
817 } else {
818 /* Available message? */
819 if ((userinfo->status != NULL) && userinfo->status[0] != '\0') {
820 tmp = oscar_encoding_to_utf8(account, userinfo->status_encoding,
821 userinfo->status, userinfo->status_len);
822 /* Available messages are plain text */
823 message = g_markup_escape_text(tmp, -1);
824 g_free(tmp);
825 }
826 #if defined (_WIN32) || defined (__APPLE__)
827 if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0'))
828 itmsurl = oscar_encoding_to_utf8(account, userinfo->itmsurl_encoding,
829 userinfo->itmsurl, userinfo->itmsurl_len);
830 #endif
831 }
832 }
833
834 if (itmsurl) {
835 tmp = g_strdup_printf("<a href=\"%s\">%s</a>",
836 itmsurl, message);
837 g_free(itmsurl);
838 g_free(message);
839 message = tmp;
840 }
841
842 if (b) {
843 if (purple_presence_is_online(presence)) {
844 if (aim_snvalid_icq(b->name) || !message || !(*message)) {
845 /* Append the status name for online ICQ statuses and for all buddies with no message.
846 * If the status name and the message are the same, only show one. */
847 const char *status_name = purple_status_get_name(status);
848 if (status_name && message && !strcmp(status_name, message))
849 status_name = NULL;
850
851 tmp = g_strdup_printf("%s%s%s",
852 status_name,
853 ((status_name && message) && *message) ? ": " : "",
854 (message && *message) ? message : "");
855 g_free(message);
856 message = tmp;
857 }
858
859 } else {
860 if (aim_ssi_waitingforauth(od->ssi.local,
861 aim_ssi_itemlist_findparentname(od->ssi.local, b->name),
862 b->name)) {
863 /* Note if an offline buddy is not authorized */
864 tmp = g_strdup_printf("%s%s%s",
865 _("Not Authorized"),
866 (message && *message) ? ": " : "",
867 (message && *message) ? message : "");
868 g_free(message);
869 message = tmp;
870 } else {
871 g_free(message);
872 message = g_strdup(_("Offline"));
873 }
874 }
875
876 }
877
878 purple_notify_user_info_add_pair(user_info, _("Status"), message);
879 g_free(message);
880 }
881
882 static void oscar_user_info_append_extra_info(PurpleConnection *gc, PurpleNotifyUserInfo *user_info, PurpleBuddy *b, aim_userinfo_t *userinfo)
776 { 883 {
777 OscarData *od; 884 OscarData *od;
778 PurpleAccount *account; 885 PurpleAccount *account;
779 PurplePresence *presence = NULL; 886 PurplePresence *presence = NULL;
780 PurpleStatus *status = NULL; 887 PurpleStatus *status = NULL;
800 status = purple_presence_get_active_status(presence); 907 status = purple_presence_get_active_status(presence);
801 } 908 }
802 909
803 if (userinfo != NULL) 910 if (userinfo != NULL)
804 bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->sn)); 911 bi = g_hash_table_lookup(od->buddyinfo, purple_normalize(account, userinfo->sn));
805 912
806 if (b != NULL) {
807 if (purple_presence_is_online(presence)) {
808 if (aim_snvalid_icq(b->name)) {
809 PurpleStatus *status = purple_presence_get_active_status(presence);
810 oscar_user_info_add_pair(user_info, _("Status"), purple_status_get_name(status));
811 }
812 } else {
813 tmp = aim_ssi_itemlist_findparentname(od->ssi.local, b->name);
814 if (aim_ssi_waitingforauth(od->ssi.local, tmp, b->name))
815 oscar_user_info_add_pair(user_info, _("Status"), _("Not Authorized"));
816 else
817 oscar_user_info_add_pair(user_info, _("Status"), _("Offline"));
818 }
819 }
820
821 if ((bi != NULL) && (bi->ipaddr != 0)) { 913 if ((bi != NULL) && (bi->ipaddr != 0)) {
822 tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu", 914 tmp = g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
823 (bi->ipaddr & 0xff000000) >> 24, 915 (bi->ipaddr & 0xff000000) >> 24,
824 (bi->ipaddr & 0x00ff0000) >> 16, 916 (bi->ipaddr & 0x00ff0000) >> 16,
825 (bi->ipaddr & 0x0000ff00) >> 8, 917 (bi->ipaddr & 0x0000ff00) >> 8,
826 (bi->ipaddr & 0x000000ff)); 918 (bi->ipaddr & 0x000000ff));
827 oscar_user_info_add_pair(user_info, _("IP Address"), tmp); 919 oscar_user_info_add_pair(user_info, _("IP Address"), tmp);
828 g_free(tmp); 920 g_free(tmp);
829 } 921 }
830
831 922
832 if ((userinfo != NULL) && (userinfo->warnlevel != 0)) { 923 if ((userinfo != NULL) && (userinfo->warnlevel != 0)) {
833 tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5)); 924 tmp = g_strdup_printf("%d", (int)(userinfo->warnlevel/10.0 + .5));
834 oscar_user_info_add_pair(user_info, _("Warning Level"), tmp); 925 oscar_user_info_add_pair(user_info, _("Warning Level"), tmp);
835 g_free(tmp); 926 g_free(tmp);
2918 3009
2919 static int purple_parse_userinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { 3010 static int purple_parse_userinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
2920 PurpleConnection *gc = od->gc; 3011 PurpleConnection *gc = od->gc;
2921 PurpleAccount *account = purple_connection_get_account(gc); 3012 PurpleAccount *account = purple_connection_get_account(gc);
2922 PurpleNotifyUserInfo *user_info; 3013 PurpleNotifyUserInfo *user_info;
2923 gchar *tmp = NULL, *info_utf8 = NULL, *away_utf8 = NULL; 3014 gchar *tmp = NULL, *info_utf8 = NULL;
2924 va_list ap; 3015 va_list ap;
2925 aim_userinfo_t *userinfo; 3016 aim_userinfo_t *userinfo;
2926 3017
2927 va_start(ap, fr); 3018 va_start(ap, fr);
2928 userinfo = va_arg(ap, aim_userinfo_t *); 3019 userinfo = va_arg(ap, aim_userinfo_t *);
2929 va_end(ap); 3020 va_end(ap);
2930 3021
2931 user_info = purple_notify_user_info_new(); 3022 user_info = purple_notify_user_info_new();
2932 purple_notify_user_info_add_pair(user_info, _("Username"), userinfo->sn); 3023
2933 3024 oscar_user_info_append_status(gc, user_info, NULL, userinfo);
2934 if (userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) { 3025
3026 if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) {
3027 tmp = purple_str_seconds_to_string(userinfo->idletime*60);
3028 oscar_user_info_add_pair(user_info, _("Idle"), tmp);
3029 g_free(tmp);
3030 }
3031
3032 oscar_user_info_append_extra_info(gc, user_info, NULL, userinfo);
3033
3034 if ((userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE) && !aim_snvalid_sms(userinfo->sn)) {
3035 /* An SMS contact is always online; its Online Since valid is not useful */
2935 time_t t = userinfo->onlinesince; 3036 time_t t = userinfo->onlinesince;
2936 oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t))); 3037 oscar_user_info_add_pair(user_info, _("Online Since"), purple_date_format_full(localtime(&t)));
2937 } 3038 }
2938 3039
2939 if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) { 3040 if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE) {
2940 time_t t = userinfo->membersince; 3041 time_t t = userinfo->membersince;
2941 oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t))); 3042 oscar_user_info_add_pair(user_info, _("Member Since"), purple_date_format_full(localtime(&t)));
2942 } 3043 }
2943 3044
2944 if (userinfo->capabilities != 0) { 3045 if (userinfo->capabilities != 0) {
2945 tmp = oscar_caps_to_string(userinfo->capabilities); 3046 tmp = oscar_caps_to_string(userinfo->capabilities);
2946 oscar_user_info_add_pair(user_info, _("Capabilities"), tmp); 3047 oscar_user_info_add_pair(user_info, _("Capabilities"), tmp);
2947 g_free(tmp); 3048 g_free(tmp);
2948 }
2949
2950 if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) {
2951 tmp = purple_str_seconds_to_string(userinfo->idletime*60);
2952 oscar_user_info_add_pair(user_info, _("Idle"), tmp);
2953 g_free(tmp);
2954 }
2955
2956 oscar_string_append_info(gc, user_info, NULL, userinfo);
2957
2958 /* Available message */
2959 if ((userinfo->status != NULL) && !(userinfo->flags & AIM_FLAG_AWAY))
2960 {
2961 if (userinfo->status[0] != '\0')
2962 tmp = oscar_encoding_to_utf8(account, userinfo->status_encoding,
2963 userinfo->status, userinfo->status_len);
2964 #if defined (_WIN32) || defined (__APPLE__)
2965 if (userinfo->itmsurl && (userinfo->itmsurl[0] != '\0')) {
2966 gchar *itmsurl, *tmp2;
2967 itmsurl = oscar_encoding_to_utf8(account, userinfo->itmsurl_encoding,
2968 userinfo->itmsurl, userinfo->itmsurl_len);
2969 tmp2 = g_strdup_printf("<a href=\"%s\">%s</a>",
2970 itmsurl, tmp);
2971 g_free(tmp);
2972 tmp = tmp2;
2973 g_free(itmsurl);
2974 }
2975 #endif
2976 oscar_user_info_add_pair(user_info, _("Available Message"), tmp);
2977 g_free(tmp);
2978 }
2979
2980 /* Away message */
2981 if ((userinfo->flags & AIM_FLAG_AWAY) && (userinfo->away_len > 0) && (userinfo->away != NULL) && (userinfo->away_encoding != NULL)) {
2982 tmp = oscar_encoding_extract(userinfo->away_encoding);
2983 away_utf8 = oscar_encoding_to_utf8(account, tmp, userinfo->away,
2984 userinfo->away_len);
2985 g_free(tmp);
2986 if (away_utf8 != NULL) {
2987 tmp = purple_str_sub_away_formatters(away_utf8, purple_account_get_username(account));
2988 oscar_user_info_add_pair(user_info, _("Away Message"), tmp);
2989 g_free(tmp);
2990 g_free(away_utf8);
2991 }
2992 } 3049 }
2993 3050
2994 /* Info */ 3051 /* Info */
2995 if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) { 3052 if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) {
2996 tmp = oscar_encoding_extract(userinfo->info_encoding); 3053 tmp = oscar_encoding_extract(userinfo->info_encoding);
3685 static int purple_icqinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) 3742 static int purple_icqinfo(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...)
3686 { 3743 {
3687 PurpleConnection *gc; 3744 PurpleConnection *gc;
3688 PurpleAccount *account; 3745 PurpleAccount *account;
3689 PurpleBuddy *buddy; 3746 PurpleBuddy *buddy;
3690 PurplePresence *presence;
3691 PurpleStatus *status;
3692 struct buddyinfo *bi; 3747 struct buddyinfo *bi;
3693 gchar who[16]; 3748 gchar who[16];
3694 PurpleNotifyUserInfo *user_info; 3749 PurpleNotifyUserInfo *user_info;
3695 gchar *utf8; 3750 gchar *utf8;
3696 gchar *buf; 3751 gchar *buf;
3779 purple_notify_user_info_add_pair(user_info, _("Personal Web Page"), buf); 3834 purple_notify_user_info_add_pair(user_info, _("Personal Web Page"), buf);
3780 g_free(buf); 3835 g_free(buf);
3781 g_free(utf8); 3836 g_free(utf8);
3782 } 3837 }
3783 3838
3784 if (buddy != NULL) { 3839 if (buddy != NULL)
3785 const gchar *message; 3840 oscar_user_info_append_status(gc, user_info, buddy, NULL);
3786 gchar *utf8, *tmp;
3787
3788 presence = purple_buddy_get_presence(buddy);
3789 status = purple_presence_get_active_status(presence);
3790 message = purple_status_get_attr_string(status, "message");
3791
3792 utf8 = message && message[0] ? oscar_utf8_try_convert(account, message) : NULL;
3793 tmp = g_strdup_printf("%s%s%s",
3794 purple_status_get_name(status),
3795 utf8 && *utf8 ? ": " : "",
3796 utf8 && *utf8 ? utf8 : "");
3797 g_free(utf8);
3798
3799 purple_notify_user_info_add_pair(user_info, _("Status"), tmp);
3800 g_free(tmp);
3801 }
3802 3841
3803 oscar_user_info_convert_and_add(account, user_info, _("Additional Information"), info->info); 3842 oscar_user_info_convert_and_add(account, user_info, _("Additional Information"), info->info);
3804 purple_notify_user_info_add_section_break(user_info); 3843 purple_notify_user_info_add_section_break(user_info);
3805 3844
3806 if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) { 3845 if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) {
5619 PurpleConnection *gc = b->account->gc; 5658 PurpleConnection *gc = b->account->gc;
5620 OscarData *od = gc->proto_data; 5659 OscarData *od = gc->proto_data;
5621 aim_userinfo_t *userinfo = aim_locate_finduserinfo(od, b->name); 5660 aim_userinfo_t *userinfo = aim_locate_finduserinfo(od, b->name);
5622 5661
5623 if (PURPLE_BUDDY_IS_ONLINE(b)) { 5662 if (PURPLE_BUDDY_IS_ONLINE(b)) {
5624 PurplePresence *presence; 5663 oscar_user_info_append_status(gc, user_info, b, userinfo);
5625 PurpleStatus *status;
5626 const char *message;
5627 5664
5628 if (full) 5665 if (full)
5629 oscar_string_append_info(gc, user_info, b, userinfo); 5666 oscar_user_info_append_extra_info(gc, user_info, b, userinfo);
5630
5631 presence = purple_buddy_get_presence(b);
5632 status = purple_presence_get_active_status(presence);
5633 message = purple_status_get_attr_string(status, "message");
5634
5635 if (purple_status_is_available(status))
5636 {
5637 if (message != NULL)
5638 {
5639 /* Available status messages are plain text */
5640 gchar *tmp;
5641 tmp = g_markup_escape_text(message, -1);
5642 purple_notify_user_info_add_pair(user_info, _("Message"), tmp);
5643 g_free(tmp);
5644 }
5645 }
5646 else
5647 {
5648 if (message != NULL)
5649 {
5650 /* Away messages are HTML */
5651 gchar *tmp1, *tmp2;
5652 tmp2 = purple_markup_strip_html(message);
5653 tmp1 = g_markup_escape_text(tmp2, -1);
5654 g_free(tmp2);
5655 tmp2 = purple_str_sub_away_formatters(tmp1, purple_account_get_username(purple_connection_get_account(gc)));
5656 g_free(tmp1);
5657 purple_notify_user_info_add_pair(user_info, _("Away Message"), tmp2);
5658 g_free(tmp2);
5659 }
5660 else
5661 {
5662 purple_notify_user_info_add_pair(user_info, _("Away Message"), _("<i>(retrieving)</i>"));
5663 }
5664 }
5665 } 5667 }
5666 } 5668 }
5667 5669
5668 char *oscar_status_text(PurpleBuddy *b) 5670 char *oscar_status_text(PurpleBuddy *b)
5669 { 5671 {