[evolution-data-server] [Weather calendar] Merge intra-day forecasts into one event



commit b56431520489f5dd729dfb532d3b1afec68e7a6f
Author: Milan Crha <mcrha redhat com>
Date:   Thu May 21 17:33:05 2015 +0200

    [Weather calendar] Merge intra-day forecasts into one event
    
    ...rather than fill all-day events with multiple forecast events.

 calendar/backends/weather/e-cal-backend-weather.c |  212 +++++++++++++++++----
 1 files changed, 171 insertions(+), 41 deletions(-)
---
diff --git a/calendar/backends/weather/e-cal-backend-weather.c 
b/calendar/backends/weather/e-cal-backend-weather.c
index 1a36da2..17fa739 100644
--- a/calendar/backends/weather/e-cal-backend-weather.c
+++ b/calendar/backends/weather/e-cal-backend-weather.c
@@ -43,7 +43,8 @@ static ECalComponent *
                create_weather                  (ECalBackendWeather *cbw,
                                                 GWeatherInfo *report,
                                                 GWeatherTemperatureUnit unit,
-                                                gboolean is_forecast);
+                                                gboolean is_forecast,
+                                                GSList *same_day_forecasts);
 static void    e_cal_backend_weather_add_timezone
                                                (ECalBackendSync *backend,
                                                 EDataCal *cal,
@@ -154,6 +155,27 @@ put_component_to_store (ECalBackendWeather *cb,
        e_cal_backend_store_put_component_with_time_range (priv->store, comp, time_start, time_end);
 }
 
+static gint
+compare_weather_info_by_date (gconstpointer a,
+                             gconstpointer b)
+{
+       GWeatherInfo *nfoa = (GWeatherInfo *) a, *nfob = (GWeatherInfo *) b;
+
+       if (nfoa && nfob) {
+               time_t tma, tmb;
+
+               if (!gweather_info_get_value_update (nfoa, &tma))
+                       tma = 0;
+
+               if (!gweather_info_get_value_update (nfob, &tmb))
+                       tmb = 0;
+
+               return tma == tmb ? 0 : (tma < tmb ? -1 : 1);
+       }
+
+       return nfoa == nfob ? 0 : (nfoa ? 1 : -1);
+}
+
 static void
 finished_retrieval_cb (GWeatherInfo *info,
                        ECalBackendWeather *cbw)
@@ -199,31 +221,83 @@ finished_retrieval_cb (GWeatherInfo *info,
        g_slist_free (comps);
        e_cal_backend_store_clean (priv->store);
 
-       comp = create_weather (cbw, info, unit, FALSE);
+       comp = create_weather (cbw, info, unit, FALSE, NULL);
        if (comp) {
-               GSList *forecasts;
+               GSList *orig_forecasts;
 
                put_component_to_store (cbw, comp);
                e_cal_backend_notify_component_created (E_CAL_BACKEND (cbw), comp);
                g_object_unref (comp);
 
-               forecasts = gweather_info_get_forecast_list (info);
-               if (forecasts) {
-                       GSList *f;
+               orig_forecasts = gweather_info_get_forecast_list (info);
+               if (orig_forecasts) {
+                       time_t info_day = 0;
+                       GSList *forecasts, *f;
+
+                       if (!gweather_info_get_value_update (info, &info_day))
+                               info_day = 0;
+
+                       info_day = info_day / (24 * 60 * 60);
 
                        /* skip the first one, it's for today, which has been added above */
-                       for (f = forecasts->next; f; f = f->next) {
+                       forecasts = g_slist_copy (orig_forecasts->next);
+                       forecasts = g_slist_sort (forecasts, compare_weather_info_by_date);
+
+                       f = forecasts;
+                       while (f) {
+                               time_t current_day;
                                GWeatherInfo *nfo = f->data;
 
-                               if (nfo) {
-                                       comp = create_weather (cbw, nfo, unit, TRUE);
+                               f = g_slist_next (f);
+
+                               if (nfo && gweather_info_get_value_update (nfo, &current_day)) {
+                                       GSList *same_day_forecasts = NULL;
+                                       gint current_hour;
+
+                                       current_hour = current_day % (24 * 60 * 60);
+                                       current_day = current_day / (24 * 60 * 60);
+
+                                       if (current_day == info_day)
+                                               continue;
+
+                                       while (f) {
+                                               GWeatherInfo *test_nfo = f->data;
+                                               time_t test_day;
+
+                                               if (test_nfo && gweather_info_get_value_update (test_nfo, 
&test_day)) {
+                                                       time_t test_hour;
+
+                                                       test_hour = test_day % (24 * 60 * 60);
+
+                                                       if (test_day / (24 * 60 * 60) != current_day)
+                                                               break;
+
+                                                       same_day_forecasts = g_slist_prepend 
(same_day_forecasts, test_nfo);
+
+                                                       /* Use the main GWeatherInfo the one closest to noon 
*/
+                                                       if (ABS (test_hour - (12 * 60 * 60)) < ABS 
(current_hour - (12 * 60 * 60))) {
+                                                               nfo = test_nfo;
+                                                               current_hour = test_hour;
+                                                       }
+                                               }
+
+                                               f = g_slist_next (f);
+                                       }
+
+                                       same_day_forecasts = g_slist_reverse (same_day_forecasts);
+
+                                       comp = create_weather (cbw, nfo, unit, TRUE, same_day_forecasts);
                                        if (comp) {
                                                put_component_to_store (cbw, comp);
                                                e_cal_backend_notify_component_created (E_CAL_BACKEND (cbw), 
comp);
                                                g_object_unref (comp);
                                        }
+
+                                       g_slist_free (same_day_forecasts);
                                }
                        }
+
+                       g_slist_free (forecasts);
                }
        }
 
@@ -339,44 +413,52 @@ cal_backend_weather_get_temp (gdouble value,
 }
 
 static gchar *
-cal_weather_get_info_forecast_text (GWeatherInfo *info)
+describe_forecast (GWeatherInfo *nfo,
+                  GWeatherTemperatureUnit unit)
 {
-       GString *buffer;
-       GSList *forecasts, *link;
+       gchar *str, *date, *summary, *temp;
+       gdouble tmin = 0.0, tmax = 0.0, temp1 = 0.0;
+
+       date = gweather_info_get_update (nfo);
+       summary = gweather_info_get_conditions (nfo);
+       if (g_str_equal (summary, "-")) {
+           g_free (summary);
+           summary = gweather_info_get_sky (nfo);
+       }
 
-       if (!info)
-               return NULL;
+       if (gweather_info_get_value_temp_min (nfo, unit, &tmin) &&
+           gweather_info_get_value_temp_max (nfo, unit, &tmax) &&
+           tmin != tmax) {
+               gchar *min, *max;
 
-       buffer = g_string_new ("");
+               min = cal_backend_weather_get_temp (tmin, unit);
+               max = cal_backend_weather_get_temp (tmax, unit);
 
-       forecasts = gweather_info_get_forecast_list (info);
-       for (link = forecasts; link; link = g_slist_next (link)) {
-               GWeatherInfo *nfo = link->data;
-               gchar *date, *summary, *temp;
+               temp = g_strdup_printf ("%s / %s", min, max);
 
-               date = gweather_info_get_update (nfo);
-               summary = gweather_info_get_conditions (nfo);
-               if (g_str_equal (summary, "-")) {
-                       g_free (summary);
-                       summary = gweather_info_get_sky (nfo);
-               }
-               temp = gweather_info_get_temp_summary (nfo);
+               g_free (min);
+               g_free (max);
+       } else if (gweather_info_get_value_temp (nfo, unit, &temp1)) {
+               temp = cal_backend_weather_get_temp (temp1, unit);
+       } else {
+               temp = gweather_info_get_temp (nfo);
+       }
 
-               g_string_append_printf (buffer, " * %s: %s, %s\n", date, summary, temp);
+       str = g_strdup_printf (" * %s: %s, %s", date, summary, temp);
 
-               g_free (date);
-               g_free (summary);
-               g_free (temp);
-       }
+       g_free (date);
+       g_free (summary);
+       g_free (temp);
 
-       return g_string_free (buffer, FALSE);
+       return str;
 }
 
 static ECalComponent *
 create_weather (ECalBackendWeather *cbw,
                 GWeatherInfo *report,
                 GWeatherTemperatureUnit unit,
-                gboolean is_forecast)
+                gboolean is_forecast,
+               GSList *same_day_forecasts)
 {
        ECalComponent             *cal_comp;
        ECalComponentText          comp_summary;
@@ -384,7 +466,7 @@ create_weather (ECalBackendWeather *cbw,
        struct icaltimetype        itt;
        ECalComponentDateTime      dt;
        gchar                     *uid;
-       GSList                    *text_list = NULL;
+       GSList                    *text_list = NULL, *link;
        ECalComponentText         *description;
        gchar                     *tmp, *city_name;
        time_t                     update_time;
@@ -466,12 +548,12 @@ create_weather (ECalBackendWeather *cbw,
        e_cal_component_set_summary (cal_comp, &comp_summary);
        g_free ((gchar *) comp_summary.value);
 
-       tmp = cal_weather_get_info_forecast_text (report);
        comp_summary.value = gweather_info_get_weather_summary (report);
 
        description = g_new0 (ECalComponentText, 1);
        {
                GString *builder;
+               gboolean has_forecast_word = FALSE;
 
                builder = g_string_new (NULL);
 
@@ -479,12 +561,60 @@ create_weather (ECalBackendWeather *cbw,
                        g_string_append (builder, comp_summary.value);
                        g_string_append_c (builder, '\n');
                }
-               if (tmp && *tmp) {
-                       g_string_append (builder, _("Forecast"));
-                       g_string_append_c (builder, ':');
-                       if (!is_forecast)
-                               g_string_append_c (builder, '\n');
-                       g_string_append (builder, tmp);
+
+               tmp = NULL;
+
+               for (link = gweather_info_get_forecast_list (report); link; link = g_slist_next (link)) {
+                       GWeatherInfo *nfo = link->data;
+
+                       if (nfo) {
+                               tmp = describe_forecast (nfo, unit);
+
+                               if (tmp && *tmp) {
+                                       if (!has_forecast_word) {
+                                               has_forecast_word = TRUE;
+
+                                               g_string_append (builder, _("Forecast"));
+                                               g_string_append_c (builder, ':');
+                                               g_string_append_c (builder, '\n');
+                                       }
+
+                                       g_string_append (builder, tmp);
+                                       g_string_append_c (builder, '\n');
+                               }
+
+                               g_free (tmp);
+                               tmp = NULL;
+                       }
+               }
+
+               if (same_day_forecasts) {
+                       g_free (tmp);
+                       tmp = NULL;
+
+                       for (link = same_day_forecasts; link; link = g_slist_next (link)) {
+                               GWeatherInfo *nfo = link->data;
+
+                               if (nfo) {
+                                       tmp = describe_forecast (nfo, unit);
+
+                                       if (tmp && *tmp) {
+                                               if (!has_forecast_word) {
+                                                       has_forecast_word = TRUE;
+
+                                                       g_string_append (builder, _("Forecast"));
+                                                       g_string_append_c (builder, ':');
+                                                       g_string_append_c (builder, '\n');
+                                               }
+
+                                               g_string_append (builder, tmp);
+                                               g_string_append_c (builder, '\n');
+                                       }
+
+                                       g_free (tmp);
+                                       tmp = NULL;
+                               }
+                       }
                }
 
                description->value = g_string_free (builder, FALSE);


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