[geocode-glib] ipclient: Add IP Geocoding client



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, &regr, "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]