📄 buddy.c
字号:
* Formats GSList data into XML-encoded string and returns a pointer * to said string. * * g_free()'ing the returned string space is the responsibility of * the caller. */static voidjabber_format_info(PurpleConnection *gc, PurpleRequestFields *fields){ xmlnode *vc_node; PurpleRequestField *field; const char *text; char *p; const struct vcard_template *vc_tp; struct tag_attr *tag_attr; vc_node = xmlnode_new("vCard"); for(tag_attr = vcard_tag_attr_list; tag_attr->attr != NULL; ++tag_attr) xmlnode_set_attrib(vc_node, tag_attr->attr, tag_attr->value); for (vc_tp = vcard_template_data; vc_tp->label != NULL; vc_tp++) { if (*vc_tp->label == '\0') continue; field = purple_request_fields_get_field(fields, vc_tp->tag); text = purple_request_field_string_get_value(field); if (text != NULL && *text != '\0') { xmlnode *xp; purple_debug(PURPLE_DEBUG_INFO, "jabber", "Setting %s to '%s'\n", vc_tp->tag, text); if ((xp = insert_tag_to_parent_tag(vc_node, NULL, vc_tp->tag)) != NULL) { xmlnode_insert_data(xp, text, -1); } } } p = xmlnode_to_str(vc_node, NULL); xmlnode_free(vc_node); purple_account_set_user_info(purple_connection_get_account(gc), p); serv_set_info(gc, p); g_free(p);}/* * This gets executed by the proto action * * Creates a new PurpleRequestFields struct, gets the XML-formatted user_info * string (if any) into GSLists for the (multi-entry) edit dialog and * calls the set_vcard dialog. */void jabber_setup_set_info(PurplePluginAction *action){ PurpleConnection *gc = (PurpleConnection *) action->context; PurpleRequestFields *fields; PurpleRequestFieldGroup *group; PurpleRequestField *field; const struct vcard_template *vc_tp; const char *user_info; char *cdata = NULL; xmlnode *x_vc_data = NULL; fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); /* * Get existing, XML-formatted, user info */ if((user_info = purple_account_get_user_info(gc->account)) != NULL) x_vc_data = xmlnode_from_str(user_info, -1); /* * Set up GSLists for edit with labels from "template," data from user info */ for(vc_tp = vcard_template_data; vc_tp->label != NULL; ++vc_tp) { xmlnode *data_node; if((vc_tp->label)[0] == '\0') continue; if (x_vc_data != NULL) { if(vc_tp->ptag == NULL) { data_node = xmlnode_get_child(x_vc_data, vc_tp->tag); } else { gchar *tag = g_strdup_printf("%s/%s", vc_tp->ptag, vc_tp->tag); data_node = xmlnode_get_child(x_vc_data, tag); g_free(tag); } if(data_node) cdata = xmlnode_get_data(data_node); } if(strcmp(vc_tp->tag, "DESC") == 0) { field = purple_request_field_string_new(vc_tp->tag, _(vc_tp->label), cdata, TRUE); } else { field = purple_request_field_string_new(vc_tp->tag, _(vc_tp->label), cdata, FALSE); } g_free(cdata); cdata = NULL; purple_request_field_group_add_field(group, field); } if(x_vc_data != NULL) xmlnode_free(x_vc_data); purple_request_fields(gc, _("Edit XMPP vCard"), _("Edit XMPP vCard"), _("All items below are optional. Enter only the " "information with which you feel comfortable."), fields, _("Save"), G_CALLBACK(jabber_format_info), _("Cancel"), NULL, purple_connection_get_account(gc), NULL, NULL, gc);}/*---------------------------------------*//* End Jabber "set info" (vCard) support *//*---------------------------------------*//****** * end of that ancient crap that needs to die ******/static void jabber_buddy_info_destroy(JabberBuddyInfo *jbi){ /* Remove the timeout, which would otherwise trigger jabber_buddy_get_info_timeout() */ if (jbi->timeout_handle > 0) purple_timeout_remove(jbi->timeout_handle); g_free(jbi->jid); g_hash_table_destroy(jbi->resources); g_free(jbi->vcard_text); g_free(jbi);}static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi){ char *resource_name, *tmp; JabberBuddyResource *jbr; JabberBuddyInfoResource *jbir = NULL; GList *resources; PurpleNotifyUserInfo *user_info; /* not yet */ if(jbi->ids) return; user_info = purple_notify_user_info_new(); resource_name = jabber_get_resource(jbi->jid); if(resource_name) { jbr = jabber_buddy_find_resource(jbi->jb, resource_name); jbir = g_hash_table_lookup(jbi->resources, resource_name); if(jbr) { char *purdy = NULL; if(jbr->status) purdy = purple_strdup_withhtml(jbr->status); tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state), (purdy ? ": " : ""), (purdy ? purdy : "")); purple_notify_user_info_add_pair(user_info, _("Status"), tmp); g_free(tmp); g_free(purdy); } else { purple_notify_user_info_add_pair(user_info, _("Status"), _("Unknown")); } if(jbir) { if(jbir->idle_seconds > 0) { char *idle = purple_str_seconds_to_string(jbir->idle_seconds); purple_notify_user_info_add_pair(user_info, _("Idle"), idle); g_free(idle); } } if(jbr && jbr->client.name) { tmp = g_strdup_printf("%s%s%s", jbr->client.name, (jbr->client.version ? " " : ""), (jbr->client.version ? jbr->client.version : "")); purple_notify_user_info_add_pair(user_info, _("Client"), tmp); g_free(tmp); if(jbr->client.os) { purple_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os); } } } else { for(resources = jbi->jb->resources; resources; resources = resources->next) { char *purdy = NULL; jbr = resources->data; if(jbr->status) purdy = purple_strdup_withhtml(jbr->status); if(jbr->name) purple_notify_user_info_add_pair(user_info, _("Resource"), jbr->name); tmp = g_strdup_printf("%d", jbr->priority); purple_notify_user_info_add_pair(user_info, _("Priority"), tmp); g_free(tmp); tmp = g_strdup_printf("%s%s%s", jabber_buddy_state_get_name(jbr->state), (purdy ? ": " : ""), (purdy ? purdy : "")); purple_notify_user_info_add_pair(user_info, _("Status"), tmp); g_free(tmp); g_free(purdy); if(jbr->name) jbir = g_hash_table_lookup(jbi->resources, jbr->name); if(jbir) { if(jbir->idle_seconds > 0) { char *idle = purple_str_seconds_to_string(jbir->idle_seconds); purple_notify_user_info_add_pair(user_info, _("Idle"), idle); g_free(idle); } } if(jbr && jbr->client.name) { tmp = g_strdup_printf("%s%s%s", jbr->client.name, (jbr->client.version ? " " : ""), (jbr->client.version ? jbr->client.version : "")); purple_notify_user_info_add_pair(user_info, _("Client"), tmp); g_free(tmp); if(jbr->client.os) { purple_notify_user_info_add_pair(user_info, _("Operating System"), jbr->client.os); } } } } g_free(resource_name); if (jbi->vcard_text != NULL) { purple_notify_user_info_add_section_break(user_info); /* Should this have some sort of label? */ purple_notify_user_info_add_pair(user_info, NULL, jbi->vcard_text); } purple_notify_userinfo(jbi->js->gc, jbi->jid, user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); while(jbi->vcard_imgids) { purple_imgstore_unref_by_id(GPOINTER_TO_INT(jbi->vcard_imgids->data)); jbi->vcard_imgids = g_slist_delete_link(jbi->vcard_imgids, jbi->vcard_imgids); } jbi->js->pending_buddy_info_requests = g_slist_remove(jbi->js->pending_buddy_info_requests, jbi); jabber_buddy_info_destroy(jbi);}static void jabber_buddy_info_remove_id(JabberBuddyInfo *jbi, const char *id){ GSList *l = jbi->ids; char *comp_id; if(!id) return; while(l) { comp_id = l->data; if(!strcmp(id, comp_id)) { jbi->ids = g_slist_remove(jbi->ids, comp_id); g_free(comp_id); return; } l = l->next; }}static void jabber_vcard_parse(JabberStream *js, xmlnode *packet, gpointer data){ const char *id, *from; GString *info_text; char *bare_jid; char *text; xmlnode *vcard; PurpleBuddy *b; JabberBuddyInfo *jbi = data; from = xmlnode_get_attrib(packet, "from"); id = xmlnode_get_attrib(packet, "id"); if(!jbi) return; jabber_buddy_info_remove_id(jbi, id); if(!from) return; if(!jabber_buddy_find(js, from, FALSE)) return; /* XXX: handle the error case */ bare_jid = jabber_get_bare_jid(from); b = purple_find_buddy(js->gc->account, bare_jid); info_text = g_string_new(""); if((vcard = xmlnode_get_child(packet, "vCard")) || (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) { xmlnode *child; for(child = vcard->child; child; child = child->next) { xmlnode *child2; if(child->type != XMLNODE_TYPE_TAG) continue; text = xmlnode_get_data(child); if(text && !strcmp(child->name, "FN")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Full Name"), text); } else if(!strcmp(child->name, "N")) { for(child2 = child->child; child2; child2 = child2->next) { char *text2; if(child2->type != XMLNODE_TYPE_TAG) continue; text2 = xmlnode_get_data(child2); if(text2 && !strcmp(child2->name, "FAMILY")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Family Name"), text2); } else if(text2 && !strcmp(child2->name, "GIVEN")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Given Name"), text2); } else if(text2 && !strcmp(child2->name, "MIDDLE")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Middle Name"), text2); } g_free(text2); } } else if(text && !strcmp(child->name, "NICKNAME")) { serv_got_alias(js->gc, from, text); if(b) { purple_blist_node_set_string((PurpleBlistNode*)b, "servernick", text); } g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Nickname"), text); } else if(text && !strcmp(child->name, "BDAY")) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Birthday"), text); } else if(!strcmp(child->name, "ADR")) { gboolean address_line_added = FALSE; for(child2 = child->child; child2; child2 = child2->next) { char *text2; if(child2->type != XMLNODE_TYPE_TAG) continue; text2 = xmlnode_get_data(child2); if (text2 == NULL) continue; /* We do this here so that it's not added if all the child * elements are empty. */ if (!address_line_added) { g_string_append_printf(info_text, "<b>%s:</b><br/>", _("Address")); address_line_added = TRUE; } if(!strcmp(child2->name, "POBOX")) { g_string_append_printf(info_text, " <b>%s:</b> %s<br/>", _("P.O. Box"), text2); } else if(!strcmp(child2->name, "EXTADR")) { g_string_append_printf(info_text, " <b>%s:</b> %s<br/>", _("Extended Address"), text2); } else if(!strcmp(child2->name, "STREET")) { g_string_append_printf(info_text, " <b>%s:</b> %s<br/>", _("Street Address"), text2); } else if(!strcmp(child2->name, "LOCALITY")) { g_string_append_printf(info_text, " <b>%s:</b> %s<br/>", _("Locality"), text2); } else if(!strcmp(child2->name, "REGION")) { g_string_append_printf(info_text, " <b>%s:</b> %s<br/>", _("Region"), text2); } else if(!strcmp(child2->name, "PCODE")) { g_string_append_printf(info_text, " <b>%s:</b> %s<br/>", _("Postal Code"), text2); } else if(!strcmp(child2->name, "CTRY") || !strcmp(child2->name, "COUNTRY")) { g_string_append_printf(info_text, " <b>%s:</b> %s<br/>", _("Country"), text2); } g_free(text2); } } else if(!strcmp(child->name, "TEL")) { char *number; if((child2 = xmlnode_get_child(child, "NUMBER"))) { /* show what kind of number it is */ number = xmlnode_get_data(child2); if(number) { g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Telephone"), number); g_free(number); } } else if((number = xmlnode_get_data(child))) { /* lots of clients (including purple) do this, but it's * out of spec */ g_string_append_printf(info_text, "<b>%s:</b> %s<br/>", _("Telephone"), number); g_free(number); } } else if(!strcmp(child->name, "EMAIL")) { char *userid; if((child2 = xmlnode_get_child(child, "USERID"))) { /* show what kind of email it is */ userid = xmlnode_get_data(child2); if(userid) { g_string_append_printf(info_text, "<b>%s:</b> <a href='mailto:%s'>%s</a><br/>", _("E-Mail"), userid, userid); g_free(userid); } } else if((userid = xmlnode_get_data(child))) { /* lots of clients (including purple) do this, but it's * out of spec */ g_string_append_printf(info_text, "<b>%s:</b> <a href='mailto:%s'>%s</a><br/>", _("E-Mail"), userid, userid); g_free(userid); } } else if(!strcmp(child->name, "ORG")) { for(child2 = child->child; child2; child2 = child2->next) { char *text2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -