[geocode-glib/gnome-maps: 8/9] lib: Report accuracy of IP-based location search result
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geocode-glib/gnome-maps: 8/9] lib: Report accuracy of IP-based location search result
- Date: Wed, 27 Mar 2013 01:39:48 +0000 (UTC)
commit a8b0142c5f082c8e13994e9e21abd1921b7cee53
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 | 70 +++++++++++++++++++++++++++++++++----
geocode-glib/geocode-ipclient.h | 30 +++++++++++++---
geocode-glib/test-geoip.c | 7 +++-
4 files changed, 94 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 d2704dc..3ec071e 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"
#include "geocode-ip-server/geoip-server.h"
/**
@@ -315,8 +316,56 @@ 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_UNKNOWN);
+ } 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_name"))
+ return GEOCODE_LOCATION_ACCURACY_REGION;
+ else if (json_object_has_member (object, "country_name"))
+ return GEOCODE_LOCATION_ACCURACY_COUNTRY;
+ else if (json_object_has_member (object, "continent"))
+ return GEOCODE_LOCATION_ACCURACY_CONTINENT;
+ else
+ return GEOCODE_LOCATION_ACCURACY_UNKNOWN;
+}
+
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;
@@ -356,6 +405,9 @@ json_to_location (const char *json, GError **error) {
g_free (desc);
}
+ if (accuracy != NULL)
+ *accuracy = get_accuracy_from_json_location (object);
+
g_object_unref (parser);
return location;
@@ -365,6 +417,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().
@@ -373,9 +426,10 @@ json_to_location (const char *json, GError **error) {
* errors. 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;
@@ -389,7 +443,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;
@@ -398,6 +452,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.
@@ -406,7 +461,8 @@ geocode_ipclient_search_finish (GeocodeIpclient *ipclient,
* errors. 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;
@@ -431,7 +487,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..b21d304 100644
--- a/geocode-glib/geocode-ipclient.h
+++ b/geocode-glib/geocode-ipclient.h
@@ -63,6 +63,24 @@ struct _GeocodeIpclientClass {
GObjectClass parent_class;
};
+/**
+ * GeocodeLocationAccuracy:
+ * GEOCODE_LOCATION_ACCURACY_UNKNOWN: accuracy is unknown.
+ * 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_UNKNOWN = -1,
+ 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 +90,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 895e643..4b5902d 100644
--- a/geocode-glib/test-geoip.c
+++ b/geocode-glib/test-geoip.c
@@ -24,13 +24,14 @@ test_search (gconstpointer data)
GError *error = NULL;
GeocodeLocation *location;
TestData *test_data = (TestData *) data;
+ GeocodeLocationAccuracy accuracy = GEOCODE_LOCATION_ACCURACY_UNKNOWN;
if (test_data->ip)
ipclient = geocode_ipclient_new_for_ip (test_data->ip);
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);
@@ -40,6 +41,7 @@ test_search (gconstpointer data)
g_assert (location->longitude == test_data->expected_longitude);
g_assert (location->description != NULL &&
strcmp(location->description, test_data->expected_description) == 0);
+ g_assert (accuracy != GEOCODE_LOCATION_ACCURACY_UNKNOWN);
geocode_location_free (location);
g_object_unref (ipclient);
}
@@ -52,8 +54,9 @@ print_geolocation_info_cb (GObject *source_object,
GeocodeIpclient *object = (GeocodeIpclient *) source_object;
GError *error = NULL;
GeocodeLocation *location;
+ GeocodeLocationAccuracy accuracy = GEOCODE_LOCATION_ACCURACY_UNKNOWN;
- 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]