[gnome-settings-daemon] datetime: Use libgweather's timezone info



commit f71de53b29b11d5f412c2c52f5b313f423343827
Author: Kalev Lember <kalevlember gmail com>
Date:   Sun Sep 1 12:54:37 2013 +0200

    datetime: Use libgweather's timezone info
    
    In addition to the Olson timezone DB, we're now merging in the timezone
    location info from libgweather as well. This should make the timezone
    autodiscovery more accurate and is hopefully good enough to turn it on
    by default.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=707241

 configure.ac                            |    2 +
 plugins/datetime/Makefile.am            |    8 ++-
 plugins/datetime/gsd-timezone-monitor.c |   20 ++++-
 plugins/datetime/tz.c                   |    2 +-
 plugins/datetime/tz.h                   |    1 +
 plugins/datetime/weather-tz.c           |  137 +++++++++++++++++++++++++++++++
 plugins/datetime/weather-tz.h           |   32 +++++++
 7 files changed, 194 insertions(+), 8 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 3b1c860..ac3df96 100644
--- a/configure.ac
+++ b/configure.ac
@@ -48,6 +48,7 @@ GIO_REQUIRED_VERSION=${GLIB_REQUIRED_VERSION}
 GTK_REQUIRED_VERSION=3.7.8
 GCONF_REQUIRED_VERSION=2.6.1
 GNOME_DESKTOP_REQUIRED_VERSION=3.9.0
+LIBGWEATHER_REQUIRED_VERSION=3.9.5
 LIBNOTIFY_REQUIRED_VERSION=0.7.3
 UPOWER_GLIB_REQUIRED_VERSION=0.9.1
 PA_REQUIRED_VERSION=2.0
@@ -255,6 +256,7 @@ AC_SUBST(LIBM)
 
 PKG_CHECK_MODULES(DATETIME,
        geocode-glib-1.0 >= $GEOCODE_GLIB_REQUIRED_VERSION
+       gweather-3.0 >= $LIBGWEATHER_REQUIRED_VERSION
        polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION
 )
 
diff --git a/plugins/datetime/Makefile.am b/plugins/datetime/Makefile.am
index c2b41c8..4232a65 100644
--- a/plugins/datetime/Makefile.am
+++ b/plugins/datetime/Makefile.am
@@ -34,7 +34,9 @@ gsd_test_datetime_SOURCES =   \
        gsd-timezone-monitor.h  \
        test-datetime.c         \
        tz.c                    \
-       tz.h
+       tz.h                    \
+       weather-tz.c            \
+       weather-tz.h
 
 gsd_test_datetime_CFLAGS =                                     \
        -I$(top_srcdir)/gnome-settings-daemon                   \
@@ -65,7 +67,9 @@ libdatetime_la_SOURCES =      \
        gsd-timezone-monitor.h  \
        gsd-timezone-monitor.c  \
        tz.h                    \
-       tz.c
+       tz.c                    \
+       weather-tz.c            \
+       weather-tz.h
 
 libdatetime_la_CPPFLAGS =                                      \
        -I$(top_srcdir)/gnome-settings-daemon                   \
diff --git a/plugins/datetime/gsd-timezone-monitor.c b/plugins/datetime/gsd-timezone-monitor.c
index 891f1e1..f0c9d12 100644
--- a/plugins/datetime/gsd-timezone-monitor.c
+++ b/plugins/datetime/gsd-timezone-monitor.c
@@ -25,6 +25,7 @@
 #include "geoclue.h"
 #include "timedated.h"
 #include "tz.h"
+#include "weather-tz.h"
 
 #include <geocode-glib/geocode-glib.h>
 #include <polkit/polkit.h>
@@ -47,6 +48,7 @@ typedef struct
         Timedate1 *dtm;
 
         TzDB *tzdb;
+        WeatherTzDB *weather_tzdb;
         gchar *current_timezone;
 } GsdTimezoneMonitorPrivate;
 
@@ -162,17 +164,23 @@ find_by_country (GList       *locations,
 }
 
 static const gchar *
-find_timezone (GeocodeLocation *location,
-               const gchar     *country_code,
-               TzDB            *tzdb)
+find_timezone (GsdTimezoneMonitor *self,
+               GeocodeLocation    *location,
+               const gchar        *country_code)
 {
         GList *filtered;
         GList *locations;
+        GsdTimezoneMonitorPrivate *priv = gsd_timezone_monitor_get_instance_private (self);
         TzLocation *closest_tz_location;
 
-        locations = ptr_array_to_list (tz_get_locations (tzdb));
+        /* First load locations from Olson DB */
+        locations = ptr_array_to_list (tz_get_locations (priv->tzdb));
         g_return_val_if_fail (locations != NULL, NULL);
 
+        /* ... and then add libgweather's locations as well */
+        locations = g_list_concat (locations,
+                                   weather_tz_db_get_locations (priv->weather_tzdb));
+
         /* Filter tz locations by country */
         filtered = find_by_country (locations, country_code);
         if (filtered != NULL) {
@@ -203,7 +211,7 @@ process_location (GsdTimezoneMonitor *self,
         country_code = geocode_place_get_country_code (place);
         location = geocode_place_get_location (place);
 
-        new_timezone = find_timezone (location, country_code, priv->tzdb);
+        new_timezone = find_timezone (self, location, country_code);
 
         if (g_strcmp0 (priv->current_timezone, new_timezone) != 0)
                 queue_set_timezone (self, new_timezone);
@@ -430,6 +438,7 @@ gsd_timezone_monitor_finalize (GObject *obj)
         g_clear_object (&priv->permission);
         g_clear_pointer (&priv->current_timezone, g_free);
         g_clear_pointer (&priv->tzdb, tz_db_free);
+        g_clear_pointer (&priv->weather_tzdb, weather_tz_db_free);
 
         G_OBJECT_CLASS (gsd_timezone_monitor_parent_class)->finalize (obj);
 }
@@ -490,6 +499,7 @@ gsd_timezone_monitor_init (GsdTimezoneMonitor *self)
 
         priv->current_timezone = timedate1_dup_timezone (priv->dtm);
         priv->tzdb = tz_load_db ();
+        priv->weather_tzdb = weather_tz_db_new ();
 
         register_geoclue (self);
 }
diff --git a/plugins/datetime/tz.c b/plugins/datetime/tz.c
index c539d59..5465d32 100644
--- a/plugins/datetime/tz.c
+++ b/plugins/datetime/tz.c
@@ -131,7 +131,7 @@ tz_load_db (void)
        return tz_db;
 }
 
-static void
+void
 tz_location_free (TzLocation *loc)
 {
        g_free (loc->country);
diff --git a/plugins/datetime/tz.h b/plugins/datetime/tz.h
index 71c1c23..7329233 100644
--- a/plugins/datetime/tz.h
+++ b/plugins/datetime/tz.h
@@ -78,6 +78,7 @@ char *     tz_info_get_clean_name     (TzDB *tz_db,
 GPtrArray *tz_get_locations           (TzDB *db);
 void       tz_location_get_position   (TzLocation *loc,
                                       double *longitude, double *latitude);
+void       tz_location_free           (TzLocation *loc);
 char      *tz_location_get_country    (TzLocation *loc);
 gchar     *tz_location_get_zone       (TzLocation *loc);
 gchar     *tz_location_get_comment    (TzLocation *loc);
diff --git a/plugins/datetime/weather-tz.c b/plugins/datetime/weather-tz.c
new file mode 100644
index 0000000..42e5f7d
--- /dev/null
+++ b/plugins/datetime/weather-tz.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Kalev Lember <kalevlember gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "weather-tz.h"
+#include "tz.h"
+
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include <libgweather/gweather.h>
+
+struct _WeatherTzDB
+{
+        GList *tz_locations;
+};
+
+static GList *
+location_get_cities (GWeatherLocation *parent_location)
+{
+        GList *cities = NULL;
+        GWeatherLocation **children;
+        gint i;
+
+        children = gweather_location_get_children (parent_location);
+        for (i = 0; children[i]; i++) {
+                if (gweather_location_get_level (children[i]) == GWEATHER_LOCATION_CITY) {
+                        cities = g_list_prepend (cities,
+                                                 children[i]);
+                } else {
+                        cities = g_list_concat (cities,
+                                                location_get_cities (children[i]));
+                }
+        }
+
+        return cities;
+}
+
+static gboolean
+weather_location_has_timezone (GWeatherLocation *loc)
+{
+        return gweather_location_get_timezone (loc) != NULL;
+}
+
+/**
+ * load_timezones:
+ * @cities: a list of #GWeatherLocation
+ *
+ * Returns: a list of #TzLocation
+ */
+static GList *
+load_timezones (GList *cities)
+{
+        GList *l;
+        GList *tz_locations = NULL;
+
+        for (l = cities; l; l = l->next) {
+                TzLocation *loc;
+                const gchar *country;
+                const gchar *timezone_id;
+                gdouble latitude;
+                gdouble longitude;
+
+                if (!gweather_location_has_coords (l->data) ||
+                    !weather_location_has_timezone (l->data)) {
+                        g_debug ("Incomplete GWeather location entry: (%s) %s",
+                                 gweather_location_get_country (l->data),
+                                 gweather_location_get_city_name (l->data));
+                        continue;
+                }
+
+                country = gweather_location_get_country (l->data);
+                timezone_id = gweather_timezone_get_tzid (gweather_location_get_timezone (l->data));
+                gweather_location_get_coords (l->data,
+                                              &latitude,
+                                              &longitude);
+
+                loc = g_new0 (TzLocation, 1);
+                loc->country = g_strdup (country);
+                loc->latitude = latitude;
+                loc->longitude = longitude;
+                loc->zone = g_strdup (timezone_id);
+                loc->comment = NULL;
+
+                tz_locations = g_list_prepend (tz_locations, loc);
+        }
+
+        return tz_locations;
+}
+
+GList *
+weather_tz_db_get_locations (WeatherTzDB *tzdb)
+{
+        return g_list_copy (tzdb->tz_locations);
+}
+
+WeatherTzDB *
+weather_tz_db_new (void)
+{
+        GList *cities;
+        GWeatherLocation *world;
+        WeatherTzDB *tzdb;
+
+        world = gweather_location_get_world ();
+        cities = location_get_cities (world);
+
+        tzdb = g_new0 (WeatherTzDB, 1);
+        tzdb->tz_locations = load_timezones (cities);
+
+        g_list_free (cities);
+
+        return tzdb;
+}
+
+void
+weather_tz_db_free (WeatherTzDB *tzdb)
+{
+        g_list_free_full (tzdb->tz_locations, (GDestroyNotify) tz_location_free);
+
+        g_free (tzdb);
+}
diff --git a/plugins/datetime/weather-tz.h b/plugins/datetime/weather-tz.h
new file mode 100644
index 0000000..069367a
--- /dev/null
+++ b/plugins/datetime/weather-tz.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Kalev Lember <kalevlember gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __WEATHER_TZ_H
+#define __WEATHER_TZ_H
+
+#include <glib.h>
+
+typedef struct _WeatherTzDB WeatherTzDB;
+
+WeatherTzDB     *weather_tz_db_new              (void);
+GList           *weather_tz_db_get_locations    (WeatherTzDB *db);
+void             weather_tz_db_free             (WeatherTzDB *db);
+
+#endif /* __WEATHER_TZ_H */


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