[geocode-glib/gnome-maps: 5/6] lib: Report accuracy of IP-based location search result



commit 1e944f93795aef004acd37165aad0328cdc4113b
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Sun Mar 24 03:01:11 2013 +0200

    lib: Report accuracy of IP-based location search result
    
    https://bugzilla.gnome.org/show_bug.cgi?id=696527

 geocode-glib/geocode-glib.symbols |    1 +
 geocode-glib/geocode-ipclient.c   |   68 +++++++++++++++++++++++++++++++++----
 geocode-glib/geocode-ipclient.h   |   28 ++++++++++++---
 geocode-glib/test-geoip.c         |    7 +++-
 4 files changed, 90 insertions(+), 14 deletions(-)
---
diff --git a/geocode-glib/geocode-glib.symbols b/geocode-glib/geocode-glib.symbols
index 9dfb37e..b6b62df 100644
--- a/geocode-glib/geocode-glib.symbols
+++ b/geocode-glib/geocode-glib.symbols
@@ -4,6 +4,7 @@ geocode_location_new_with_description
 geocode_location_free
 geocode_location_get_distance_from
 geocode_location_set_description
+geocode_location_accuracy_get_type
 geocode_forward_get_type
 geocode_forward_new_for_string
 geocode_forward_new_for_params
diff --git a/geocode-glib/geocode-ipclient.c b/geocode-glib/geocode-ipclient.c
index c74b045..185f99a 100644
--- a/geocode-glib/geocode-ipclient.c
+++ b/geocode-glib/geocode-ipclient.c
@@ -26,6 +26,7 @@
 #include <json-glib/json-glib.h>
 #include "geocode-ipclient.h"
 #include "geocode-error.h"
+#include "geocode-enum-types.h"
 
 /**
  * SECTION:geocode-ipclient
@@ -320,8 +321,54 @@ parse_server_error (JsonObject *object, GError **error) {
         return TRUE;
 }
 
+/* Modified copy of gvir_config_genum_get_value from libvirt-glib */
+static int
+get_enum_value_by_nick (GType       enum_type,
+                        const char *nick,
+                        gint        default_value)
+{
+        GEnumClass *enum_class;
+        GEnumValue *enum_value;
+
+        g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), default_value);
+        g_return_val_if_fail (nick != NULL, default_value);
+
+        enum_class = g_type_class_ref (enum_type);
+        enum_value = g_enum_get_value_by_nick (enum_class, nick);
+        g_type_class_unref (enum_class);
+
+        if (enum_value != NULL)
+                return enum_value->value;
+
+        g_return_val_if_reached (default_value);
+}
+
+static GeocodeLocationAccuracy
+get_accuracy_from_json_location (JsonObject *object)
+{
+        if (json_object_has_member (object, "accuracy")) {
+                const char *str;
+
+                str = json_object_get_string_member (object, "accuracy");
+                return get_enum_value_by_nick (GEOCODE_TYPE_LOCATION_ACCURACY,
+                                               str,
+                                               GEOCODE_LOCATION_ACCURACY_COUNTRY);
+        } else if (json_object_has_member (object, "street"))
+                return GEOCODE_LOCATION_ACCURACY_STREET;
+        else if (json_object_has_member (object, "city"))
+                return GEOCODE_LOCATION_ACCURACY_CITY;
+        else if (json_object_has_member (object, "region"))
+                return GEOCODE_LOCATION_ACCURACY_REGION;
+        else if (json_object_has_member (object, "country"))
+                return GEOCODE_LOCATION_ACCURACY_COUNTRY;
+        else
+                return GEOCODE_LOCATION_ACCURACY_CONTINENT;
+}
+
 static GeocodeLocation *
-json_to_location (const char *json, GError **error) {
+json_to_location (const char              *json,
+                  GeocodeLocationAccuracy *accuracy,
+                  GError                 **error) {
         JsonParser *parser;
         JsonNode *node;
         JsonObject *object;
@@ -363,6 +410,9 @@ json_to_location (const char *json, GError **error) {
                                  json_object_get_string_member (object, "country_name"));
         }
 
+        if (accuracy != NULL)
+                *accuracy = get_accuracy_from_json_location (object);
+
         location->description = g_string_free (string, FALSE);
         g_object_unref (parser);
 
@@ -373,6 +423,7 @@ json_to_location (const char *json, GError **error) {
  * geocode_ipclient_search_finish:
  * @ipclient: a #GeocodeIpclient representing a query
  * @res: a #GAsyncResult
+ * @accuracy: (out): place-holder for accuracy of the returned location or NULL
  * @error: a #GError
  *
  * Finishes a geolocation search operation. See geocode_ipclient_search_async().
@@ -381,9 +432,10 @@ json_to_location (const char *json, GError **error) {
  * Free the returned object with g_object_unref() when done.
  **/
 GeocodeLocation *
-geocode_ipclient_search_finish (GeocodeIpclient *ipclient,
-                                GAsyncResult    *res,
-                                GError          **error)
+geocode_ipclient_search_finish (GeocodeIpclient         *ipclient,
+                                GAsyncResult            *res,
+                                GeocodeLocationAccuracy *accuracy,
+                                GError                 **error)
 {
         GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
         char *contents = NULL;
@@ -397,7 +449,7 @@ geocode_ipclient_search_finish (GeocodeIpclient *ipclient,
                 return NULL;
 
         contents = g_simple_async_result_get_op_res_gpointer (simple);
-        location = json_to_location (contents, error);
+        location = json_to_location (contents, accuracy, error);
         g_free (contents);
 
         return location;
@@ -406,6 +458,7 @@ geocode_ipclient_search_finish (GeocodeIpclient *ipclient,
 /**
  * geocode_ipclient_search:
  * @ipclient: a #GeocodeIpclient representing a query
+ * @accuracy: (out): place-holder for accuracy of the returned location or NULL
  * @error: a #GError
  *
  * Gets the geolocation data for an IP address from the server.
@@ -414,7 +467,8 @@ geocode_ipclient_search_finish (GeocodeIpclient *ipclient,
  * Free the returned object with g_object_unref() when done.
  **/
 GeocodeLocation *
-geocode_ipclient_search (GeocodeIpclient        *ipclient,
+geocode_ipclient_search (GeocodeIpclient         *ipclient,
+                         GeocodeLocationAccuracy *accuracy,
                          GError                 **error)
 {
         char *contents;
@@ -439,7 +493,7 @@ geocode_ipclient_search (GeocodeIpclient        *ipclient,
         }
         g_object_unref (query);
 
-        location = json_to_location (contents, error);
+        location = json_to_location (contents, accuracy, error);
         g_free (contents);
 
         return location;
diff --git a/geocode-glib/geocode-ipclient.h b/geocode-glib/geocode-ipclient.h
index 7bd26da..5b97595 100644
--- a/geocode-glib/geocode-ipclient.h
+++ b/geocode-glib/geocode-ipclient.h
@@ -63,6 +63,22 @@ struct _GeocodeIpclientClass {
         GObjectClass parent_class;
 };
 
+/**
+ * GeocodeLocationAccuracy:
+ * GEOCODE_LOCATION_ACCURACY_STREET: Street-level accuracy.
+ * GEOCODE_LOCATION_ACCURACY_CITY: City-level accuracy.
+ * GEOCODE_LOCATION_ACCURACY_REGION: Region-level accuracy.
+ * GEOCODE_LOCATION_ACCURACY_COUNTRY: Country-level accuracy.
+ * GEOCODE_LOCATION_ACCURACY_CONTINENT: Continent-level accuracy.
+ **/
+typedef enum {
+        GEOCODE_LOCATION_ACCURACY_STREET,
+        GEOCODE_LOCATION_ACCURACY_CITY,
+        GEOCODE_LOCATION_ACCURACY_REGION,
+        GEOCODE_LOCATION_ACCURACY_COUNTRY,
+        GEOCODE_LOCATION_ACCURACY_CONTINENT
+} GeocodeLocationAccuracy;
+
 GeocodeIpclient *geocode_ipclient_new           (void);
 GeocodeIpclient *geocode_ipclient_new_for_ip    (const char *str);
 
@@ -72,12 +88,14 @@ void geocode_ipclient_search_async  (GeocodeIpclient       *ipclient,
                                      GAsyncReadyCallback    callback,
                                      gpointer               user_data);
 
-GeocodeLocation *geocode_ipclient_search_finish (GeocodeIpclient   *ipclient,
-                                                 GAsyncResult      *res,
-                                                 GError            **error);
+GeocodeLocation *geocode_ipclient_search_finish (GeocodeIpclient         *ipclient,
+                                                 GAsyncResult            *res,
+                                                 GeocodeLocationAccuracy *accuracy,
+                                                 GError                 **error);
 
-GeocodeLocation *geocode_ipclient_search (GeocodeIpclient *ipclient,
-                                          GError          **error);
+GeocodeLocation *geocode_ipclient_search (GeocodeIpclient         *ipclient,
+                                          GeocodeLocationAccuracy *accuracy,
+                                          GError                 **error);
 
 G_END_DECLS
 
diff --git a/geocode-glib/test-geoip.c b/geocode-glib/test-geoip.c
index 19ca905..320cd3b 100644
--- a/geocode-glib/test-geoip.c
+++ b/geocode-glib/test-geoip.c
@@ -15,6 +15,7 @@ test_search (gconstpointer data)
         GeocodeIpclient *ipclient;
         GError *error = NULL;
         GeocodeLocation *location;
+        GeocodeLocationAccuracy accuracy = -1;
         const char *ip;
 
         ip = (const char *) data;
@@ -23,12 +24,13 @@ test_search (gconstpointer data)
         else {
                 ipclient = geocode_ipclient_new ();
         }
-        location = geocode_ipclient_search (ipclient, &error);
+        location = geocode_ipclient_search (ipclient, &accuracy, &error);
         if (!location) {
                 g_warning ("Failed at getting the geolocation information: %s", error->message);
                 g_error_free (error);
         }
         g_assert (location != NULL);
+        g_assert (accuracy > 0);
         g_object_unref (location);
         g_object_unref (ipclient);
 }
@@ -41,8 +43,9 @@ print_geolocation_info_cb (GObject          *source_object,
         GeocodeIpclient *object = (GeocodeIpclient *) source_object;
         GError *error = NULL;
         GeocodeLocation *location;
+        GeocodeLocationAccuracy accuracy = -1;
 
-        location = geocode_ipclient_search_finish (object, res, &error);
+        location = geocode_ipclient_search_finish (object, res, &accuracy, &error);
         if (location == NULL) {
                 g_message ("Failed to search the geolocation info: %s", error->message);
                 g_error_free (error);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]