/soc/2012/tomkiewicz/gg: 57013b9e1a8e: Gadu-Gadu: roster - downl...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Mon Jul 9 15:21:39 EDT 2012
Changeset: 57013b9e1a8e44cda2d00de413bdb160858d070c
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-07-09 21:21 +0200
Branch: soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/57013b9e1a8e
Description:
Gadu-Gadu: roster - downloading
diffstat:
configure.ac | 13 +
libpurple/protocols/gg/Makefile.am | 10 +-
libpurple/protocols/gg/gg.c | 17 +-
libpurple/protocols/gg/gg.h | 2 +
libpurple/protocols/gg/lib/config.h | 2 +-
libpurple/protocols/gg/roster.c | 325 ++++++++++++++++++++++++++++++++++++
libpurple/protocols/gg/roster.h | 19 ++
libpurple/protocols/gg/xml.c | 58 ++++++
libpurple/protocols/gg/xml.h | 11 +
9 files changed, 450 insertions(+), 7 deletions(-)
diffs (truncated from 568 to 300 lines):
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -765,6 +765,19 @@
AC_SUBST(LIBXML_LIBS)
dnl #######################################################################
+dnl # Check for zlib (required)
+dnl #######################################################################
+
+PKG_CHECK_MODULES(ZLIB, [zlib >= 1.2.0], , [
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([
+You must have zlib >= 1.2.0 development headers installed to build.
+])])
+
+AC_SUBST(ZLIB_CFLAGS)
+AC_SUBST(ZLIB_LIBS)
+
+dnl #######################################################################
dnl # GConf schemas
dnl #######################################################################
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -1,3 +1,5 @@
+V=0
+
pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
EXTRA_DIST = \
@@ -35,8 +37,10 @@
lib/sha1.c
INTGG_CFLAGS = -I$(top_srcdir)/libpurple/protocols/gg/lib \
+ $(ZLIB_CFLAGS) \
-DGG_IGNORE_DEPRECATED \
-DGG_INTERNAL_LIBGADU_VERSION=$(GADU_LIBGADU_VERSION)
+GADU_LIBS += $(ZLIB_LIBS)
endif
if USE_GNUTLS
@@ -71,7 +75,11 @@
avatar.h \
avatar.c \
libgadu-events.h \
- libgadu-events.c
+ libgadu-events.c \
+ roster.c \
+ roster.h \
+ xml.c \
+ xml.h
AM_CFLAGS = $(st)
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
@@ -65,11 +65,9 @@
static void ggp_action_buddylist_get(PurplePluginAction *action)
{
PurpleConnection *gc = (PurpleConnection *)action->context;
- GGPInfo *info = purple_connection_get_protocol_data(gc);
-
- purple_debug_info("gg", "Downloading...\n");
-
- gg_userlist_request(info->session, GG_USERLIST_GET, NULL);
+ // TODO: just for debugging
+ // we will drop this action when roster will be ready
+ ggp_roster_update(gc);
}
/**
@@ -1197,6 +1195,13 @@
case GG_EVENT_USER_DATA:
ggp_events_user_data(gc, &ev->event.user_data);
break;
+ case GG_EVENT_USERLIST100_VERSION:
+ purple_debug_info("gg", "GG_EVENT_USERLIST100_VERSION: %u\n",
+ ev->event.userlist100_version.version);
+ break;
+ case GG_EVENT_USERLIST100_REPLY:
+ ggp_roster_reply(gc, &ev->event.userlist100_reply);
+ break;
default:
purple_debug_error("gg",
"unsupported event type=%d\n", ev->type);
@@ -1568,6 +1573,7 @@
ggp_image_setup(gc);
ggp_avatar_setup(gc);
+ ggp_roster_setup(gc);
glp->uin = ggp_str_to_uin(purple_account_get_username(account));
glp->password = ggp_convert_to_cp1250(purple_account_get_password(account));
@@ -1683,6 +1689,7 @@
ggp_search_destroy(info->searches);
ggp_image_cleanup(gc);
ggp_avatar_cleanup(gc);
+ ggp_roster_cleanup(gc);
if (info->inpa > 0)
purple_input_remove(info->inpa);
diff --git a/libpurple/protocols/gg/gg.h b/libpurple/protocols/gg/gg.h
--- a/libpurple/protocols/gg/gg.h
+++ b/libpurple/protocols/gg/gg.h
@@ -32,6 +32,7 @@
#include "image.h"
#include "avatar.h"
#include "account.h"
+#include "roster.h"
#define PUBDIR_RESULTS_MAX 20
@@ -57,6 +58,7 @@
ggp_image_connection_data image_data;
ggp_avatar_session_data avatar_data;
+ ggp_roster_session_data roster_data;
} GGPInfo;
#endif /* _PURPLE_GG_H */
diff --git a/libpurple/protocols/gg/lib/config.h b/libpurple/protocols/gg/lib/config.h
--- a/libpurple/protocols/gg/lib/config.h
+++ b/libpurple/protocols/gg/lib/config.h
@@ -58,7 +58,7 @@
#undef GG_CONFIG_HAVE_OPENSSL
/* Defined if libgadu was compiled and linked with zlib support. */
-#undef GG_CONFIG_HAVE_ZLIB
+#define GG_CONFIG_HAVE_ZLIB
/* Defined if uintX_t types are defined in <stdint.h>. */
#undef GG_CONFIG_HAVE_STDINT_H
diff --git a/libpurple/protocols/gg/roster.c b/libpurple/protocols/gg/roster.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/roster.c
@@ -0,0 +1,325 @@
+#include "roster.h"
+
+#include "gg.h"
+#include "xml.h"
+#include "utils.h"
+
+#include <debug.h>
+
+#define GGP_ROSTER_SYNC_SETT "gg-synchronized"
+#define GGP_ROSTER_DEBUG 1
+
+static void ggp_roster_set_synchronized(PurpleBuddy *buddy, gboolean synchronized);
+static gboolean ggp_roster_is_synchronized(PurpleBuddy *buddy);
+
+static void ggp_roster_reply_list(PurpleConnection *gc, uint32_t version, const char *reply);
+
+#if GGP_ROSTER_DEBUG
+static void ggp_roster_dump(PurpleConnection *gc);
+#endif
+
+/********/
+
+static inline ggp_roster_session_data *
+ggp_roster_get_rdata(PurpleConnection *gc)
+{
+ GGPInfo *accdata = purple_connection_get_protocol_data(gc);
+ return &accdata->roster_data;
+}
+
+void ggp_roster_setup(PurpleConnection *gc)
+{
+ ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
+
+ rdata->xml = NULL;
+ rdata->version = 0;
+}
+
+void ggp_roster_cleanup(PurpleConnection *gc)
+{
+ ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
+
+ if (rdata->xml)
+ xmlnode_free(rdata->xml);
+}
+
+static void ggp_roster_set_synchronized(PurpleBuddy *buddy, gboolean synchronized)
+{
+ purple_blist_node_set_bool((PurpleBlistNode*)buddy, GGP_ROSTER_SYNC_SETT, synchronized);
+}
+
+static gboolean ggp_roster_is_synchronized(PurpleBuddy *buddy)
+{
+ return purple_blist_node_get_bool((PurpleBlistNode*)buddy, GGP_ROSTER_SYNC_SETT);
+}
+
+void ggp_roster_update(PurpleConnection *gc)
+{
+ GGPInfo *accdata = purple_connection_get_protocol_data(gc);
+
+ purple_debug_info("gg", "ggp_roster_update\n");
+
+ if (!gg_libgadu_check_feature(GG_LIBGADU_FEATURE_USERLIST100))
+ {
+ purple_debug_error("gg", "ggp_roster_update - feature disabled\n");
+ return;
+ }
+
+ gg_userlist100_request(accdata->session, GG_USERLIST100_GET, 0, GG_USERLIST100_FORMAT_TYPE_GG100, NULL);
+}
+
+void ggp_roster_reply(PurpleConnection *gc, struct gg_event_userlist100_reply *reply)
+{
+ purple_debug_info("gg", "ggp_roster_reply [type=%d, version=%u, format_type=%d]\n",
+ reply->type, reply->version, reply->format_type);
+
+ if (reply->type != GG_USERLIST100_REPLY_LIST)
+ return;
+
+ if (GG_USERLIST100_FORMAT_TYPE_GG100 != reply->format_type)
+ {
+ purple_debug_warning("gg", "ggp_buddylist_load100_reply: unsupported format type (%u)\n", reply->format_type);
+ return;
+ }
+
+ ggp_roster_reply_list(gc, reply->version, reply->reply);
+}
+
+static void ggp_roster_reply_list(PurpleConnection *gc, uint32_t version, const char *data)
+{
+ ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
+ xmlnode *xml, *curr_list, *curr_elem;
+ GHashTable *groups;
+ PurpleAccount *account;
+ GSList *buddies;
+ GHashTable *remove_buddies;
+ GList *remove_buddies_list, *remove_buddies_it;
+
+ g_return_if_fail(gc != NULL);
+ g_return_if_fail(data != NULL);
+
+ account = purple_connection_get_account(gc);
+
+ xml = xmlnode_from_str(data, -1);
+ if (xml == NULL)
+ {
+ purple_debug_warning("gg", "ggp_roster_reply_list: invalid xml\n");
+ return;
+ }
+
+ if (rdata->xml)
+ xmlnode_free(rdata->xml);
+ rdata->xml = xml;
+
+#if GGP_ROSTER_DEBUG
+ ggp_roster_dump(gc);
+#endif
+
+ // reading groups
+
+ curr_list = xmlnode_get_child(xml, "Groups");
+ g_return_if_fail(curr_list != NULL);
+
+ groups = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ curr_elem = xmlnode_get_child(curr_list, "Group");
+ while (curr_elem != NULL)
+ {
+ char *name, *id;
+ gboolean removable;
+ gboolean succ = TRUE;
+
+ succ &= ggp_xml_get_string(curr_elem, "Id", &id);
+ succ &= ggp_xml_get_string(curr_elem, "Name", &name);
+ succ &= ggp_xml_get_bool(curr_elem, "IsRemovable", &removable);
+
+ if (!succ)
+ {
+ g_free(id);
+ g_free(name);
+ g_hash_table_destroy(groups);
+ g_return_if_reached();
+ }
+
+ if (removable)
+ {
+ g_hash_table_insert(groups, id, name);
+ purple_debug_misc("gg", "ggp_roster_reply_list: group %s [id=%s]\n", name, id);
+ }
+ else
+ {
+ g_free(id);
+ g_free(name);
+ }
+
+ curr_elem = xmlnode_get_next_twin(curr_elem);
+ }
+
+ // dumping current buddy list
+ // we will remove them, if not found in list at server
+
+ buddies = purple_find_buddies(account, NULL);
More information about the Commits
mailing list