changeset 24463:4fd22591e3f0

Send FQY as the first thing when adding a buddy so that we know what network they use. Should be helpful for adding federated buddies. References #6755.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sun, 07 Dec 2008 07:09:57 +0000
parents 2b4c909b40c4
children 3915331092b2
files libpurple/protocols/msn/contact.c libpurple/protocols/msn/msn.c libpurple/protocols/msn/notification.c libpurple/protocols/msn/user.c libpurple/protocols/msn/user.h libpurple/protocols/msn/userlist.c libpurple/protocols/msn/userlist.h
diffstat 7 files changed, 133 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/contact.c	Sun Dec 07 07:04:23 2008 +0000
+++ b/libpurple/protocols/msn/contact.c	Sun Dec 07 07:09:57 2008 +0000
@@ -981,8 +981,6 @@
 		msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
 	}
 
-	msn_notification_send_fqy(session, state->who);
-
 	user = msn_userlist_find_add_user(userlist, state->who, state->who);
 	msn_user_add_group_id(user, state->guid);
 
@@ -1072,7 +1070,6 @@
 			msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_AL);
 			msn_userlist_add_buddy_to_list(userlist, state->who, MSN_LIST_FL);
 		}
-		msn_notification_send_fqy(state->session, state->who);
 
 		if (msn_userlist_user_is_in_list(user, MSN_LIST_PL)) {
 			msn_del_contact_from_list(state->session, NULL, state->who, MSN_LIST_PL);
--- a/libpurple/protocols/msn/msn.c	Sun Dec 07 07:04:23 2008 +0000
+++ b/libpurple/protocols/msn/msn.c	Sun Dec 07 07:09:57 2008 +0000
@@ -1457,7 +1457,15 @@
 	/* XXX - Would group ever be NULL here?  I don't think so...
 	 * shx: Yes it should; MSN handles non-grouped buddies, and this is only
 	 * internal. */
-	msn_userlist_add_buddy(userlist, who, group ? group->name : NULL);
+	if (msn_userlist_find_user(userlist, who) != NULL) {
+		/* We already know this buddy. This function takes care of users
+		   already in the list and stuff... */
+		msn_userlist_add_buddy(userlist, who, group ? group->name : NULL);
+	} else {
+		/* We need to check the network for this buddy first */
+		msn_userlist_save_pending_buddy(userlist, who, group ? group->name : NULL);
+		msn_notification_send_fqy(session, who);
+	}
 }
 
 static void
--- a/libpurple/protocols/msn/notification.c	Sun Dec 07 07:04:23 2008 +0000
+++ b/libpurple/protocols/msn/notification.c	Sun Dec 07 07:09:57 2008 +0000
@@ -849,10 +849,35 @@
 fqy_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload,
 			 size_t len)
 {
-	purple_debug_info("msn", "FQY payload:\n%s\n", payload);
-	g_return_if_fail(cmdproc->session != NULL);
-/*	msn_notification_post_adl(cmdproc, payload, len); */
-/*	msn_get_address_book(cmdproc->session, MSN_AB_SAVE_CONTACT, NULL, NULL); */
+	MsnUserList *userlist;
+	xmlnode *ml, *d, *c;
+	const char *domain;
+	const char *local;
+	const char *type;
+	char *passport;
+	MsnNetwork network = MSN_NETWORK_PASSPORT;
+
+	userlist = cmdproc->session->userlist;
+
+	/* FQY response:
+	    <ml><d n="domain.com"><c n="local-node" t="network" /></d></ml> */
+	ml = xmlnode_from_str(payload, len);
+	d = xmlnode_get_child(ml, "d");
+	c = xmlnode_get_child(d, "c");
+	domain = xmlnode_get_attrib(d, "n");
+	local = xmlnode_get_attrib(c, "n");
+	type = xmlnode_get_attrib(c, "t");
+
+	passport = g_strdup_printf("%s@%s", local, domain);
+
+	if (type != NULL)
+		network = (MsnNetwork)strtoul(type, NULL, 10);
+	purple_debug_info("msn", "FQY response says %s is from network %d\n",
+	                  passport, network);
+	msn_userlist_add_pending_buddy(userlist, passport, network);
+
+	g_free(passport);
+	xmlnode_free(ml);
 }
 
 static void
--- a/libpurple/protocols/msn/user.c	Sun Dec 07 07:04:23 2008 +0000
+++ b/libpurple/protocols/msn/user.c	Sun Dec 07 07:09:57 2008 +0000
@@ -340,6 +340,20 @@
 }
 
 void
+msn_user_set_pending_group(MsnUser *user, const char *group)
+{
+	user->pending_group = g_strdup(group);
+}
+
+char *
+msn_user_remove_pending_group(MsnUser *user)
+{
+	char *group = user->pending_group;
+	user->pending_group = NULL;
+	return group;
+}
+
+void
 msn_user_set_home_phone(MsnUser *user, const char *number)
 {
 	g_return_if_fail(user != NULL);
--- a/libpurple/protocols/msn/user.h	Sun Dec 07 07:04:23 2008 +0000
+++ b/libpurple/protocols/msn/user.h	Sun Dec 07 07:09:57 2008 +0000
@@ -91,6 +91,7 @@
 	gboolean mobile;        /**< Signed up with MSN Mobile.     */
 
 	GList *group_ids;       /**< The group IDs.                 */
+	char *pending_group;    /**< A pending group to add.        */
 
 	MsnObject *msnobj;      /**< The user's MSN Object.         */
 
@@ -213,6 +214,23 @@
 void msn_user_remove_group_id(MsnUser *user, const char * id);
 
 /**
+ * Sets the pending group for a user.
+ *
+ * @param user  The user.
+ * @param group The group name.
+ */
+void msn_user_set_pending_group(MsnUser *user, const char *group);
+
+/**
+ * Removes the pending group from a user.
+ *
+ * @param user The user.
+ *
+ * @return Returns the pending group name.
+ */
+char *msn_user_remove_pending_group(MsnUser *user);
+
+/**
  * Sets the home phone number for a user.
  *
  * @param user   The user.
--- a/libpurple/protocols/msn/userlist.c	Sun Dec 07 07:04:23 2008 +0000
+++ b/libpurple/protocols/msn/userlist.c	Sun Dec 07 07:09:57 2008 +0000
@@ -756,6 +756,62 @@
 	msn_add_contact_to_group(userlist->session, state, who, group_id);
 }
 
+/*
+ * Save a buddy address/group until we get back response from FQY
+ */
+void
+msn_userlist_save_pending_buddy(MsnUserList *userlist,
+                               const char *who,
+                               const char *group_name)
+{
+	MsnUser *user;
+
+	g_return_if_fail(userlist != NULL);
+
+	user = msn_user_new(userlist, who, NULL);
+	msn_user_set_pending_group(user, group_name);
+	msn_user_set_network(user, MSN_NETWORK_UNKNOWN);
+	userlist->pending = g_list_prepend(userlist->pending, user);
+}
+
+/*
+ * Actually adds a buddy once we have the response from FQY
+ */
+void
+msn_userlist_add_pending_buddy(MsnUserList *userlist,
+                               const char *who,
+                               /*MsnNetwork*/ int network)
+{
+	MsnUser *user = NULL;
+	GList *l;
+	char *group;
+
+	for (l = userlist->pending; l != NULL; l = l->next)
+	{
+		user = (MsnUser *)l->data;
+
+		if (!g_strcasecmp(who, user->passport)) {
+			userlist->pending = g_list_delete_link(userlist->pending, l);
+			break;
+		}
+	}
+
+	if (user == NULL) {
+		purple_debug_error("msn", "Attempting to add a pending user that does not exist.\n");
+		return;
+	}
+
+	/* Bit of a hack, but by adding to userlist now, the rest of the code
+	 * will know what network to use.
+	 */
+	msn_user_set_network(user, network);
+	msn_userlist_add_user(userlist, user);
+
+	group = msn_user_remove_pending_group(user);
+	msn_userlist_add_buddy(userlist, who, group);
+	g_free(group);
+}
+
 void
 msn_userlist_add_buddy_to_list(MsnUserList *userlist, const char *who,
 							MsnListId list_id)
--- a/libpurple/protocols/msn/userlist.h	Sun Dec 07 07:04:23 2008 +0000
+++ b/libpurple/protocols/msn/userlist.h	Sun Dec 07 07:09:57 2008 +0000
@@ -47,6 +47,7 @@
 
 	GList *users; /* Contains MsnUsers */
 	GList *groups; /* Contains MsnGroups */
+	GList *pending; /* MsnUsers pending addition (waiting for FQY response) */
 
 	GQueue *buddy_icon_requests;
 	int buddy_icon_window;
@@ -93,6 +94,12 @@
 void msn_userlist_rem_buddy(MsnUserList *userlist, const char *who);
 void msn_userlist_add_buddy(MsnUserList *userlist,
 			    const char *who, const char *group_name);
+void msn_userlist_save_pending_buddy(MsnUserList *userlist,
+                                     const char *who,
+                                     const char *group_name);
+void msn_userlist_add_pending_buddy(MsnUserList *userlist,
+                                    const char *who,
+                                    /*MsnNetwork*/ int network);
 void msn_userlist_move_buddy(MsnUserList *userlist, const char *who,
 						    const char *old_group_name,
 						    const char *new_group_name);