comparison libpurple/protocols/jabber/buddy.c @ 23208:646e96069fcd

Use the notify_user_info API for the vcard information instead of creating a large string and passing it as a single value.
author Evan Schoenberg <evan.s@dreskin.net>
date Tue, 27 May 2008 01:37:42 +0000
parents e0bcb8cfda74
children f34fbd06984f
comparison
equal deleted inserted replaced
23207:84693a70ea3a 23208:646e96069fcd
46 JabberBuddy *jb; 46 JabberBuddy *jb;
47 char *jid; 47 char *jid;
48 GSList *ids; 48 GSList *ids;
49 GHashTable *resources; 49 GHashTable *resources;
50 int timeout_handle; 50 int timeout_handle;
51 char *vcard_text;
52 GSList *vcard_imgids; 51 GSList *vcard_imgids;
52 PurpleNotifyUserInfo *user_info;
53 } JabberBuddyInfo; 53 } JabberBuddyInfo;
54 54
55 void jabber_buddy_free(JabberBuddy *jb) 55 void jabber_buddy_free(JabberBuddy *jb)
56 { 56 {
57 g_return_if_fail(jb != NULL); 57 g_return_if_fail(jb != NULL);
775 if (jbi->timeout_handle > 0) 775 if (jbi->timeout_handle > 0)
776 purple_timeout_remove(jbi->timeout_handle); 776 purple_timeout_remove(jbi->timeout_handle);
777 777
778 g_free(jbi->jid); 778 g_free(jbi->jid);
779 g_hash_table_destroy(jbi->resources); 779 g_hash_table_destroy(jbi->resources);
780 g_free(jbi->vcard_text); 780 purple_notify_user_info_destroy(jbi->user_info);
781 g_free(jbi); 781 g_free(jbi);
782 } 782 }
783 783
784 static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi) 784 static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi)
785 { 785 {
791 791
792 /* not yet */ 792 /* not yet */
793 if(jbi->ids) 793 if(jbi->ids)
794 return; 794 return;
795 795
796 user_info = purple_notify_user_info_new(); 796 user_info = jbi->user_info;
797 resource_name = jabber_get_resource(jbi->jid); 797 resource_name = jabber_get_resource(jbi->jid);
798 798
799 /* If we have one or more pairs from the vcard, put a section break above it */
800 if (purple_notify_user_info_get_entries(user_info))
801 purple_notify_user_info_prepend_section_break(user_info);
802
803 /* Prepend the primary buddy info to user_info so that it goes before the vcard. */
799 if(resource_name) { 804 if(resource_name) {
800 jbr = jabber_buddy_find_resource(jbi->jb, resource_name); 805 jbr = jabber_buddy_find_resource(jbi->jb, resource_name);
801 jbir = g_hash_table_lookup(jbi->resources, resource_name); 806 jbir = g_hash_table_lookup(jbi->resources, resource_name);
807 if(jbr && jbr->client.name) {
808 tmp = g_strdup_printf("%s%s%s", jbr->client.name,
809 (jbr->client.version ? " " : ""),
810 (jbr->client.version ? jbr->client.version : ""));
811 purple_notify_user_info_add_pair(user_info, _("Client"), tmp);
812 g_free(tmp);
813
814 if(jbr->client.os) {
815 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
816 }
817 }
818 if(jbir) {
819 if(jbir->idle_seconds > 0) {
820 char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
821 purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle);
822 g_free(idle);
823 }
824 }
802 if(jbr) { 825 if(jbr) {
803 char *purdy = NULL; 826 char *purdy = NULL;
804 if(jbr->status) 827 if(jbr->status)
805 purdy = purple_strdup_withhtml(jbr->status); 828 purdy = purple_strdup_withhtml(jbr->status);
806 tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state), 829 tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state),
807 (purdy ? ": " : ""), 830 (purdy ? ": " : ""),
808 (purdy ? purdy : "")); 831 (purdy ? purdy : ""));
809 purple_notify_user_info_add_pair(user_info, _("Status"), tmp); 832 purple_notify_user_info_prepend_pair(user_info, _("Status"), tmp);
810 g_free(tmp); 833 g_free(tmp);
811 g_free(purdy); 834 g_free(purdy);
812 } else { 835 } else {
813 purple_notify_user_info_add_pair(user_info, _("Status"), _("Unknown")); 836 purple_notify_user_info_prepend_pair(user_info, _("Status"), _("Unknown"));
814 }
815 if(jbir) {
816 if(jbir->idle_seconds > 0) {
817 char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
818 purple_notify_user_info_add_pair(user_info, _("Idle"), idle);
819 g_free(idle);
820 }
821 }
822 if(jbr && jbr->client.name) {
823 tmp = g_strdup_printf("%s%s%s", jbr->client.name,
824 (jbr->client.version ? " " : ""),
825 (jbr->client.version ? jbr->client.version : ""));
826 purple_notify_user_info_add_pair(user_info, _("Client"), tmp);
827 g_free(tmp);
828
829 if(jbr->client.os) {
830 purple_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os);
831 }
832 } 837 }
833 #if 0 838 #if 0
834 /* #if 0 this for now; I think this would be far more useful if we limited this to a particular set of features 839 /* #if 0 this for now; I think this would be far more useful if we limited this to a particular set of features
835 * of particular interest (-vv jumps out as one). As it is now, I don't picture people getting all excited: "Oh sweet crap! 840 * of particular interest (-vv jumps out as one). As it is now, I don't picture people getting all excited: "Oh sweet crap!
836 * So-and-so supports 'jabber:x:data' AND 'Collaborative Data Objects'!" 841 * So-and-so supports 'jabber:x:data' AND 'Collaborative Data Objects'!"
947 if(feature) 952 if(feature)
948 g_string_append_printf(tmp, "%s<br/>", feature); 953 g_string_append_printf(tmp, "%s<br/>", feature);
949 } 954 }
950 955
951 if(strlen(tmp->str) > 0) 956 if(strlen(tmp->str) > 0)
952 purple_notify_user_info_add_pair(user_info, _("Capabilities"), tmp->str); 957 purple_notify_user_info_prepend_pair(user_info, _("Capabilities"), tmp->str);
953 958
954 g_string_free(tmp, TRUE); 959 g_string_free(tmp, TRUE);
955 } 960 }
956 #endif 961 #endif
957 } else { 962 } else {
963 gboolean multiple_resources = g_hash_table_size(jbi->jb->resources) > 1;
964
958 for(resources = jbi->jb->resources; resources; resources = resources->next) { 965 for(resources = jbi->jb->resources; resources; resources = resources->next) {
959 char *purdy = NULL; 966 char *purdy = NULL;
960 jbr = resources->data; 967 jbr = resources->data;
968
969 if(jbr->client.name) {
970 tmp = g_strdup_printf("%s%s%s", jbr->client.name,
971 (jbr->client.version ? " " : ""),
972 (jbr->client.version ? jbr->client.version : ""));
973 purple_notify_user_info_prepend_pair(user_info,
974 _("Client"), tmp);
975 g_free(tmp);
976
977 if(jbr->client.os) {
978 purple_notify_user_info_prepend_pair(user_info, _("Operating System"), jbr->client.os);
979 }
980 }
981
982 if(jbr->name && (jbir = g_hash_table_lookup(jbi->resources, jbr->name))) {
983 if(jbir->idle_seconds > 0) {
984 char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
985 purple_notify_user_info_prepend_pair(user_info, _("Idle"), idle);
986 g_free(idle);
987 }
988 }
989
961 if(jbr->status) 990 if(jbr->status)
962 purdy = purple_strdup_withhtml(jbr->status); 991 purdy = purple_strdup_withhtml(jbr->status);
963 if(jbr->name)
964 purple_notify_user_info_add_pair(user_info, _("Resource"), jbr->name);
965 tmp = g_strdup_printf("%d", jbr->priority);
966 purple_notify_user_info_add_pair(user_info, _("Priority"), tmp);
967 g_free(tmp);
968
969 tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state), 992 tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state),
970 (purdy ? ": " : ""), 993 (purdy ? ": " : ""),
971 (purdy ? purdy : "")); 994 (purdy ? purdy : ""));
972 purple_notify_user_info_add_pair(user_info, _("Status"), tmp); 995 purple_notify_user_info_prepend_pair(user_info, _("Status"), tmp);
973 g_free(tmp); 996 g_free(tmp);
974 g_free(purdy); 997 g_free(purdy);
998
999 if(multiple_resources) {
1000 tmp = g_strdup_printf("%d", jbr->priority);
1001 purple_notify_user_info_prepend_pair(user_info, _("Priority"), tmp);
1002 g_free(tmp);
1003 }
975 1004
976 if(jbr->name) 1005 if(jbr->name)
977 jbir = g_hash_table_lookup(jbi->resources, jbr->name); 1006 purple_notify_user_info_prepend_pair(user_info, _("Resource"), jbr->name);
978
979 if(jbir) {
980 if(jbir->idle_seconds > 0) {
981 char *idle = purple_str_seconds_to_string(jbir->idle_seconds);
982 purple_notify_user_info_add_pair(user_info, _("Idle"), idle);
983 g_free(idle);
984 }
985 }
986 if(jbr && jbr->client.name) {
987 tmp = g_strdup_printf("%s%s%s", jbr->client.name,
988 (jbr->client.version ? " " : ""),
989 (jbr->client.version ? jbr->client.version : ""));
990 purple_notify_user_info_add_pair(user_info,
991 _("Client"), tmp);
992 g_free(tmp);
993
994 if(jbr->client.os) {
995 purple_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os);
996 }
997 }
998 #if 0 1007 #if 0
999 if(jbr && jbr->caps) { 1008 if(jbr && jbr->caps) {
1000 GString *tmp = g_string_new(""); 1009 GString *tmp = g_string_new("");
1001 GList *iter; 1010 GList *iter;
1002 for(iter = jbr->caps->features; iter; iter = g_list_next(iter)) { 1011 for(iter = jbr->caps->features; iter; iter = g_list_next(iter)) {
1107 1116
1108 if(feature) 1117 if(feature)
1109 g_string_append_printf(tmp, "%s\n", feature); 1118 g_string_append_printf(tmp, "%s\n", feature);
1110 } 1119 }
1111 if(strlen(tmp->str) > 0) 1120 if(strlen(tmp->str) > 0)
1112 purple_notify_user_info_add_pair(user_info, _("Capabilities"), tmp->str); 1121 purple_notify_user_info_prepend_pair(user_info, _("Capabilities"), tmp->str);
1113 1122
1114 g_string_free(tmp, TRUE); 1123 g_string_free(tmp, TRUE);
1115 } 1124 }
1116 #endif 1125 #endif
1117 } 1126 }
1118 } 1127 }
1119 1128
1120 g_free(resource_name); 1129 g_free(resource_name);
1121 1130
1122 if (jbi->vcard_text != NULL) {
1123 purple_notify_user_info_add_section_break(user_info);
1124 /* Should this have some sort of label? */
1125 purple_notify_user_info_add_pair(user_info, NULL, jbi->vcard_text);
1126 }
1127
1128 purple_notify_userinfo(jbi->js->gc, jbi->jid, user_info, NULL, NULL); 1131 purple_notify_userinfo(jbi->js->gc, jbi->jid, user_info, NULL, NULL);
1129 purple_notify_user_info_destroy(user_info);
1130 1132
1131 while(jbi->vcard_imgids) { 1133 while(jbi->vcard_imgids) {
1132 purple_imgstore_unref_by_id(GPOINTER_TO_INT(jbi->vcard_imgids->data)); 1134 purple_imgstore_unref_by_id(GPOINTER_TO_INT(jbi->vcard_imgids->data));
1133 jbi->vcard_imgids = g_slist_delete_link(jbi->vcard_imgids, jbi->vcard_imgids); 1135 jbi->vcard_imgids = g_slist_delete_link(jbi->vcard_imgids, jbi->vcard_imgids);
1134 } 1136 }
1191 jabber_iq_set_callback(iq, jabber_vcard_save_mine, NULL); 1193 jabber_iq_set_callback(iq, jabber_vcard_save_mine, NULL);
1192 1194
1193 jabber_iq_send(iq); 1195 jabber_iq_send(iq);
1194 } 1196 }
1195 1197
1196 static void
1197 jabber_string_escape_and_append(GString *string, const char *name, const char *value, gboolean indent)
1198 {
1199 gchar *escaped;
1200
1201 escaped = g_markup_escape_text(value, -1);
1202 g_string_append_printf(string, "%s<b>%s:</b> %s<br/>",
1203 indent ? "&nbsp;&nbsp;" : "", name, escaped);
1204 g_free(escaped);
1205 }
1206
1207 static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data) 1198 static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data)
1208 { 1199 {
1209 const char *id, *from; 1200 const char *id, *from;
1210 GString *info_text;
1211 char *bare_jid; 1201 char *bare_jid;
1212 char *text; 1202 char *text;
1213 char *serverside_alias = NULL; 1203 char *serverside_alias = NULL;
1214 xmlnode *vcard; 1204 xmlnode *vcard;
1215 PurpleBuddy *b; 1205 PurpleBuddy *b;
1216 JabberBuddyInfo *jbi = data; 1206 JabberBuddyInfo *jbi = data;
1207 PurpleNotifyUserInfo *user_info;
1217 1208
1218 from = xmlnode_get_attrib(packet, "from"); 1209 from = xmlnode_get_attrib(packet, "from");
1219 id = xmlnode_get_attrib(packet, "id"); 1210 id = xmlnode_get_attrib(packet, "id");
1220 1211
1221 if(!jbi) 1212 if(!jbi)
1229 if(!jabber_buddy_find(js, from, FALSE)) 1220 if(!jabber_buddy_find(js, from, FALSE))
1230 return; 1221 return;
1231 1222
1232 /* XXX: handle the error case */ 1223 /* XXX: handle the error case */
1233 1224
1225 user_info = jbi->user_info;
1234 bare_jid = jabber_get_bare_jid(from); 1226 bare_jid = jabber_get_bare_jid(from);
1235 1227
1236 b = purple_find_buddy(js->gc->account, bare_jid); 1228 b = purple_find_buddy(js->gc->account, bare_jid);
1237
1238 info_text = g_string_new("");
1239 1229
1240 if((vcard = xmlnode_get_child(packet, "vCard")) || 1230 if((vcard = xmlnode_get_child(packet, "vCard")) ||
1241 (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) { 1231 (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) {
1242 xmlnode *child; 1232 xmlnode *child;
1243 for(child = vcard->child; child; child = child->next) 1233 for(child = vcard->child; child; child = child->next)
1251 if(text && !strcmp(child->name, "FN")) { 1241 if(text && !strcmp(child->name, "FN")) {
1252 /* If we havne't found a name yet, use this one as the serverside name */ 1242 /* If we havne't found a name yet, use this one as the serverside name */
1253 if (!serverside_alias) 1243 if (!serverside_alias)
1254 serverside_alias = g_strdup(text); 1244 serverside_alias = g_strdup(text);
1255 1245
1256 jabber_string_escape_and_append(info_text, 1246 purple_notify_user_info_add_pair(user_info, _("Full Name"), text);
1257 _("Full Name"), text, FALSE);
1258 } else if(!strcmp(child->name, "N")) { 1247 } else if(!strcmp(child->name, "N")) {
1259 for(child2 = child->child; child2; child2 = child2->next) 1248 for(child2 = child->child; child2; child2 = child2->next)
1260 { 1249 {
1261 char *text2; 1250 char *text2;
1262 1251
1263 if(child2->type != XMLNODE_TYPE_TAG) 1252 if(child2->type != XMLNODE_TYPE_TAG)
1264 continue; 1253 continue;
1265 1254
1266 text2 = xmlnode_get_data(child2); 1255 text2 = xmlnode_get_data(child2);
1267 if(text2 && !strcmp(child2->name, "FAMILY")) { 1256 if(text2 && !strcmp(child2->name, "FAMILY")) {
1268 jabber_string_escape_and_append(info_text, 1257 purple_notify_user_info_add_pair(user_info, _("Family Name"), text2);
1269 _("Family Name"), text2, FALSE);
1270 } else if(text2 && !strcmp(child2->name, "GIVEN")) { 1258 } else if(text2 && !strcmp(child2->name, "GIVEN")) {
1271 jabber_string_escape_and_append(info_text, 1259 purple_notify_user_info_add_pair(user_info, _("Given Name"), text2);
1272 _("Given Name"), text2, FALSE);
1273 } else if(text2 && !strcmp(child2->name, "MIDDLE")) { 1260 } else if(text2 && !strcmp(child2->name, "MIDDLE")) {
1274 jabber_string_escape_and_append(info_text, 1261 purple_notify_user_info_add_pair(user_info, _("Middle Name"), text2);
1275 _("Middle Name"), text2, FALSE);
1276 } 1262 }
1277 g_free(text2); 1263 g_free(text2);
1278 } 1264 }
1279 } else if(text && !strcmp(child->name, "NICKNAME")) { 1265 } else if(text && !strcmp(child->name, "NICKNAME")) {
1280 /* Prefer the Nickcname to the Full Name as the serverside alias */ 1266 /* Prefer the Nickcname to the Full Name as the serverside alias */
1281 g_free(serverside_alias); 1267 g_free(serverside_alias);
1282 serverside_alias = g_strdup(text); 1268 serverside_alias = g_strdup(text);
1283 1269
1284 jabber_string_escape_and_append(info_text, 1270 purple_notify_user_info_add_pair(user_info, _("Nickname"), text);
1285 _("Nickname"), text, FALSE);
1286 } else if(text && !strcmp(child->name, "BDAY")) { 1271 } else if(text && !strcmp(child->name, "BDAY")) {
1287 jabber_string_escape_and_append(info_text, 1272 purple_notify_user_info_add_pair(user_info, _("Birthday"), text);
1288 _("Birthday"), text, FALSE);
1289 } else if(!strcmp(child->name, "ADR")) { 1273 } else if(!strcmp(child->name, "ADR")) {
1290 gboolean address_line_added = FALSE; 1274 gboolean address_line_added = FALSE;
1291 1275
1292 for(child2 = child->child; child2; child2 = child2->next) 1276 for(child2 = child->child; child2; child2 = child2->next)
1293 { 1277 {
1302 1286
1303 /* We do this here so that it's not added if all the child 1287 /* We do this here so that it's not added if all the child
1304 * elements are empty. */ 1288 * elements are empty. */
1305 if (!address_line_added) 1289 if (!address_line_added)
1306 { 1290 {
1307 g_string_append_printf(info_text, "<b>%s:</b><br/>", 1291 purple_notify_user_info_add_section_header(user_info, _("Address"));
1308 _("Address"));
1309 address_line_added = TRUE; 1292 address_line_added = TRUE;
1310 } 1293 }
1311 1294
1312 if(!strcmp(child2->name, "POBOX")) { 1295 if(!strcmp(child2->name, "POBOX")) {
1313 jabber_string_escape_and_append(info_text, 1296 purple_notify_user_info_add_pair(user_info, _("P.O. Box"), text2);
1314 _("P.O. Box"), text2, TRUE);
1315 } else if(!strcmp(child2->name, "EXTADR")) { 1297 } else if(!strcmp(child2->name, "EXTADR")) {
1316 jabber_string_escape_and_append(info_text, 1298 purple_notify_user_info_add_pair(user_info, _("Extended Address"), text2);
1317 _("Extended Address"), text2, TRUE);
1318 } else if(!strcmp(child2->name, "STREET")) { 1299 } else if(!strcmp(child2->name, "STREET")) {
1319 jabber_string_escape_and_append(info_text, 1300 purple_notify_user_info_add_pair(user_info, _("Street Address"), text2);
1320 _("Street Address"), text2, TRUE);
1321 } else if(!strcmp(child2->name, "LOCALITY")) { 1301 } else if(!strcmp(child2->name, "LOCALITY")) {
1322 jabber_string_escape_and_append(info_text, 1302 purple_notify_user_info_add_pair(user_info, _("Locality"), text2);
1323 _("Locality"), text2, TRUE);
1324 } else if(!strcmp(child2->name, "REGION")) { 1303 } else if(!strcmp(child2->name, "REGION")) {
1325 jabber_string_escape_and_append(info_text, 1304 purple_notify_user_info_add_pair(user_info, _("Region"), text2);
1326 _("Region"), text2, TRUE);
1327 } else if(!strcmp(child2->name, "PCODE")) { 1305 } else if(!strcmp(child2->name, "PCODE")) {
1328 jabber_string_escape_and_append(info_text, 1306 purple_notify_user_info_add_pair(user_info, _("Postal Code"), text2);
1329 _("Postal Code"), text2, TRUE);
1330 } else if(!strcmp(child2->name, "CTRY") 1307 } else if(!strcmp(child2->name, "CTRY")
1331 || !strcmp(child2->name, "COUNTRY")) { 1308 || !strcmp(child2->name, "COUNTRY")) {
1332 jabber_string_escape_and_append(info_text, 1309 purple_notify_user_info_add_pair(user_info, _("Country"), text2);
1333 _("Country"), text2, TRUE);
1334 } 1310 }
1335 g_free(text2); 1311 g_free(text2);
1336 } 1312 }
1313
1314 if (address_line_added)
1315 purple_notify_user_info_add_section_break(user_info);
1316
1337 } else if(!strcmp(child->name, "TEL")) { 1317 } else if(!strcmp(child->name, "TEL")) {
1338 char *number; 1318 char *number;
1339 if((child2 = xmlnode_get_child(child, "NUMBER"))) { 1319 if((child2 = xmlnode_get_child(child, "NUMBER"))) {
1340 /* show what kind of number it is */ 1320 /* show what kind of number it is */
1341 number = xmlnode_get_data(child2); 1321 number = xmlnode_get_data(child2);
1342 if(number) { 1322 if(number) {
1343 jabber_string_escape_and_append(info_text, 1323 purple_notify_user_info_add_pair(user_info, _("Telephone"), number);
1344 _("Telephone"), number, FALSE);
1345 g_free(number); 1324 g_free(number);
1346 } 1325 }
1347 } else if((number = xmlnode_get_data(child))) { 1326 } else if((number = xmlnode_get_data(child))) {
1348 /* lots of clients (including purple) do this, but it's 1327 /* lots of clients (including purple) do this, but it's
1349 * out of spec */ 1328 * out of spec */
1350 jabber_string_escape_and_append(info_text, 1329 purple_notify_user_info_add_pair(user_info, _("Telephone"), number);
1351 _("Telephone"), number, FALSE);
1352 g_free(number); 1330 g_free(number);
1353 } 1331 }
1354 } else if(!strcmp(child->name, "EMAIL")) { 1332 } else if(!strcmp(child->name, "EMAIL")) {
1355 char *userid, *escaped; 1333 char *userid, *escaped;
1356 if((child2 = xmlnode_get_child(child, "USERID"))) { 1334 if((child2 = xmlnode_get_child(child, "USERID"))) {
1357 /* show what kind of email it is */ 1335 /* show what kind of email it is */
1358 userid = xmlnode_get_data(child2); 1336 userid = xmlnode_get_data(child2);
1359 if(userid) { 1337 if(userid) {
1338 char *mailto;
1360 escaped = g_markup_escape_text(userid, -1); 1339 escaped = g_markup_escape_text(userid, -1);
1361 g_string_append_printf(info_text, 1340 mailto = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", escaped, escaped);
1362 "<b>%s:</b> <a href=\"mailto:%s\">%s</a><br/>", 1341 purple_notify_user_info_add_pair(user_info, _("Email"), mailto);
1363 _("Email"), escaped, escaped); 1342
1343 g_free(mailto);
1364 g_free(escaped); 1344 g_free(escaped);
1365 g_free(userid); 1345 g_free(userid);
1366 } 1346 }
1367 } else if((userid = xmlnode_get_data(child))) { 1347 } else if((userid = xmlnode_get_data(child))) {
1368 /* lots of clients (including purple) do this, but it's 1348 /* lots of clients (including purple) do this, but it's
1369 * out of spec */ 1349 * out of spec */
1350 char *mailto;
1351
1370 escaped = g_markup_escape_text(userid, -1); 1352 escaped = g_markup_escape_text(userid, -1);
1371 g_string_append_printf(info_text, 1353 mailto = g_strdup_printf("<a href=\"mailto:%s\">%s</a>", escaped, escaped);
1372 "<b>%s:</b> <a href=\"mailto:%s\">%s</a><br/>", 1354 purple_notify_user_info_add_pair(user_info, _("Email"), mailto);
1373 _("Email"), escaped, escaped); 1355
1356 g_free(mailto);
1374 g_free(escaped); 1357 g_free(escaped);
1375 g_free(userid); 1358 g_free(userid);
1376 } 1359 }
1377 } else if(!strcmp(child->name, "ORG")) { 1360 } else if(!strcmp(child->name, "ORG")) {
1378 for(child2 = child->child; child2; child2 = child2->next) 1361 for(child2 = child->child; child2; child2 = child2->next)
1382 if(child2->type != XMLNODE_TYPE_TAG) 1365 if(child2->type != XMLNODE_TYPE_TAG)
1383 continue; 1366 continue;
1384 1367
1385 text2 = xmlnode_get_data(child2); 1368 text2 = xmlnode_get_data(child2);
1386 if(text2 && !strcmp(child2->name, "ORGNAME")) { 1369 if(text2 && !strcmp(child2->name, "ORGNAME")) {
1387 jabber_string_escape_and_append(info_text, 1370 purple_notify_user_info_add_pair(user_info, _("Organization Name"), text2);
1388 _("Organization Name"), text2, FALSE);
1389 } else if(text2 && !strcmp(child2->name, "ORGUNIT")) { 1371 } else if(text2 && !strcmp(child2->name, "ORGUNIT")) {
1390 jabber_string_escape_and_append(info_text, 1372 purple_notify_user_info_add_pair(user_info, _("Organization Unit"), text2);
1391 _("Organization Unit"), text2, FALSE);
1392 } 1373 }
1393 g_free(text2); 1374 g_free(text2);
1394 } 1375 }
1395 } else if(text && !strcmp(child->name, "TITLE")) { 1376 } else if(text && !strcmp(child->name, "TITLE")) {
1396 jabber_string_escape_and_append(info_text, 1377 purple_notify_user_info_add_pair(user_info, _("Title"), text);
1397 _("Title"), text, FALSE);
1398 } else if(text && !strcmp(child->name, "ROLE")) { 1378 } else if(text && !strcmp(child->name, "ROLE")) {
1399 jabber_string_escape_and_append(info_text, 1379 purple_notify_user_info_add_pair(user_info, _("Role"), text);
1400 _("Role"), text, FALSE);
1401 } else if(text && !strcmp(child->name, "DESC")) { 1380 } else if(text && !strcmp(child->name, "DESC")) {
1402 jabber_string_escape_and_append(info_text, 1381 purple_notify_user_info_add_pair(user_info, _("Description"), text);
1403 _("Description"), text, FALSE);
1404 } else if(!strcmp(child->name, "PHOTO") || 1382 } else if(!strcmp(child->name, "PHOTO") ||
1405 !strcmp(child->name, "LOGO")) { 1383 !strcmp(child->name, "LOGO")) {
1406 char *bintext = NULL; 1384 char *bintext = NULL;
1407 xmlnode *binval; 1385 xmlnode *binval;
1408 1386
1416 char *p, hash[41]; 1394 char *p, hash[41];
1417 gboolean photo = (strcmp(child->name, "PHOTO") == 0); 1395 gboolean photo = (strcmp(child->name, "PHOTO") == 0);
1418 1396
1419 data = purple_base64_decode(bintext, &size); 1397 data = purple_base64_decode(bintext, &size);
1420 if (data) { 1398 if (data) {
1399 char *img_text;
1400
1421 jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png"))); 1401 jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png")));
1422 g_string_append_printf(info_text, 1402 img_text = g_strdup_printf("<img id='%d'>", GPOINTER_TO_INT(jbi->vcard_imgids->data));
1423 "<b>%s:</b> <img id='%d'><br/>", 1403
1424 photo ? _("Photo") : _("Logo"), 1404 purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text);
1425 GPOINTER_TO_INT(jbi->vcard_imgids->data)); 1405
1426
1427 purple_cipher_digest_region("sha1", (guchar *)data, size, 1406 purple_cipher_digest_region("sha1", (guchar *)data, size,
1428 sizeof(hashval), hashval, NULL); 1407 sizeof(hashval), hashval, NULL);
1429 p = hash; 1408 p = hash;
1430 for(i=0; i<20; i++, p+=2) 1409 for(i=0; i<20; i++, p+=2)
1431 snprintf(p, 3, "%02x", hashval[i]); 1410 snprintf(p, 3, "%02x", hashval[i]);
1432 1411
1433 purple_buddy_icons_set_for_user(js->gc->account, bare_jid, 1412 purple_buddy_icons_set_for_user(js->gc->account, bare_jid,
1434 data, size, hash); 1413 data, size, hash);
1435 g_free(bintext); 1414 g_free(bintext);
1415 g_free(img_text);
1436 } 1416 }
1437 } 1417 }
1438 } 1418 }
1439 g_free(text); 1419 g_free(text);
1440 } 1420 }
1448 } 1428 }
1449 1429
1450 g_free(serverside_alias); 1430 g_free(serverside_alias);
1451 } 1431 }
1452 1432
1453 jbi->vcard_text = purple_strdup_withhtml(info_text->str);
1454 g_string_free(info_text, TRUE);
1455 g_free(bare_jid); 1433 g_free(bare_jid);
1456 1434
1457 jabber_buddy_info_show_if_ready(jbi); 1435 jabber_buddy_info_show_if_ready(jbi);
1458 } 1436 }
1459 1437
1733 jbi = g_new0(JabberBuddyInfo, 1); 1711 jbi = g_new0(JabberBuddyInfo, 1);
1734 jbi->jid = g_strdup(jid); 1712 jbi->jid = g_strdup(jid);
1735 jbi->js = js; 1713 jbi->js = js;
1736 jbi->jb = jb; 1714 jbi->jb = jb;
1737 jbi->resources = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, jabber_buddy_info_resource_free); 1715 jbi->resources = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, jabber_buddy_info_resource_free);
1716 jbi->user_info = purple_notify_user_info_new();
1738 1717
1739 iq = jabber_iq_new(js, JABBER_IQ_GET); 1718 iq = jabber_iq_new(js, JABBER_IQ_GET);
1740 1719
1741 xmlnode_set_attrib(iq->node, "to", jid); 1720 xmlnode_set_attrib(iq->node, "to", jid);
1742 vcard = xmlnode_new_child(iq->node, "vCard"); 1721 vcard = xmlnode_new_child(iq->node, "vCard");