/soc/2012/tomkiewicz/gg: 636bfc28f2cf: Gadu-Gadu: roster - final...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Thu Jul 12 16:02:13 EDT 2012


Changeset: 636bfc28f2cf3f2f3e1a304ff50339f2268efaaa
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-07-12 22:01 +0200
Branch:	 soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/636bfc28f2cf

Description:

Gadu-Gadu: roster - finally working

diffstat:

 libpurple/protocols/gg/gg.c     |    7 +-
 libpurple/protocols/gg/roster.c |  343 ++++++++++++++++++++++++++-------------
 libpurple/protocols/gg/roster.h |   10 +-
 3 files changed, 244 insertions(+), 116 deletions(-)

diffs (truncated from 629 to 300 lines):

diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -1227,7 +1227,7 @@
 				purple_connection_set_state(gc, PURPLE_CONNECTED);
 				
 				ggp_buddylist_send(gc);
-				ggp_roster_update(gc);
+				ggp_roster_request_update(gc);
 			}
 			break;
 		case GG_EVENT_CONN_FAILED:
@@ -1901,6 +1901,8 @@
 		
 		g_free(status_msg_gg);
 	}
+	
+	ggp_roster_add_buddy(gc, buddy, group, message);
 }
 
 static void ggp_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
@@ -1909,6 +1911,7 @@
 	GGPInfo *info = purple_connection_get_protocol_data(gc);
 
 	gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy)));
+	ggp_roster_remove_buddy(gc, buddy, group);
 }
 
 static void ggp_join_chat(PurpleConnection *gc, GHashTable *data)
@@ -2107,7 +2110,7 @@
 	NULL,				/* get_cb_info */
 	ggp_roster_alias_buddy,		/* alias_buddy */
 	ggp_roster_group_buddy,		/* group_buddy */
-	NULL,				/* rename_group */
+	ggp_roster_rename_group,	/* rename_group */
 	NULL,				/* buddy_free */
 	NULL,				/* convo_closed */
 	ggp_normalize,			/* normalize */
diff --git a/libpurple/protocols/gg/roster.c b/libpurple/protocols/gg/roster.c
--- a/libpurple/protocols/gg/roster.c
+++ b/libpurple/protocols/gg/roster.c
@@ -9,17 +9,10 @@
 
 #define GGP_ROSTER_SYNC_SETT "gg-synchronized"
 #define GGP_ROSTER_ID_SETT "gg-id"
-#define GGP_ROSTER_DEBUG 1
+#define GGP_ROSTER_DEBUG 0
 #define GGP_ROSTER_GROUPID_DEFAULT "00000000-0000-0000-0000-000000000000"
 
-/*
- TODO:
-
-- remove_group
-- group rename (both ways; rename_group)
-- buddy removal
-
-*/
+// TODO: check what happens, if feature is disabled
 
 typedef struct
 {
@@ -48,10 +41,12 @@
 	{
 		GGP_ROSTER_CHANGE_CONTACT_UPDATE,
 		GGP_ROSTER_CHANGE_CONTACT_REMOVE,
+		GGP_ROSTER_CHANGE_GROUP_RENAME,
 	} type;
 	union
 	{
 		uin_t uin;
+		gchar *group_name;
 	} data;
 } ggp_roster_change;
 
@@ -72,8 +67,6 @@
 static void ggp_roster_dump(ggp_roster_content *content);
 #endif
 
-static void ggp_roster_set_not_synchronized(PurpleConnection *gc, const char *who);
-
 /********/
 
 static inline ggp_roster_session_data *
@@ -121,6 +114,10 @@
 static void ggp_roster_change_free(gpointer _change)
 {
 	ggp_roster_change *change = _change;
+	
+	if (change->type == GGP_ROSTER_CHANGE_GROUP_RENAME)
+		g_free(change->data.group_name);
+	
 	g_free(change);
 }
 
@@ -157,16 +154,16 @@
 	return TRUE;
 }
 
-void ggp_roster_update(PurpleConnection *gc)
+void ggp_roster_request_update(PurpleConnection *gc)
 {
 	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
 	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
 	
-	purple_debug_info("gg", "ggp_roster_update [local: %u]\n", rdata->version);
+	purple_debug_info("gg", "ggp_roster_request_update: local=%u\n", rdata->version);
 	
 	if (!gg_libgadu_check_feature(GG_LIBGADU_FEATURE_USERLIST100))
 	{
-		purple_debug_error("gg", "ggp_roster_update - feature disabled\n");
+		purple_debug_error("gg", "ggp_roster_request_update: feature disabled\n");
 		return;
 	}
 	
@@ -175,9 +172,6 @@
 
 void ggp_roster_reply(PurpleConnection *gc, struct gg_event_userlist100_reply *reply)
 {
-	purple_debug_info("gg", "ggp_roster_reply [type=%x, version=%u, format_type=%x]\n",
-		reply->type, reply->version, reply->format_type);
-
 	if (GG_USERLIST100_FORMAT_TYPE_GG100 != reply->format_type)
 	{
 		purple_debug_warning("gg", "ggp_roster_reply: unsupported format type (%x)\n", reply->format_type);
@@ -202,10 +196,10 @@
 	int local_version = rdata->version;
 	int remote_version = version->version;
 
-	purple_debug_info("gg", "ggp_roster_version [local=%u, remote=%u]\n", local_version, remote_version);
+	purple_debug_info("gg", "ggp_roster_version: local=%u, remote=%u\n", local_version, remote_version);
 	
 	if (local_version < remote_version)
-		ggp_roster_update(gc);
+		ggp_roster_request_update(gc);
 }
 
 static void ggp_roster_reply_ack(PurpleConnection *gc, uint32_t version)
@@ -257,18 +251,19 @@
 		ggp_roster_content_free(rdata->content);
 		rdata->content = NULL;
 		// we have to wait for gg_event_userlist100_version
-		//ggp_roster_update(gc);
+		//ggp_roster_request_update(gc);
 	}
 	else
 		rdata->version = version;
 }
 
-static gboolean ggp_roster_reply_list_read_group(xmlnode *node, ggp_roster_content *content, GHashTable *groups)
+static gboolean ggp_roster_reply_list_read_group(xmlnode *node, ggp_roster_content *content, GHashTable *groups, GHashTable *remove_groups)
 {
 	char *name, *id;
 	gboolean removable;
 	gboolean succ = TRUE;
 	PurpleGroup *local_group;
+	const char *local_group_name;
 	
 	succ &= ggp_xml_get_string(node, "Id", &id);
 	succ &= ggp_xml_get_string(node, "Name", &name);
@@ -288,8 +283,18 @@
 		return TRUE;
 	}
 	
-	//TODO: group rename - first find by id and maybe rename local; if not found, do the following
-	local_group = purple_find_group(name);
+	local_group = g_hash_table_lookup(remove_groups, id);
+	g_hash_table_remove(remove_groups, id);
+	if (local_group)
+		local_group_name = purple_group_get_name(local_group);
+	if (local_group &&
+		0 != g_strcmp0(name, local_group_name))
+	{
+		purple_debug_info("gg", "ggp_roster_reply_list_read_group: rename group from %s to %s\n", local_group_name, name);
+		purple_blist_rename_group(local_group, name);
+	}
+	if (!local_group)
+		local_group = purple_find_group(name);
 	if (local_group)
 		purple_blist_node_set_string(PURPLE_BLIST_NODE(local_group), GGP_ROSTER_ID_SETT, id);
 	
@@ -303,7 +308,6 @@
 {
 	gchar *alias, *group_name;
 	uin_t uin;
-	gboolean isbot;
 	gboolean succ = TRUE;
 	xmlnode *group_list, *group_elem;
 	PurpleBuddy *buddy = NULL;
@@ -326,14 +330,6 @@
 	
 	g_hash_table_insert(content->contact_nodes, GINT_TO_POINTER(uin), node);
 	
-	// we don't want to import bots;
-	// they are inserted to roster by default
-	if (isbot)
-	{
-		g_free(alias);
-		return TRUE;
-	}
-	
 	// check, if alias is set
 	if (strlen(alias) == 0 ||
 		strcmp(alias, ggp_uin_to_str(uin)) == 0)
@@ -347,6 +343,8 @@
 	while (group_elem != NULL)
 	{
 		gchar *id;
+		gboolean isbot;
+		
 		if (!ggp_xml_get_string(group_elem, NULL, &id))
 			continue;
 		group_name = g_hash_table_lookup(groups, id);
@@ -354,8 +352,13 @@
 			g_strcmp0(group_name, "Pomocnicy") == 0);
 		g_free(id);
 		
+		// we don't want to import bots;
+		// they are inserted to roster by default
 		if (isbot)
-			break;
+		{
+			g_free(alias);
+			return TRUE;
+		}
 		
 		if (group_name != NULL)
 			break;
@@ -420,15 +423,18 @@
 	GHashTable *groups;
 	PurpleAccount *account;
 	GSList *buddies;
-	GHashTable *remove_buddies;
-	GList *remove_buddies_list, *remove_buddies_it;
+	GHashTable *remove_buddies, *remove_groups;
+	GList *remove_buddies_list, *remove_buddies_it, *map_values, *it;
 	GList *update_buddies = NULL, *update_buddies_it;
 	ggp_roster_content *content;
+	PurpleBlistNode *bnode;
 
 	g_return_if_fail(gc != NULL);
 	g_return_if_fail(data != NULL);
 
 	account = purple_connection_get_account(gc);
+	
+	purple_debug_info("gg", "ggp_roster_reply_list: got list (version=%u)\n", version);
 
 	xml = xmlnode_from_str(data, -1);
 	if (xml == NULL)
@@ -448,18 +454,35 @@
 	ggp_roster_dump(content);
 #endif
 
+	remove_groups = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+	// dumping local group list
+	for (bnode = purple_blist_get_root(); bnode != NULL; bnode = bnode->next)
+	{
+		PurpleGroup *group;
+		const char *id;
+		if (!PURPLE_BLIST_NODE_IS_GROUP(bnode))
+			continue;
+		group = (PurpleGroup*)bnode;
+		
+		id = purple_blist_node_get_string(bnode, GGP_ROSTER_ID_SETT);
+		if (!id)
+			continue;
+		g_hash_table_insert(remove_groups, g_strdup(id), group);
+	}
+
 	// reading groups
 	content->groups_node = xmlnode_get_child(xml, "Groups");
 	if (content->groups_node == NULL)
 	{
 		ggp_roster_content_free(content);
+		g_hash_table_destroy(remove_groups);
 		g_return_if_reached();
 	}
 	groups = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 	curr_elem = xmlnode_get_child(content->groups_node, "Group");
 	while (curr_elem != NULL)
 	{
-		if (!ggp_roster_reply_list_read_group(curr_elem, content, groups))
+		if (!ggp_roster_reply_list_read_group(curr_elem, content, groups, remove_groups))
 		{
 			g_hash_table_destroy(groups);
 			ggp_roster_content_free(content);
@@ -497,6 +520,7 @@
 	{
 		g_hash_table_destroy(groups);
 		g_hash_table_destroy(remove_buddies);
+		g_hash_table_destroy(remove_groups);
 		g_list_free(update_buddies);
 		ggp_roster_content_free(content);
 		g_return_if_reached();
@@ -508,6 +532,7 @@
 		{
 			g_hash_table_destroy(groups);
 			g_hash_table_destroy(remove_buddies);
+			g_hash_table_destroy(remove_groups);
 			g_list_free(update_buddies);
 			ggp_roster_content_free(content);



More information about the Commits mailing list