/soc/2012/tomkiewicz/gg: f0ac6497f256: Gadu-Gadu: roster - fix s...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Fri Jul 13 04:13:07 EDT 2012


Changeset: f0ac6497f256575efa5e885a876510a498e061c7
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-07-13 10:12 +0200
Branch:	 soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/f0ac6497f256

Description:

Gadu-Gadu: roster - fix synchronization for multiple gg accounts

diffstat:

 libpurple/protocols/gg/purplew.c |    2 +-
 libpurple/protocols/gg/roster.c  |  172 +++++++++++++++++++++-----------------
 libpurple/protocols/gg/roster.h  |    2 +
 3 files changed, 100 insertions(+), 76 deletions(-)

diffs (truncated from 481 to 300 lines):

diff --git a/libpurple/protocols/gg/purplew.c b/libpurple/protocols/gg/purplew.c
--- a/libpurple/protocols/gg/purplew.c
+++ b/libpurple/protocols/gg/purplew.c
@@ -57,7 +57,7 @@
 PurpleGroup * ggp_purplew_buddy_get_group_only(PurpleBuddy *buddy)
 {
 	PurpleGroup *group = purple_buddy_get_group(buddy);
-	if (!group)
+	if (!group) // TODO: get contact's group
 		return NULL;
 	if (0 == strcmp(_("Buddies"), purple_group_get_name(group)))
 		return NULL;
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
@@ -8,11 +8,10 @@
 #include <debug.h>
 
 #define GGP_ROSTER_SYNC_SETT "gg-synchronized"
-#define GGP_ROSTER_ID_SETT "gg-id"
 #define GGP_ROSTER_DEBUG 0
 #define GGP_ROSTER_GROUPID_DEFAULT "00000000-0000-0000-0000-000000000000"
 
-// TODO: check what happens, if feature is disabled
+// TODO: ggp_purplew_buddy_get_group_only
 
 typedef struct
 {
@@ -31,6 +30,18 @@
 	 * Value: (xmlnode*) xml node for group
 	 */
 	GHashTable *group_nodes;
+	
+	/**
+	 * Key: (gchar*) group name
+	 * Value: (gchar*) group id
+	 */
+	GHashTable *group_ids;
+
+	/**
+	 * Key: (gchar*) group id
+	 * Value: (gchar*) group name
+	 */
+	GHashTable *group_names; //TODO: wywalic? tylko zapamietujmy grupe "Pomocnicy" (dla botow)
 
 	gboolean needs_update;
 } ggp_roster_content;
@@ -46,7 +57,11 @@
 	union
 	{
 		uin_t uin;
-		gchar *group_name;
+		struct
+		{
+			gchar *old_name;
+			gchar *new_name;
+		} group_rename;
 	} data;
 } ggp_roster_change;
 
@@ -98,6 +113,7 @@
 	rdata->sent_updates = NULL;
 	rdata->pending_updates = NULL;
 	rdata->timer = 0;
+	rdata->is_updating = FALSE;
 	
 	if (ggp_roster_enabled())
 		rdata->timer = purple_timeout_add_seconds(2, ggp_roster_timer_cb, gc);
@@ -124,6 +140,10 @@
 		g_hash_table_destroy(content->contact_nodes);
 	if (content->group_nodes)
 		g_hash_table_destroy(content->group_nodes);
+	if (content->group_ids)
+		g_hash_table_destroy(content->group_ids);
+	if (content->group_names)
+		g_hash_table_destroy(content->group_names);
 	g_free(content);
 }
 
@@ -132,7 +152,10 @@
 	ggp_roster_change *change = _change;
 	
 	if (change->type == GGP_ROSTER_CHANGE_GROUP_RENAME)
-		g_free(change->data.group_name);
+	{
+		g_free(change->data.group_rename.old_name);
+		g_free(change->data.group_rename.new_name);
+	}
 	
 	g_free(change);
 }
@@ -146,7 +169,7 @@
 	purple_blist_node_set_bool(PURPLE_BLIST_NODE(buddy), GGP_ROSTER_SYNC_SETT, synchronized);
 	if (!synchronized)
 	{
-		change = g_new(ggp_roster_change, 1);
+		change = g_new0(ggp_roster_change, 1);
 		change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE;
 		change->data.uin = uin;
 		rdata->pending_updates = g_list_append(rdata->pending_updates, change);
@@ -273,13 +296,11 @@
 		rdata->version = version;
 }
 
-static gboolean ggp_roster_reply_list_read_group(xmlnode *node, ggp_roster_content *content, GHashTable *groups, GHashTable *remove_groups)
+static gboolean ggp_roster_reply_list_read_group(xmlnode *node, ggp_roster_content *content)
 {
 	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);
@@ -299,28 +320,14 @@
 		return TRUE;
 	}
 	
-	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);
-	
 	g_hash_table_insert(content->group_nodes, g_strdup(id), node);
-	g_hash_table_insert(groups, id, name);
+	g_hash_table_insert(content->group_ids, g_strdup(name), g_strdup(id));
+	g_hash_table_insert(content->group_names, id, name);
 	
 	return TRUE;
 }
 
-static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc, xmlnode *node, ggp_roster_content *content, GHashTable *groups, GHashTable *remove_buddies)
+static gboolean ggp_roster_reply_list_read_buddy(PurpleConnection *gc, xmlnode *node, ggp_roster_content *content, GHashTable *remove_buddies)
 {
 	gchar *alias, *group_name;
 	uin_t uin;
@@ -359,13 +366,14 @@
 	while (group_elem != NULL)
 	{
 		gchar *id;
-		gboolean isbot;
+		gboolean isbot, isdefault;
 		
 		if (!ggp_xml_get_string(group_elem, NULL, &id))
 			continue;
-		group_name = g_hash_table_lookup(groups, id);
+		group_name = g_hash_table_lookup(content->group_names, id);
 		isbot = (strcmp(id, "0b345af6-0001-0000-0000-000000000004") == 0 ||
 			g_strcmp0(group_name, "Pomocnicy") == 0);
+		isdefault = (0 == g_strcmp0(group_name, _("Buddies")));
 		g_free(id);
 		
 		// we don't want to import bots;
@@ -375,6 +383,8 @@
 			g_free(alias);
 			return TRUE;
 		}
+		if (isdefault)
+			group_name = NULL;
 		
 		if (group_name != NULL)
 			break;
@@ -396,7 +406,7 @@
 	g_hash_table_remove(remove_buddies, GINT_TO_POINTER(uin));
 	if (!buddy)
 	{
-		purple_debug_info("gg", "ggp_roster_reply_list: adding %u to buddy list\n", uin);
+		purple_debug_info("gg", "ggp_roster_reply_list: adding %u (%s) to buddy list\n", uin, alias);
 		buddy = purple_buddy_new(account, ggp_uin_to_str(uin), alias);
 		purple_blist_add_buddy(buddy, NULL, group, NULL);
 		ggp_roster_set_synchronized(gc, buddy, TRUE);
@@ -408,7 +418,7 @@
 	// buddy exists, but is not synchronized - local list has priority
 	if (!ggp_roster_is_synchronized(buddy))
 	{
-		purple_debug_info("gg", "ggp_roster_reply_list: ignoring not synchronized %s\n", purple_buddy_get_name(buddy));
+		purple_debug_misc("gg", "ggp_roster_reply_list: ignoring not synchronized %s\n", purple_buddy_get_name(buddy));
 		g_free(alias);
 		return TRUE;
 	}
@@ -436,14 +446,14 @@
 {
 	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
 	xmlnode *xml, *curr_elem;
-	GHashTable *groups;
 	PurpleAccount *account;
 	GSList *buddies;
-	GHashTable *remove_buddies, *remove_groups;
-	GList *remove_buddies_list, *remove_buddies_it, *map_values, *it;
+	GHashTable *remove_buddies;//, *remove_groups;
+	GList *remove_buddies_list, *remove_buddies_it;//, *map_values, *it;
+	//GList *map_values, *it; TODO
 	GList *update_buddies = NULL, *update_buddies_it;
 	ggp_roster_content *content;
-	PurpleBlistNode *bnode;
+	//PurpleBlistNode *bnode;
 
 	g_return_if_fail(gc != NULL);
 	g_return_if_fail(data != NULL);
@@ -461,46 +471,30 @@
 
 	ggp_roster_content_free(rdata->content);
 	rdata->content = NULL;
+	rdata->is_updating = TRUE;
 	content = g_new0(ggp_roster_content, 1);
 	content->xml = xml;
 	content->contact_nodes = g_hash_table_new(NULL, NULL);
 	content->group_nodes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+	content->group_ids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+	content->group_names = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 
 #if GGP_ROSTER_DEBUG
 	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, remove_groups))
+		if (!ggp_roster_reply_list_read_group(curr_elem, content))
 		{
-			g_hash_table_destroy(groups);
 			ggp_roster_content_free(content);
 			g_return_if_reached();
 		}
@@ -534,9 +528,7 @@
 	content->contacts_node = xmlnode_get_child(xml, "Contacts");
 	if (content->contacts_node == NULL)
 	{
-		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();
@@ -544,11 +536,9 @@
 	curr_elem = xmlnode_get_child(content->contacts_node, "Contact");
 	while (curr_elem != NULL)
 	{
-		if (!ggp_roster_reply_list_read_buddy(gc, curr_elem, content, groups, remove_buddies))
+		if (!ggp_roster_reply_list_read_buddy(gc, curr_elem, content, remove_buddies))
 		{
-			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();
@@ -557,8 +547,6 @@
 		curr_elem = xmlnode_get_next_twin(curr_elem);
 	}
 	
-	g_hash_table_destroy(groups);
-	
 	// removing buddies, which are not present in roster
 	remove_buddies_list = g_hash_table_get_values(remove_buddies);
 	remove_buddies_it = g_list_first(remove_buddies_list);
@@ -575,6 +563,7 @@
 	g_list_free(remove_buddies_list);
 	g_hash_table_destroy(remove_buddies);
 	
+	/* TODO: remove groups, which are empty, but had contacts before synchronization
 	// removing groups, which are:
 	// - not present in roster



More information about the Commits mailing list