From f7445cf674c2ce4e262a11c200ccaeba8393f362 Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Tue, 11 Sep 2012 19:03:29 +0300 Subject: [PATCH] notify: process deletedGroup elements in roaming contacts Those are sent only for empty groups, i.e. takes care of sending buddy removal events before sending this element. Refactored some common group cleanup code for this. Introduced new backend API sipe_backend_buddy_group_remove() to support deleting of groups. Supplied a functional implementation for purple and dummy stubs for miranda & telepathy. --- src/api/sipe-backend.h | 13 ++++++++++++- src/core/sipe-core.c | 11 +++-------- src/core/sipe-group.c | 24 ++++++++++++++++++++---- src/core/sipe-group.h | 6 ++++++ src/core/sipe-notify.c | 27 ++++++++++++++++++--------- src/miranda/miranda-buddy.c | 6 ++++++ src/purple/purple-buddy.c | 8 ++++++++ src/telepathy/telepathy-buddy.c | 12 ++++++++++++ 8 files changed, 85 insertions(+), 22 deletions(-) diff --git a/src/api/sipe-backend.h b/src/api/sipe-backend.h index 40b6f974..20bd588f 100644 --- a/src/api/sipe-backend.h +++ b/src/api/sipe-backend.h @@ -912,7 +912,7 @@ const gchar *sipe_backend_buddy_get_photo_hash(struct sipe_core_public *sipe_pub * the group will not be added. * * @param sipe_public The handle representing the protocol instance making the call - * @param group The group being added + * @param group_name The group being added * @return TRUE if everything is ok, FALSE if the group should not be added */ gboolean sipe_backend_buddy_group_add(struct sipe_core_public *sipe_public, @@ -931,6 +931,17 @@ gboolean sipe_backend_buddy_group_rename(struct sipe_core_public *sipe_public, const gchar *new_name); /** + * Called when a new internal group should be deleted + * + * NOTE: this will only be called on empty groups. + * + * @param sipe_public The handle representing the protocol instance making the call + * @param group_name The group that should be removed + */ +void sipe_backend_buddy_group_remove(struct sipe_core_public *sipe_public, + const gchar *group_name); + +/** * Present requested buddy information to the user */ struct sipe_backend_buddy_info; diff --git a/src/core/sipe-core.c b/src/core/sipe-core.c index 35ee3e85..5aa25572 100644 --- a/src/core/sipe-core.c +++ b/src/core/sipe-core.c @@ -417,15 +417,10 @@ void sipe_core_deallocate(struct sipe_core_public *sipe_public) sipe_subscriptions_destroy(sipe_private); if (sipe_private->groups) { - GSList *entry = sipe_private->groups; - while (entry) { - struct sipe_group *group = entry->data; - g_free(group->name); - g_free(group); - entry = entry->next; - } + GSList *entry; + while ((entry = sipe_private->groups) != NULL) + sipe_group_free(sipe_private, entry->data); } - g_slist_free(sipe_private->groups); if (sipe_private->our_publication_keys) { GSList *entry = sipe_private->our_publication_keys; diff --git a/src/core/sipe-group.c b/src/core/sipe-group.c index 0589dc9e..09b51120 100755 --- a/src/core/sipe-group.c +++ b/src/core/sipe-group.c @@ -207,6 +207,25 @@ sipe_group_add(struct sipe_core_private *sipe_private, } } +void sipe_group_free(struct sipe_core_private *sipe_private, + struct sipe_group *group) +{ + sipe_private->groups = g_slist_remove(sipe_private->groups, + group); + g_free(group->name); + g_free(group); +} + +void sipe_group_remove(struct sipe_core_private *sipe_private, + struct sipe_group *group) +{ + if (group) { + SIPE_DEBUG_INFO("removing group %s (id %d)", group->name, group->id); + sipe_backend_buddy_group_remove(SIPE_CORE_PUBLIC, group->name); + sipe_group_free(sipe_private, group); + } +} + void sipe_core_group_rename(struct sipe_core_public *sipe_public, const gchar *old_name, @@ -252,10 +271,7 @@ sipe_core_group_remove(struct sipe_core_public *sipe_public, request); g_free(request); - sipe_private->groups = g_slist_remove(sipe_private->groups, - s_group); - g_free(s_group->name); - g_free(s_group); + sipe_group_free(sipe_private, s_group); } else { SIPE_DEBUG_INFO("Cannot find group %s to delete", name); } diff --git a/src/core/sipe-group.h b/src/core/sipe-group.h index 8616bc21..7cb6baf5 100644 --- a/src/core/sipe-group.h +++ b/src/core/sipe-group.h @@ -43,4 +43,10 @@ gboolean sipe_group_rename(struct sipe_core_private *sipe_private, void sipe_group_add(struct sipe_core_private *sipe_private, struct sipe_group * group); +/* remove group from core and free the data structure */ +void sipe_group_free(struct sipe_core_private *sipe_private, + struct sipe_group *group); +/* remove group from core & backend */ +void sipe_group_remove(struct sipe_core_private *sipe_private, + struct sipe_group *group); diff --git a/src/core/sipe-notify.c b/src/core/sipe-notify.c index 25a4176e..8ef67d07 100644 --- a/src/core/sipe-notify.c +++ b/src/core/sipe-notify.c @@ -1269,15 +1269,6 @@ static gboolean sipe_process_roaming_contacts(struct sipe_core_private *sipe_pri } } - /* @TODO: Process deleted groups - * - * - */ - for (group_node = sipe_xml_child(isc, "deletedGroup"); group_node; group_node = sipe_xml_twin(group_node)) { - const gchar *id = sipe_xml_attribute(group_node, "id"); - SIPE_DEBUG_INFO("Delete group ID %s - NOT IMPLEMENTED", id); - } - /* @TODO: Process new buddies * * @@ -1408,6 +1399,24 @@ static gboolean sipe_process_roaming_contacts(struct sipe_core_private *sipe_pri sipe_buddy_remove(sipe_private, buddy); } } + + /* Process deleted groups + * + * NOTE: all buddies will already have been removed from the + * group prior to this. The log shows that OCS actually + * sends two separate updates when you delete a group: + * + * - first one with "modifiedContact" removing buddies + * from the group, leaving it empty, and + * + * - then one with "deletedGroup" removing the group + */ + for (group_node = sipe_xml_child(isc, "deletedGroup"); group_node; group_node = sipe_xml_twin(group_node)) + sipe_group_remove(sipe_private, + sipe_group_find_by_id(sipe_private, + (int)g_ascii_strtod(sipe_xml_attribute(group_node, "id"), + NULL))); + } sipe_xml_free(isc); diff --git a/src/miranda/miranda-buddy.c b/src/miranda/miranda-buddy.c index 8a00eeba..619046e2 100644 --- a/src/miranda/miranda-buddy.c +++ b/src/miranda/miranda-buddy.c @@ -519,6 +519,12 @@ gboolean sipe_backend_buddy_group_rename(SIPE_UNUSED_PARAMETER struct sipe_core_ return(FALSE); } +void sipe_backend_buddy_group_remove(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public, + SIPE_UNUSED_PARAMETER const gchar *group_name) +{ + /* @TODO */ +} + struct sipe_backend_buddy_info *sipe_backend_buddy_info_start(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public) { return((struct sipe_backend_buddy_info *)g_hash_table_new_full(NULL,NULL,NULL,g_free)); diff --git a/src/purple/purple-buddy.c b/src/purple/purple-buddy.c index 55895820..7653d4ec 100644 --- a/src/purple/purple-buddy.c +++ b/src/purple/purple-buddy.c @@ -342,6 +342,14 @@ gboolean sipe_backend_buddy_group_rename(SIPE_UNUSED_PARAMETER struct sipe_core_ return(purple_group != NULL); } +void sipe_backend_buddy_group_remove(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public, + const gchar *group_name) +{ + PurpleGroup *purple_group = purple_find_group(group_name); + if (purple_group) + purple_blist_remove_group(purple_group); +} + struct sipe_backend_buddy_info *sipe_backend_buddy_info_start(SIPE_UNUSED_PARAMETER struct sipe_core_public *sipe_public) { return((struct sipe_backend_buddy_info *)purple_notify_user_info_new()); diff --git a/src/telepathy/telepathy-buddy.c b/src/telepathy/telepathy-buddy.c index f357a43c..28777995 100644 --- a/src/telepathy/telepathy-buddy.c +++ b/src/telepathy/telepathy-buddy.c @@ -589,6 +589,18 @@ gboolean sipe_backend_buddy_group_add(struct sipe_core_public *sipe_public, return(group != NULL); } +void sipe_backend_buddy_group_remove(struct sipe_core_public *sipe_public, + const gchar *group_name) +{ + struct sipe_backend_private *telepathy_private = sipe_public->backend_private; + SipeContactList *contact_list = telepathy_private->contact_list; + + g_hash_table_remove(contact_list->groups, group_name); + + if (contact_list->initial_received) { + /* @TODO: emit signal? */ + } +} /* Local Variables: -- 2.11.4.GIT