# HG changeset patch # User Elliott Sales de Andrade # Date 1212825701 0 # Node ID 70de4e2246ecc7a896e05013c1adeaa1af8f3d31 # Parent 5a6cf27ead311f170cc1074a025555acdd0f41b4 Add real server-side aliasing to MSN. diff -r 5a6cf27ead31 -r 70de4e2246ec libpurple/protocols/msn/contact.c --- a/libpurple/protocols/msn/contact.c Sat Jun 07 06:39:13 2008 +0000 +++ b/libpurple/protocols/msn/contact.c Sat Jun 07 08:01:41 2008 +0000 @@ -510,12 +510,14 @@ msn_parse_addressbook_contacts(MsnSession *session, xmlnode *node) { xmlnode *contactNode; - char *passport = NULL, *Name = NULL, *uid = NULL, *type = NULL, *mobile_number = NULL; + char *passport = NULL, *Name = NULL, *uid = NULL, *type = NULL, *mobile_number = NULL, *alias = NULL; gboolean mobile = FALSE; + PurpleConnection *pc = purple_account_get_connection(session->account); for(contactNode = xmlnode_get_child(node, "Contact"); contactNode; contactNode = xmlnode_get_next_twin(contactNode)) { xmlnode *contactId, *contactInfo, *contactType, *passportName, *displayName, *guid, *groupIds, *messenger_user; + xmlnode *annotation; MsnUser *user; MsnUserType usertype; @@ -526,10 +528,11 @@ g_free(passport); g_free(Name); + g_free(alias); g_free(uid); g_free(type); g_free(mobile_number); - passport = Name = uid = type = mobile_number = NULL; + passport = Name = uid = type = mobile_number = alias = NULL; mobile = FALSE; uid = xmlnode_get_data(contactId); @@ -610,10 +613,19 @@ else Name = g_strdup(passport); + for (annotation = xmlnode_get_child(contactInfo, "annotations/Annotation"); + annotation; annotation = xmlnode_get_next_twin(annotation)) { + char *name; + name = xmlnode_get_data(xmlnode_get_child(annotation, "Name")); + if (!strcmp(name, "AB.NickName")) + alias = xmlnode_get_data(xmlnode_get_child(annotation, "Value")); + g_free(name); + } + mobile = msn_parse_addressbook_mobile(contactInfo, &mobile_number); - purple_debug_misc("MsnAB","passport:{%s} uid:{%s} display:{%s} mobile:{%s} mobile number:{%s}\n", - passport, uid ? uid : "(null)", Name ? Name : "(null)", + purple_debug_misc("MsnAB","passport:{%s} uid:{%s} display:{%s} alias: {%s} mobile:{%s} mobile number:{%s}\n", + passport, uid ? uid : "(null)", Name ? Name : "(null)", alias ? alias : "(null)", mobile ? "true" : "false", mobile_number ? mobile_number : "(null)"); user = msn_userlist_find_add_user(session->userlist, passport, Name); @@ -644,6 +656,8 @@ purple_prpl_got_user_status(session->account, user->passport, "mobile", NULL); purple_prpl_got_user_status(session->account, user->passport, "available", NULL); } + if (alias) + purple_serv_got_private_alias(pc, passport, alias); } g_free(passport); @@ -1185,28 +1199,72 @@ purple_debug_info("MSN CL","Contact updated successfully\n"); } -/* Update a contact's nickname */ +/* Update a contact's info */ void -msn_update_contact(MsnSession *session, const char* nickname) +msn_update_contact(MsnSession *session, const char *passport, MsnContactUpdateType type, const char* value) { MsnCallbackState *state; - gchar *body = NULL, *escaped_nickname; + xmlnode *contact; + xmlnode *contact_info; + xmlnode *changes; - purple_debug_info("MSN CL","Update contact information with new friendly name: %s\n", nickname); + purple_debug_info("MSN CL","Update contact information with new %s: %s\n", + type==MSN_UPDATE_DISPLAY ? "display name" : "alias", value); + purple_debug_info("msncl", "passport=%s\n", passport); + g_return_if_fail(passport != NULL); + contact_info = xmlnode_new("contactInfo"); + changes = xmlnode_new("propertiesChanged"); - escaped_nickname = g_markup_escape_text(nickname, -1); + switch (type) { + xmlnode *annotations; + xmlnode *display; + xmlnode *a, *n, *v; + case MSN_UPDATE_DISPLAY: + display = xmlnode_new_child(contact_info, "displayName"); + xmlnode_insert_data(display, value, -1); + xmlnode_insert_data(changes, "DisplayName", -1); + break; - body = g_strdup_printf(MSN_CONTACT_UPDATE_TEMPLATE, escaped_nickname); + case MSN_UPDATE_ALIAS: + annotations = xmlnode_new_child(contact_info, "annotations"); + xmlnode_insert_data(changes, "Annotation ", -1); + + a = xmlnode_new_child(annotations, "Annotation"); + n = xmlnode_new_child(a, "Name"); + xmlnode_insert_data(n, "AB.NickName", -1); + v = xmlnode_new_child(a, "Value"); + xmlnode_insert_data(v, value, -1); + break; + + default: + g_return_if_reached(); + } + + state = msn_callback_state_new(session); - state->body = xmlnode_from_str(body, -1); + + state->body = xmlnode_from_str(MSN_CONTACT_UPDATE_TEMPLATE, -1); state->action = MSN_UPDATE_INFO; state->post_action = MSN_CONTACT_UPDATE_SOAP_ACTION; state->post_url = MSN_ADDRESS_BOOK_POST_URL; state->cb = msn_update_contact_read_cb; - g_free(escaped_nickname); - g_free(body); + contact = xmlnode_get_child(state->body, "Body/ABContactUpdate/contacts/Contact"); + xmlnode_insert_child(contact, contact_info); + xmlnode_insert_child(contact, changes); + + if (!strcmp(passport, "Me")) { + xmlnode *contactType = xmlnode_new_child(contact_info, "contactType"); + xmlnode_insert_data(contactType, "Me", -1); + } else { + MsnUser *user = msn_userlist_find_user(session->userlist, passport); + xmlnode *contactId = xmlnode_new_child(contact, "contactId"); + msn_callback_state_set_uid(state, user->uid); + xmlnode_insert_data(contactId, state->uid, -1); + } + + msn_contact_request(state); } static void diff -r 5a6cf27ead31 -r 70de4e2246ec libpurple/protocols/msn/contact.h --- a/libpurple/protocols/msn/contact.h Sat Jun 07 06:39:13 2008 +0000 +++ b/libpurple/protocols/msn/contact.h Sat Jun 07 08:01:41 2008 +0000 @@ -331,7 +331,7 @@ "" -/* Update Contact Nickname */ +/* Update Contact Information */ #define MSN_CONTACT_UPDATE_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/ABContactUpdate" #define MSN_CONTACT_UPDATE_TEMPLATE ""\ "00000000-0000-0000-0000-000000000000"\ ""\ ""\ - ""\ - "Me"\ - "%s"\ - ""\ - "DisplayName"\ + ""\ ""\ ""\ ""\ @@ -618,6 +614,13 @@ MSN_PS_BLOCK_UNBLOCK } MsnSoapPartnerScenario; +typedef enum +{ + MSN_UPDATE_DISPLAY, /* Real display name */ + MSN_UPDATE_ALIAS, /* Aliased display name */ + MSN_UPDATE_COMMENT +} MsnContactUpdateType; + /************************************************ * function prototype ************************************************/ @@ -644,7 +647,7 @@ const char * update, const char * gupdate); /* contact SOAP operations */ -void msn_update_contact(MsnSession *session, const char* nickname); +void msn_update_contact(MsnSession *session, const char *passport, MsnContactUpdateType type, const char* value); void msn_add_contact(MsnSession *session, MsnCallbackState *state, const char *passport); diff -r 5a6cf27ead31 -r 70de4e2246ec libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Sat Jun 07 06:39:13 2008 +0000 +++ b/libpurple/protocols/msn/msn.c Sat Jun 07 08:01:41 2008 +0000 @@ -1581,6 +1581,15 @@ } } +static void msn_alias_buddy(PurpleConnection *pc, const char *name, const char *alias) +{ + MsnSession *session; + + session = pc->proto_data; + + msn_update_contact(session, name, MSN_UPDATE_ALIAS, alias); +} + static void msn_group_buddy(PurpleConnection *gc, const char *who, const char *old_group_name, const char *new_group_name) @@ -2418,7 +2427,7 @@ NULL, /* register_user */ NULL, /* get_cb_info */ NULL, /* get_cb_away */ - NULL, /* alias_buddy */ + msn_alias_buddy, /* alias_buddy */ msn_group_buddy, /* group_buddy */ msn_rename_group, /* rename_group */ NULL, /* buddy_free */ diff -r 5a6cf27ead31 -r 70de4e2246ec libpurple/protocols/msn/notification.c --- a/libpurple/protocols/msn/notification.c Sat Jun 07 06:39:13 2008 +0000 +++ b/libpurple/protocols/msn/notification.c Sat Jun 07 08:01:41 2008 +0000 @@ -1284,7 +1284,7 @@ if (!strcmp(type, "MFN")) { friendlyname = purple_url_decode(cmd->params[2]); - msn_update_contact(session, friendlyname); + msn_update_contact(session, "Me", MSN_UPDATE_DISPLAY, friendlyname); purple_connection_set_display_name( purple_account_get_connection(session->account),