changeset 19794:5568b3ac6fce

[gaim-migrate @ 17481] gradually got SOAP contact list and address book from Server. Cache the info in blist.xml committer: Ethan Blanton <elb@pidgin.im>
author Ma Yuan <mayuan2006@gmail.com>
date Sat, 14 Oct 2006 20:00:56 +0000
parents 2b36697b05ea
children 6fc33ac621d9
files src/protocols/msn/contact.c src/protocols/msn/contact.h src/protocols/msn/notification.c src/protocols/msn/session.c src/protocols/msn/session.h src/protocols/msn/user.c src/protocols/msn/user.h src/protocols/msn/userlist.c src/protocols/msn/userlist.h
diffstat 9 files changed, 206 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/msn/contact.c	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/contact.c	Sat Oct 14 20:00:56 2006 +0000
@@ -85,7 +85,7 @@
 	g_return_if_fail(session != NULL);
 
 	/*login ok!We can retrieve the contact list*/
-//	msn_get_contact_list(contact);
+//	msn_get_contact_list(contact,NULL);
 }
 
 /*get MSN member role utility*/
@@ -126,38 +126,45 @@
 	MsnSession * session;
 	int list_op =0;
 	char * passport;
-	xmlnode * node,*body,*response,*result,*services,*service,*memberships;
+	xmlnode * node,*body,*response,*result,*services;
+	xmlnode *service,*memberships;
 	xmlnode *LastChangeNode;
 	xmlnode *membershipnode,*members,*member,*passportNode;
-	char *lastchange;
+	char *LastChangeStr;
 
 	session = contact->session;
-	gaim_debug_misc("xml","parse contact list:{%s}\nsize:%d\n",contact->soapconn->body,contact->soapconn->body_len);
+	gaim_debug_misc("MSNCL","parse contact list:{%s}\nsize:%d\n",contact->soapconn->body,contact->soapconn->body_len);
 	node = 	xmlnode_from_str(contact->soapconn->body, contact->soapconn->body_len);
 
 	if(node == NULL){
-		gaim_debug_misc("xml","parse contact from str err!\n");
+		gaim_debug_misc("MSNCL","parse contact from str err!\n");
 		return;
 	}
-	gaim_debug_misc("xml","node{%p},name:%s,child:%s,last:%s\n",node,node->name,node->child->name,node->lastchild->name);
+	gaim_debug_misc("MSNCL","node{%p},name:%s,child:%s,last:%s\n",node,node->name,node->child->name,node->lastchild->name);
 	body = xmlnode_get_child(node,"Body");
-	gaim_debug_misc("xml","body{%p},name:%s\n",body,body->name);
+	gaim_debug_misc("MSNCL","body{%p},name:%s\n",body,body->name);
 	response = xmlnode_get_child(body,"FindMembershipResponse");
-	gaim_debug_misc("xml","response{%p},name:%s\n",response,response->name);
+	gaim_debug_misc("MSNCL","response{%p},name:%s\n",response,response->name);
 	result =xmlnode_get_child(response,"FindMembershipResult");
-	gaim_debug_misc("xml","result{%p},name:%s\n",result,result->name);
+	if(result == NULL){
+		gaim_debug_misc("MSNCL","receive No Update!\n");
+		return;
+	}
+	gaim_debug_misc("MSNCL","result{%p},name:%s\n",result,result->name);
 	services =xmlnode_get_child(result,"Services");
-	gaim_debug_misc("xml","services{%p},name:%s\n",services,services->name);
+	gaim_debug_misc("MSNCL","services{%p},name:%s\n",services,services->name);
 	service =xmlnode_get_child(services,"Service");
-	gaim_debug_misc("xml","service{%p},name:%s\n",service,service->name);
+	gaim_debug_misc("MSNCL","service{%p},name:%s\n",service,service->name);
 	
 	/*Last Change Node*/
 	LastChangeNode = xmlnode_get_child(service,"LastChange");
-	lastchange = xmlnode_get_data(LastChangeNode);
-	gaim_debug_misc("MSNContact","LastChangeNode %s\n",lastchange);
+	LastChangeStr = xmlnode_get_data(LastChangeNode);
+	gaim_debug_misc("MSNCL","LastChangeNode0 %s\n",LastChangeStr);	
+	gaim_blist_node_set_string(msn_session_get_bnode(contact->session),"CLLastChange",LastChangeStr);
+	gaim_debug_misc("MSNCL","LastChangeNode %s\n",LastChangeStr);
 	
 	memberships =xmlnode_get_child(service,"Memberships");
-	gaim_debug_misc("xml","memberships{%p},name:%s\n",memberships,memberships->name);
+	gaim_debug_misc("MSNCL","memberships{%p},name:%s\n",memberships,memberships->name);
 	for(membershipnode = xmlnode_get_child(memberships, "Membership"); membershipnode;
 					membershipnode = xmlnode_get_next_twin(membershipnode)){
 		xmlnode *roleNode;
@@ -165,7 +172,7 @@
 		roleNode = xmlnode_get_child(membershipnode,"MemberRole");
 		role=xmlnode_get_data(roleNode);
 		list_op = msn_get_memberrole(role);
-		gaim_debug_misc("memberrole","role:%s,list_op:%d\n",role,list_op);
+		gaim_debug_misc("MSNCL","MemberRole role:%s,list_op:%d\n",role,list_op);
 		g_free(role);
 		members = xmlnode_get_child(membershipnode,"Members");
 		for(member = xmlnode_get_child(members, "Member"); member;
@@ -174,13 +181,13 @@
 			xmlnode * typeNode;
 			char * type;
 
-			gaim_debug_misc("MaYuan","type:%s\n",xmlnode_get_attrib(member,"type"));
+			gaim_debug_misc("MSNCL","type:%s\n",xmlnode_get_attrib(member,"type"));
 			if(!g_strcasecmp(xmlnode_get_attrib(member,"type"),"PassportMember")){
 				passportNode = xmlnode_get_child(member,"PassportName");
 				passport = xmlnode_get_data(passportNode);
 				typeNode = xmlnode_get_child(member,"Type");
 				type = xmlnode_get_data(typeNode);
-				gaim_debug_misc("Passport","name:%s,type:%s\n",passport,type);
+				gaim_debug_misc("MSNCL","Passport name:%s,type:%s\n",passport,type);
 				g_free(type);
 
 				user = msn_userlist_find_add_user(session->userlist,passport,NULL);
@@ -194,7 +201,7 @@
 
 				emailNode = xmlnode_get_child(member,"Email");
 				passport = xmlnode_get_data(emailNode);
-				gaim_debug_info("Email","name:%s,list_op:%d\n",passport,list_op);
+				gaim_debug_info("MSNCL","Email Member :name:%s,list_op:%d\n",passport,list_op);
 				user = msn_userlist_find_add_user(session->userlist,passport,NULL);
 				msn_got_lst_user(session,user,list_op,NULL);
 				g_free(passport);
@@ -211,6 +218,8 @@
 	MsnSoapConn * soapconn = data;	
 	MsnContact *contact;
 	MsnSession *session;
+	const char * abLastChange;
+	const char * dynamicItemLastChange;
 
 	contact = soapconn->parent;
 	g_return_if_fail(contact != NULL);
@@ -224,7 +233,9 @@
 	/*free the read buffer*/
 	msn_soap_free_read_buf(soapconn);
 
-	msn_get_address_book(contact);
+	abLastChange = gaim_blist_node_get_string(msn_session_get_bnode(contact->session),"ablastChange");
+	dynamicItemLastChange = gaim_blist_node_get_string(msn_session_get_bnode(contact->session),"dynamicItemLastChange");
+	msn_get_address_book(contact,abLastChange,dynamicItemLastChange);
 }
 
 static void
@@ -237,18 +248,30 @@
 //	msn_soap_read_cb(data,source,cond);
 }
 
+/*SOAP  get contact list*/
 void
-msn_get_contact_list(MsnContact * contact)
+msn_get_contact_list(MsnContact * contact,char * update_time)
 {
 	MsnSoapReq *soap_request;
-
+	char *body = NULL;
+	char * update_str;
+	
 	gaim_debug_info("MaYuan","Getting Contact List...\n");
+	if(update_time != NULL){
+		gaim_debug_info("MSNCL","last update time:{%s}\n",update_time);
+		update_str = g_strdup_printf(MSN_GET_CONTACT_UPDATE_XML,update_time);
+	}else{
+		update_str = g_strdup("");
+	}
+	body = g_strdup_printf(MSN_GET_CONTACT_TEMPLATE,update_str);
 	soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
 					MSN_GET_CONTACT_POST_URL,MSN_GET_CONTACT_SOAP_ACTION,
-					MSN_GET_CONTACT_TEMPLATE,
+					body,
 					msn_get_contact_list_cb,
 					msn_get_contact_written_cb);
 	msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init);
+	g_free(update_str);
+	g_free(body);
 }
 
 static void
@@ -258,8 +281,7 @@
 	xmlnode * node,*body,*response,*result;
 	xmlnode *groups,*group,*groupname,*groupId,*groupInfo;
 	xmlnode	*contacts,*contactNode,*contactId,*contactInfo,*contactType,*passportName,*displayName,*groupIds,*guid;
-	xmlnode *abNode,*LastChangeNode;
-	char *lastchange;
+	xmlnode *abNode;
 	char *group_name,*group_id;
 
 	session = contact->session;
@@ -276,6 +298,10 @@
 	response = xmlnode_get_child(body,"ABFindAllResponse");
 	gaim_debug_misc("xml","response{%p},name:%s\n",response,response->name);
 	result =xmlnode_get_child(response,"ABFindAllResult");
+	if(result == NULL){
+		gaim_debug_misc("MSNAB","receive no address book update\n");
+		return;
+	}
 	gaim_debug_misc("xml","result{%p},name:%s\n",result,result->name);
 
 	/*Process Group List*/
@@ -298,6 +324,7 @@
 		gaim_debug_misc("MsnAB","group_id:%s name:%s\n",group_id,group_name);
 		if ((gaim_find_group(group_name)) == NULL){
 			GaimGroup *g = gaim_group_new(group_name);
+			gaim_blist_node_set_string(&(g->node),"groupId",group_id);
 			gaim_blist_add_group(g, NULL);
 		}
 		g_free(group_id);
@@ -437,9 +464,18 @@
 
 	abNode =xmlnode_get_child(result,"ab");
 	if(abNode != NULL){
+		xmlnode *LastChangeNode, *DynamicItemLastChangedNode;
+		char *lastchange, *dynamicChange;
+
 		LastChangeNode = xmlnode_get_child(abNode,"lastChange");
 		lastchange = xmlnode_get_data(LastChangeNode);
 		gaim_debug_info("MsnAB"," lastchanged Time:{%s}\n",lastchange);
+		gaim_blist_node_set_string(msn_session_get_bnode(contact->session),"ablastChange",lastchange);
+		
+		DynamicItemLastChangedNode = xmlnode_get_child(abNode,"DynamicItemLastChanged");
+		dynamicChange = xmlnode_get_data(DynamicItemLastChangedNode);
+		gaim_debug_info("MsnAB"," DynamicItemLastChanged :{%s}\n",dynamicChange);
+		gaim_blist_node_set_string(msn_session_get_bnode(contact->session),"DynamicItemLastChanged",lastchange);
 	}
 
 	xmlnode_free(node);
@@ -481,18 +517,36 @@
 
 /*get the address book*/
 void
-msn_get_address_book(MsnContact *contact)
+msn_get_address_book(MsnContact *contact,char * LastChanged, char * dynamicItemLastChange)
 {
 	MsnSoapReq *soap_request;
+	char *body = NULL;
+	char *ab_update_str,*update_str;
 
 	gaim_debug_info("MaYuan","msn_get_address_book()...\n");
 	/*build SOAP and POST it*/
+	if(LastChanged != NULL){
+		ab_update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML,LastChanged);
+	}else{
+		ab_update_str = g_strdup("");
+	}
+	if(dynamicItemLastChange != NULL){
+		update_str = g_strdup_printf(MSN_GET_ADDRESS_UPDATE_XML,
+								ab_update_str,dynamicItemLastChange);
+	}else{
+		update_str = g_strdup(ab_update_str);
+	}
+	g_free(ab_update_str);
+	
+	body = g_strdup_printf(MSN_GET_ADDRESS_TEMPLATE,update_str);
 	soap_request = msn_soap_request_new(MSN_CONTACT_SERVER,
 					MSN_ADDRESS_BOOK_POST_URL,MSN_GET_ADDRESS_SOAP_ACTION,
-					MSN_GET_ADDRESS_TEMPLATE,
+					body,
 					msn_get_address_cb,
 					msn_address_written_cb);
 	msn_soap_post(contact->soapconn,soap_request,msn_contact_connect_init);
+	g_free(update_str);
+	g_free(body);
 }
 
 static void
--- a/src/protocols/msn/contact.h	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/contact.h	Sat Oct 14 20:00:56 2006 +0000
@@ -30,6 +30,9 @@
 /*get contact list soap request template*/
 #define MSN_GET_CONTACT_POST_URL	"/abservice/SharingService.asmx"
 #define MSN_GET_CONTACT_SOAP_ACTION "http://www.msn.com/webservices/AddressBook/FindMembership"
+#define MSN_GET_CONTACT_UPDATE_XML "<View>Full</View>"\
+	"<deltasOnly>true</deltasOnly>"\
+	"<lastChange>%s</lastChange>"
 #define MSN_GET_CONTACT_TEMPLATE	"<?xml version='1.0' encoding='utf-8'?>"\
 "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
 	"<soap:Header xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
@@ -53,6 +56,7 @@
 				"<ServiceType xmlns=\"http://www.msn.com/webservices/AddressBook\">Profile</ServiceType>"\
 			"</Types>"\
 			"</serviceFilter>"\
+			"%s"\
 		"</FindMembership>"\
 	"</soap:Body>"\
 "</soap:Envelope>"
@@ -63,6 +67,15 @@
 #define MSN_ADDRESS_BOOK_POST_URL	"/abservice/abservice.asmx"
 /*get addressbook soap request template*/
 #define MSN_GET_ADDRESS_SOAP_ACTION	"http://www.msn.com/webservices/AddressBook/ABFindAll"
+#define MSN_GET_ADDRESS_FULL_TIME "0001-01-01T00:00:00.0000000-08:00"
+#define MSN_GET_ADDRESS_UPDATE_XML "<deltasOnly>true</deltasOnly>"\
+	"<lastChange>%s</lastChange>"
+
+#define MSN_GET_GLEAM_UPDATE_XML \
+	"%s"\
+	"<dynamicItemView>Gleam</dynamicItemView>"\
+	"<dynamicItemLastChange>%s</dynamicItemLastChange>"
+
 #define MSN_GET_ADDRESS_TEMPLATE	"<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
 "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"\
 	"<soap:Header>"\
@@ -79,6 +92,7 @@
 		"<ABFindAll xmlns=\"http://www.msn.com/webservices/AddressBook\">"\
 			"<abId>00000000-0000-0000-0000-000000000000</abId>"\
 			"<abView>Full</abView>"\
+			"%s"\
 		"</ABFindAll>"\
 	"</soap:Body>"\
 "</soap:Envelope>"
@@ -199,8 +213,8 @@
 void msn_contact_destroy(MsnContact *contact);
 
 void msn_contact_connect(MsnContact *contact);
-void msn_get_contact_list(MsnContact * contact);
-void msn_get_address_book(MsnContact *contact);
+void msn_get_contact_list(MsnContact * contact,char * update);
+void msn_get_address_book(MsnContact *contact,char * update, char * gupdate);
 
 /*contact SOAP Operation*/
 void msn_add_contact(MsnContact *contact,const char *passport,const char *groupId);
--- a/src/protocols/msn/notification.c	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/notification.c	Sat Oct 14 20:00:56 2006 +0000
@@ -1450,6 +1450,7 @@
 {
 	MsnSession *session;
 	const char *value;
+	const char *clLastChange;
 
 	gaim_debug_info("MaYuan","profile_msg... \n");
 	session = cmdproc->session;
@@ -1495,8 +1496,12 @@
 		session->passport_info.sl = atol(value);
 
 	/*starting retrieve the contact list*/
+	msn_userlist_load(session);
+	
+	msn_session_set_bnode(session);
 	session->contact = msn_contact_new(session);
-	msn_get_contact_list(session->contact);
+	clLastChange = gaim_blist_node_get_string(msn_session_get_bnode(session),"CLLastChange");
+	msn_get_contact_list(session->contact,clLastChange);
 //	msn_contact_connect(session->contact);
 }
 
--- a/src/protocols/msn/session.c	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/session.c	Sat Oct 14 20:00:56 2006 +0000
@@ -42,7 +42,8 @@
 
 	session->user = msn_user_new(session->userlist,
 								 gaim_account_get_username(account), NULL);
-
+	session->bnode = NULL;
+	
 	/*if you want to chat with Yahoo Messenger*/
 	//session->protocol_ver = WLM_YAHOO_PROT_VER;
 	session->protocol_ver = WLM_PROT_VER;
@@ -260,6 +261,47 @@
 	return swboard;
 }
 
+/*setup the bnode, for MSN SOAP contact/address book op*/
+void 
+msn_session_set_bnode(MsnSession *session)
+{
+	GaimBlistNode *gnode, *cnode, *bnode;
+	GaimConnection *gc = gaim_account_get_connection(session->account);
+
+	g_return_if_fail(gc != NULL);
+
+	for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next){
+		if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
+			continue;
+		for(cnode = gnode->child; cnode; cnode = cnode->next) {
+			if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
+				continue;
+			for(bnode = cnode->child; bnode; bnode = bnode->next) {
+				GaimBuddy *b;
+				if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
+					continue;
+				b = (GaimBuddy *)bnode;
+				if(b->account == gc->account){
+					session->bnode = bnode;
+					return;
+				}
+			}
+		}
+	}
+	session->bnode = NULL;
+}
+
+/*get bnode*/
+GaimBlistNode *
+msn_session_get_bnode(MsnSession *session)
+{
+#if 1
+	return session->bnode;
+#else
+	return gaim_get_blist()->root;
+#endif
+}
+
 static void
 msn_session_sync_users(MsnSession *session)
 {
--- a/src/protocols/msn/session.h	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/session.h	Sat Oct 14 20:00:56 2006 +0000
@@ -111,7 +111,10 @@
 
 	/*psm info*/
 	char *psm;
-
+	
+	/*first blist contact node*/
+	GaimBlistNode *bnode;
+	
 	struct
 	{
 		/*t and p, get via USR TWN*/
--- a/src/protocols/msn/user.c	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/user.c	Sat Oct 14 20:00:56 2006 +0000
@@ -186,6 +186,13 @@
 }
 
 void
+msn_user_set_op(MsnUser *user,int list_op)
+{
+	g_return_if_fail(list_op != NULL);
+	user->list_op |= list_op;
+}
+
+void
 msn_user_set_buddy_icon(MsnUser *user, const char *filename)
 {
 	struct stat st;
@@ -295,14 +302,13 @@
 	}
 
 	b = gaim_find_buddy_in_group(account, passport, g);
-
 	if (b == NULL){
 		b = gaim_buddy_new(account, passport, NULL);
-
 		gaim_blist_add_buddy(b, NULL, g, NULL);
 	}
-
 	b->proto_data = user;
+	/*Update the blist Node info*/
+//	gaim_blist_node_set_string(&(b->node), "", "");
 }
 
 /*check if the msn user is online*/
--- a/src/protocols/msn/user.h	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/user.h	Sat Oct 14 20:00:56 2006 +0000
@@ -306,6 +306,10 @@
  */
 gboolean
 msn_user_is_yahoo(GaimAccount *account ,const char *name);
+
+void msn_user_set_op(MsnUser *user,int list_op);
+
 /*@}*/
 
+
 #endif /* _MSN_USER_H_ */
--- a/src/protocols/msn/userlist.c	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/userlist.c	Sat Oct 14 20:00:56 2006 +0000
@@ -718,3 +718,46 @@
 	msn_userlist_rem_buddy(userlist, who, MSN_LIST_FL, old_group_name);
 }
 
+/*load userlist from the Blist file cache*/
+void
+msn_userlist_load(MsnSession *session)
+{
+	GaimBlistNode *gnode, *cnode, *bnode;
+	GaimConnection *gc = gaim_account_get_connection(session->account);
+	GSList *l;
+	MsnUser * user;
+
+	g_return_if_fail(gc != NULL);
+
+	for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next){
+		if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
+			continue;
+		for(cnode = gnode->child; cnode; cnode = cnode->next) {
+			if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
+				continue;
+			for(bnode = cnode->child; bnode; bnode = bnode->next) {
+				GaimBuddy *b;
+				if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
+					continue;
+				b = (GaimBuddy *)bnode;
+				if(b->account == gc->account){
+					user = msn_userlist_find_add_user(session->userlist,
+						b->name,NULL);
+					msn_user_set_op(user,MSN_LIST_FL_OP);
+				}
+			}
+		}
+	}
+	for (l = session->account->permit; l != NULL; l = l->next) {
+		user = msn_userlist_find_add_user(session->userlist,
+						(char *)l->data,NULL);
+		msn_user_set_op(user,MSN_LIST_AL_OP);
+	}
+	for (l = session->account->deny; l != NULL; l = l->next) {
+		user = msn_userlist_find_add_user(session->userlist,
+						(char *)l->data,NULL);
+		msn_user_set_op(user,MSN_LIST_BL_OP);
+	}
+	
+}
+
--- a/src/protocols/msn/userlist.h	Sat Sep 16 18:27:25 2006 +0000
+++ b/src/protocols/msn/userlist.h	Sat Oct 14 20:00:56 2006 +0000
@@ -103,5 +103,6 @@
 void msn_userlist_move_buddy(MsnUserList *userlist, const char *who,
 							 const char *old_group_name,
 							 const char *new_group_name);
+void msn_userlist_load(MsnSession *session);
 
 #endif /* _MSN_USERLIST_H_ */