[geocode-glib] ipclient: Add IP Geocoding client
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geocode-glib] ipclient: Add IP Geocoding client
- Date: Tue, 12 Feb 2013 09:01:58 +0000 (UTC)
commit d889f52ac40b71a278da9b0049062929a8fd760b
Author: Satabdi Das <satabdidas gmail com>
Date: Wed Jan 30 19:44:33 2013 +0530
ipclient: Add IP Geocoding client
Add synchronous and asynchronous functions to talk to the server
geocode-glib/Makefile.am | 9 +-
geocode-glib/geocode-glib.symbols | 6 +
geocode-glib/geocode-ipclient.c | 217 +++++++++++++++++++++++++++++++++++++
geocode-glib/geocode-ipclient.h | 83 ++++++++++++++
geocode-glib/test-geoip.c | 103 ++++++++++++++++++
5 files changed, 415 insertions(+), 3 deletions(-)
---
diff --git a/geocode-glib/Makefile.am b/geocode-glib/Makefile.am
index 4630461..39d2e51 100644
--- a/geocode-glib/Makefile.am
+++ b/geocode-glib/Makefile.am
@@ -13,7 +13,8 @@ public_files = \
geocode-forward.c \
geocode-reverse.c \
geocode-glib.c \
- geocode-error.c
+ geocode-error.c \
+ geocode-ipclient.c
libgeocode_glib_la_SOURCES = \
$(public_files) \
@@ -33,7 +34,8 @@ gcglib_HEADERS = \
geocode-location.h \
geocode-forward.h \
geocode-reverse.h \
- geocode-error.h
+ geocode-error.h \
+ geocode-ipclient.h
AM_CFLAGS = -I$(top_srcdir) $(GEOCODE_CFLAGS) $(COMMON_CFLAGS) $(WARN_CFLAGS) $(DISABLE_DEPRECATED) -DTEST_SRCDIR=\""$(srcdir)/data/"\"
@@ -65,10 +67,11 @@ CLEANFILES += $(gir_DATA) $(typelib_DATA)
endif # HAVE_INTROSPECTION
-TEST_PROGS += test-gcglib
+TEST_PROGS += test-gcglib test-geoip
noinst_PROGRAMS = $(TEST_PROGS)
test_gcglib_LDADD = libgeocode-glib.la $(GEOCODE_LIBS)
+test_geoip_LDADD = libgeocode-glib.la $(GEOCODE_LIBS)
MAINTAINERCLEANFILES = Makefile.in
diff --git a/geocode-glib/geocode-glib.symbols b/geocode-glib/geocode-glib.symbols
index 513ca69..5245bf9 100644
--- a/geocode-glib/geocode-glib.symbols
+++ b/geocode-glib/geocode-glib.symbols
@@ -19,3 +19,9 @@ geocode_reverse_resolve
geocode_error_quark
_geocode_parse_search_json
_geocode_parse_resolve_json
+geocode_ipclient_get_type
+geocode_ipclient_new
+geocode_ipclient_new_for_ip
+geocode_ipclient_search_async
+geocode_ipclient_search
+geocode_ipclient_search_finish
\ No newline at end of file
diff --git a/geocode-glib/geocode-ipclient.c b/geocode-glib/geocode-ipclient.c
new file mode 100644
index 0000000..a5f1d08
--- /dev/null
+++ b/geocode-glib/geocode-ipclient.c
@@ -0,0 +1,217 @@
+/*
+ Copyright (C) 2013 Satabdi Das
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301 USA.
+
+ Authors: Satabdi Das <satabdidas gmail com>
+
+ */
+
+#include <stdlib.h>
+#include <glib.h>
+#include <libsoup/soup.h>
+#include "geocode-ipclient.h"
+
+struct _GeocodeIpclientPrivate {
+ char *ip;
+};
+
+G_DEFINE_TYPE (GeocodeIpclient, geocode_ipclient, G_TYPE_OBJECT)
+
+static void
+geocode_ipclient_finalize (GObject *gipclient)
+{
+ GeocodeIpclient *ipclient = (GeocodeIpclient *) gipclient;
+
+ g_free (ipclient->priv->ip);
+
+ G_OBJECT_CLASS (geocode_ipclient_parent_class)->finalize (gipclient);
+}
+
+static void
+geocode_ipclient_class_init (GeocodeIpclientClass *klass)
+{
+ GObjectClass *gipclient_class = G_OBJECT_CLASS (klass);
+
+ gipclient_class->finalize = geocode_ipclient_finalize;
+
+ g_type_class_add_private (klass, sizeof (GeocodeIpclientPrivate));
+}
+
+static void
+geocode_ipclient_init (GeocodeIpclient *ipclient)
+{
+ ipclient->priv = G_TYPE_INSTANCE_GET_PRIVATE ((ipclient), GEOCODE_TYPE_IPCLIENT, GeocodeIpclientPrivate);
+}
+
+GeocodeIpclient *
+geocode_ipclient_new_for_ip (const char *ip)
+{
+ GeocodeIpclient *ipclient;
+
+ ipclient = g_object_new (GEOCODE_TYPE_IPCLIENT, NULL);
+ ipclient->priv->ip = g_strdup (ip);
+
+ return ipclient;
+}
+
+GeocodeIpclient *
+geocode_ipclient_new (void)
+{
+ return geocode_ipclient_new_for_ip (NULL);
+}
+
+static GFile *
+get_search_query (GeocodeIpclient *ipclient)
+{
+ GFile * ret;
+ GHashTable *ht;
+ char *query_string;
+ char *uri;
+ const char *ipaddress;
+ /* FIXME: the server uri needs to be made a property */
+ const char *server_uri = "http://127.0.0.1:12345/cgi-bin/geoip-lookup";
+
+ ipaddress = ipclient->priv->ip;
+ if (ipaddress) {
+ ht = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (ht, "ip", g_strdup (ipaddress));
+ query_string = soup_form_encode_hash (ht);
+ g_hash_table_destroy (ht);
+
+ uri = g_strdup_printf ("%s?%s", server_uri, query_string);
+ g_free (query_string);
+ } else
+ uri = g_strdup (server_uri);
+
+ ret = g_file_new_for_uri (uri);
+ g_free (uri);
+
+ return ret;
+}
+
+static void
+query_callback (GObject *source_forward,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ GFile *query;
+ GError *error = NULL;
+ char *contents;
+
+ query = G_FILE (source_forward);
+ if (g_file_load_contents_finish (query,
+ res,
+ &contents,
+ NULL,
+ NULL,
+ &error) == FALSE) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ g_error_free (error);
+ return;
+
+ }
+ if (contents == NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ g_error_free (error);
+ return;
+ }
+ g_simple_async_result_set_op_res_gpointer (simple, contents, NULL);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+}
+
+void
+geocode_ipclient_search_async (GeocodeIpclient *ipclient,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ GFile *query;
+ GError *error = NULL;
+
+ g_return_if_fail (GEOCODE_IS_IPCLIENT (ipclient));
+
+ simple = g_simple_async_result_new (G_OBJECT (ipclient),
+ callback,
+ user_data,
+ geocode_ipclient_search_async);
+
+ query = get_search_query (ipclient);
+ if (!query) {
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ return;
+ }
+ g_file_load_contents_async (query,
+ cancellable,
+ query_callback,
+ simple);
+ g_object_unref (query);
+}
+
+char *
+geocode_ipclient_search_finish (GeocodeIpclient *ipclient,
+ GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+ char *contents = NULL;
+
+ g_return_val_if_fail (GEOCODE_IS_IPCLIENT (ipclient), NULL);
+
+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == geocode_ipclient_search_async);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ contents = g_simple_async_result_get_op_res_gpointer (simple);
+ return contents;
+}
+
+char *
+geocode_ipclient_search (GeocodeIpclient *ipclient,
+ GError **error)
+{
+ char *contents;
+ GFile *query;
+
+ g_return_val_if_fail (GEOCODE_IS_IPCLIENT (ipclient), NULL);
+
+ query = get_search_query (ipclient);
+
+ if (!query)
+ return NULL;
+ if (g_file_load_contents (query,
+ NULL,
+ &contents,
+ NULL,
+ NULL,
+ error) == FALSE) {
+ g_object_unref (query);
+ return NULL;
+ }
+ g_object_unref (query);
+
+ return contents;
+}
diff --git a/geocode-glib/geocode-ipclient.h b/geocode-glib/geocode-ipclient.h
new file mode 100644
index 0000000..ab9e7d9
--- /dev/null
+++ b/geocode-glib/geocode-ipclient.h
@@ -0,0 +1,83 @@
+/*
+ Copyright (C) 2013 Satabdi Das
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301 USA.
+
+ Authors: Satabdi Das <satabdidas gmail com>
+
+ */
+
+#ifndef GEOCODE_IPCLIENT_H
+#define GEOCODE_IPCLIENT_H
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+GType geocode_ipclient_get_type (void) G_GNUC_CONST;
+
+#define GEOCODE_TYPE_IPCLIENT (geocode_ipclient_get_type ())
+#define GEOCODE_IPCLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCODE_TYPE_IPCLIENT, GeocodeIpclient))
+#define GEOCODE_IS_IPCLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCODE_TYPE_IPCLIENT))
+#define GEOCODE_IPCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCODE_TYPE_IPCLIENT, GeocodeIpclientClass))
+#define GEOCODE_IS_IPCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCODE_TYPE_IPCLIENT))
+#define GEOCODE_IPCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEOCODE_TYPE_IPCLIENT, GeocodeIpclientClass))
+
+/**
+ * GeocodeIpclient:
+ *
+ * All the fields in the #GeocodeIpclient structure are private and should never be accessed directly.
+**/
+typedef struct _GeocodeIpclient GeocodeIpclient;
+typedef struct _GeocodeIpclientClass GeocodeIpclientClass;
+typedef struct _GeocodeIpclientPrivate GeocodeIpclientPrivate;
+
+struct _GeocodeIpclient {
+ /* <private> */
+ GObject parent_instance;
+ GeocodeIpclientPrivate *priv;
+};
+
+/**
+ * GeocodeIpclientClass:
+ *
+ * All the fields in the #GeocodeIpclientClass structure are private and should never be accessed directly.
+**/
+struct _GeocodeIpclientClass {
+ /* <private> */
+ GObjectClass parent_class;
+};
+
+GeocodeIpclient *geocode_ipclient_new (void);
+GeocodeIpclient *geocode_ipclient_new_for_ip (const char *str);
+
+
+void geocode_ipclient_search_async (GeocodeIpclient *ipclient,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+char *geocode_ipclient_search_finish (GeocodeIpclient *ipclient,
+ GAsyncResult *res,
+ GError **error);
+
+char *geocode_ipclient_search (GeocodeIpclient *ipclient,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* GEOCODE_IPCLIENT_H */
diff --git a/geocode-glib/test-geoip.c b/geocode-glib/test-geoip.c
new file mode 100644
index 0000000..b5af960
--- /dev/null
+++ b/geocode-glib/test-geoip.c
@@ -0,0 +1,103 @@
+
+#include "config.h"
+#include <locale.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <geocode-ipclient.h>
+
+static GMainLoop *loop = NULL;
+
+static void
+test_search (gconstpointer data)
+{
+ GeocodeIpclient *ipclient;
+ GError *error = NULL;
+ char *contents;
+ const char *ip;
+
+ ip = (const char *) data;
+ if (ip)
+ ipclient = geocode_ipclient_new_for_ip ("24.34.34.24");
+ else {
+ ipclient = geocode_ipclient_new ();
+ }
+ contents = geocode_ipclient_search (ipclient, &error);
+ if (!contents) {
+ g_warning ("Failed at getting the geolocation information: %s", error->message);
+ g_error_free (error);
+ }
+ g_assert (contents != NULL);
+
+ g_object_unref (ipclient);
+ g_print ("%s\n", contents);
+ g_free (contents);
+}
+
+static void
+print_geolocation_info_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GeocodeIpclient *object = (GeocodeIpclient *) source_object;
+ GError *error = NULL;
+ char *results;
+
+ results = geocode_ipclient_search_finish (object, res, &error);
+ if (results == NULL) {
+ g_message ("Failed to search the geolocation info: %s", error->message);
+ g_error_free (error);
+ exit (1);
+ }
+ g_print ("%s\n", results);
+ g_free (results);
+
+ g_object_unref (object);
+ exit (0);
+}
+
+
+int main (int argc, char **argv)
+{
+ GError *error = NULL;
+ GOptionContext *context;
+ GeocodeIpclient *ipclient;
+ char *ip = NULL;
+ gboolean regr = FALSE;
+ const GOptionEntry entries[] = {
+ { "ip", 0, 0, G_OPTION_ARG_STRING, &ip, "The ip address for which to search the geolocation data", NULL },
+ { "regr", 0, 0, G_OPTION_ARG_NONE, ®r, "Run the default testcases", NULL },
+ { NULL }
+ };
+
+ setlocale (LC_ALL, "");
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=");
+
+ /* Parse our own command-line options */
+ context = g_option_context_new ("- test parser functions");
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+
+ if (g_option_context_parse (context, &argc, &argv, &error) == FALSE) {
+ g_print ("Option parsing failed: %s\n", error->message);
+ return 1;
+ }
+
+ if (regr == TRUE) {
+ g_test_add_data_func ("/geoip/search_with_ip", "24.24.24.24", test_search);
+ g_test_add_data_func ("/geocode/search", NULL, test_search);
+ return g_test_run ();
+ }
+
+ if (ip)
+ ipclient = geocode_ipclient_new_for_ip (ip);
+ else
+ ipclient = geocode_ipclient_new ();
+ geocode_ipclient_search_async (ipclient, NULL, print_geolocation_info_cb, NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]