/soc/2012/tomkiewicz/gg: 02ee2834030c: Gadu-Gadu: servers histor...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Wed Aug 15 08:59:03 EDT 2012


Changeset: 02ee2834030c0592226e5828589f18692f9ed630
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-08-15 14:58 +0200
Branch:	 soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/02ee2834030c

Description:

Gadu-Gadu: servers history feature

diffstat:

 libpurple/protocols/gg/Makefile.am |   2 +
 libpurple/protocols/gg/gg.c        |  43 ++++++++++++++++---
 libpurple/protocols/gg/servconn.c  |  67 +++++++++++++++++++++++++++++++
 libpurple/protocols/gg/servconn.h  |  13 ++++++
 libpurple/protocols/gg/utils.c     |  82 ++++++++++++++++++++++++++++++++++++++
 libpurple/protocols/gg/utils.h     |  12 +++++
 6 files changed, 211 insertions(+), 8 deletions(-)

diffs (truncated from 324 to 300 lines):

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
@@ -86,6 +86,8 @@ GGSOURCES = \
 	multilogon.h \
 	status.c \
 	status.h \
+	servconn.c \
+	servconn.h \
 	oauth/oauth.c \
 	oauth/oauth.h \
 	oauth/oauth-parameter.c \
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
@@ -50,6 +50,7 @@
 #include "libgadu-events.h"
 #include "multilogon.h"
 #include "status.h"
+#include "servconn.h"
 
 /* Prototypes */
 
@@ -1200,7 +1201,12 @@ static void ggp_async_login_handler(gpoi
 			break;
 		case GG_EVENT_CONN_SUCCESS:
 			{
-				purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS\n");
+				const gchar * server_ip = ggp_ipv4_to_str(
+					info->session->server_addr);
+				purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS:"
+					" successfully connected to %s\n",
+					server_ip);
+				ggp_servconn_add_server(server_ip);
 				purple_input_remove(info->inpa);
 				info->inpa = purple_input_add(info->session->fd,
 							  PURPLE_INPUT_READ,
@@ -1591,7 +1597,7 @@ static void ggp_close(PurpleConnection *
 				status_msg ? GG_STATUS_NOT_AVAIL_DESCR : GG_STATUS_NOT_AVAIL,
 				status_msg))
 			{
-				struct gg_event *ev;
+				/*struct gg_event *ev;
 				guint64 wait_start = ggp_microtime(), now;
 				int sleep_time = 5000;
 				while ((ev = gg_watch_fd(info->session)) != NULL)
@@ -1603,7 +1609,8 @@ static void ggp_close(PurpleConnection *
 						break;
 					usleep(sleep_time);
 					sleep_time *= 2;
-				}
+				}*/
+				usleep(100000);
 			}
 			gg_logoff(info->session);
 			gg_free_session(info->session);
@@ -2074,6 +2081,9 @@ static PurplePluginProtocolInfo prpl_inf
 	NULL				/* get_public_alias */
 };
 
+static gboolean ggp_load(PurplePlugin *plugin);
+static gboolean ggp_unload(PurplePlugin *plugin);
+
 static PurplePluginInfo info = {
 	PURPLE_PLUGIN_MAGIC,			/* magic */
 	PURPLE_MAJOR_VERSION,			/* major_version */
@@ -2093,8 +2103,8 @@ static PurplePluginInfo info = {
 	"boler at sourceforge.net",		/* author */
 	PURPLE_WEBSITE,				/* homepage */
 
-	NULL,					/* load */
-	NULL,					/* unload */
+	ggp_load,				/* load */
+	ggp_unload,				/* unload */
 	NULL,					/* destroy */
 
 	NULL,					/* ui_info */
@@ -2132,18 +2142,20 @@ static void purple_gg_debug_handler(int 
 	g_free(msg);
 }
 
+static PurpleAccountOption *ggp_server_option;
+
 static void init_plugin(PurplePlugin *plugin)
 {
 	PurpleAccountOption *option;
 	GList *encryption_options = NULL;
 
-	purple_debug_info("gg", "Loading Gadu-Gadu protocol plugin with "
-		"libgadu %s...\n", gg_libgadu_version());
+	purple_prefs_add_none("/plugins/prpl/gg");
 
 	option = purple_account_option_string_new(_("GG server"),
 			"gg_server", "");
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 			option);
+	ggp_server_option = option;
 
 #define ADD_VALUE(list, desc, v) { \
 	PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1); \
@@ -2168,8 +2180,23 @@ static void init_plugin(PurplePlugin *pl
 		option);
 
 	gg_debug_handler = purple_gg_debug_handler;
+}
+
+static gboolean ggp_load(PurplePlugin *plugin)
+{
+	purple_debug_info("gg", "Loading Gadu-Gadu protocol plugin with "
+		"libgadu %s...\n", gg_libgadu_version());
+
+	ggp_resolver_purple_setup();
+	ggp_servconn_setup(ggp_server_option);
 	
-	ggp_resolver_purple_setup();
+	return TRUE;
+}
+
+static gboolean ggp_unload(PurplePlugin *plugin)
+{
+	ggp_servconn_cleanup();
+	return TRUE;
 }
 
 PURPLE_INIT_PLUGIN(gg, init_plugin, info);
diff --git a/libpurple/protocols/gg/servconn.c b/libpurple/protocols/gg/servconn.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/servconn.c
@@ -0,0 +1,67 @@
+#include "servconn.h"
+
+#include "utils.h"
+
+#include <debug.h>
+
+#define GGP_SERVCONN_HISTORY_PREF "/plugins/prpl/gg/server_history"
+#define GGP_SERVCONN_HISTORY_MAXLEN 15
+
+typedef struct
+{
+	GList *server_history;
+	PurpleAccountOption *server_option;
+} ggp_servconn_global_data;
+
+static ggp_servconn_global_data global_data;
+
+void ggp_servconn_setup(PurpleAccountOption *server_option)
+{
+	purple_prefs_add_string(GGP_SERVCONN_HISTORY_PREF, "");
+	
+	global_data.server_option = server_option;
+	global_data.server_history = ggp_strsplit_list(purple_prefs_get_string(
+		GGP_SERVCONN_HISTORY_PREF), ";", GGP_SERVCONN_HISTORY_MAXLEN + 1);
+	global_data.server_history = ggp_list_truncate(
+		global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN,
+		g_free);
+	
+	purple_account_option_string_set_hints(global_data.server_option,
+		ggp_servconn_get_servers());
+}
+
+void ggp_servconn_cleanup(void)
+{
+	g_list_free_full(global_data.server_history, &g_free);
+}
+
+void ggp_servconn_add_server(const gchar *server)
+{
+	GList *old_entry;
+	
+	old_entry = g_list_find_custom(global_data.server_history, server,
+		(GCompareFunc)g_strcmp0);
+	if (old_entry)
+	{
+		g_free(old_entry->data);
+		global_data.server_history = g_list_delete_link(
+			global_data.server_history, old_entry);
+	}
+	
+	global_data.server_history = g_list_prepend(global_data.server_history,
+		g_strdup(server));
+	global_data.server_history = ggp_list_truncate(
+		global_data.server_history, GGP_SERVCONN_HISTORY_MAXLEN,
+		g_free);
+
+	purple_prefs_set_string(GGP_SERVCONN_HISTORY_PREF, ggp_strjoin_list(";",
+		global_data.server_history));
+	purple_account_option_string_set_hints(global_data.server_option,
+		ggp_servconn_get_servers());
+}
+
+GSList * ggp_servconn_get_servers(void)
+{
+	return ggp_list_copy_to_slist_deep(global_data.server_history,
+		(GCopyFunc)g_strdup, NULL);
+}
diff --git a/libpurple/protocols/gg/servconn.h b/libpurple/protocols/gg/servconn.h
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/servconn.h
@@ -0,0 +1,13 @@
+#ifndef _GGP_SERVCONN_H
+#define _GGP_SERVCONN_H
+
+#include <internal.h>
+#include <accountopt.h>
+
+void ggp_servconn_setup(PurpleAccountOption *server_option);
+void ggp_servconn_cleanup(void);
+
+void ggp_servconn_add_server(const gchar *server);
+GSList * ggp_servconn_get_servers(void);
+
+#endif /* _GGP_SERVCONN_H */
diff --git a/libpurple/protocols/gg/utils.c b/libpurple/protocols/gg/utils.c
--- a/libpurple/protocols/gg/utils.c
+++ b/libpurple/protocols/gg/utils.c
@@ -127,3 +127,85 @@ gchar * ggp_utf8_strndup(const gchar *st
 	
 	return g_strndup(str, raw_len);
 }
+
+GSList * ggp_list_copy_to_slist_deep(GList *list, GCopyFunc func,
+	gpointer user_data)
+{
+	GSList *new_list = NULL;
+	GList *it;
+	
+	it = g_list_first(list);
+	while (it)
+	{
+		new_list = g_slist_append(new_list, func(it->data, user_data));
+		it = g_list_next(it);
+	}
+	return new_list;
+}
+
+GList * ggp_strsplit_list(const gchar *string, const gchar *delimiter,
+	gint max_tokens)
+{
+	gchar **splitted, **it;
+	GList *list = NULL;
+	
+	it = splitted = g_strsplit(string, delimiter, max_tokens);
+	while (*it)
+	{
+		list = g_list_append(list, *it);
+		it++;
+	}
+	g_free(splitted);
+	
+	return list;
+}
+
+gchar * ggp_strjoin_list(const gchar *separator, GList *list)
+{
+	gchar **str_array;
+	gchar *joined;
+	gint list_len, i;
+	GList *it;
+	
+	list_len = g_list_length(list);
+	str_array = g_new(gchar*, list_len + 1);
+	
+	it = g_list_first(list);
+	i = 0;
+	while (it)
+	{
+		str_array[i++] = it->data;
+		it = g_list_next(it);
+	}
+	str_array[i] = NULL;
+	
+	joined = g_strjoinv(separator, str_array);
+	g_free(str_array);
+	
+	return joined;
+}
+
+const gchar * ggp_ipv4_to_str(uint32_t raw_ip)
+{
+	static gchar buff[INET_ADDRSTRLEN];
+	buff[0] = '\0';
+	
+	g_snprintf(buff, sizeof(buff), "%d.%d.%d.%d",
+		((raw_ip >>  0) & 0xFF),
+		((raw_ip >>  8) & 0xFF),
+		((raw_ip >> 16) & 0xFF),
+		((raw_ip >> 24) & 0xFF));
+	
+	return buff;
+}
+
+GList * ggp_list_truncate(GList *list, gint length, GDestroyNotify free_func)
+{
+	while (g_list_length(list) > length)
+	{
+		GList *last = g_list_last(list);
+		free_func(last->data);



More information about the Commits mailing list