/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