diff -up evolution-data-server-3.12.11/calendar/backends/weather/e-cal-backend-weather.c.weather-calendar-merge-day-forecasts evolution-data-server-3.12.11/calendar/backends/weather/e-cal-backend-weather.c --- evolution-data-server-3.12.11/calendar/backends/weather/e-cal-backend-weather.c.weather-calendar-merge-day-forecasts 2014-03-24 10:07:52.000000000 +0100 +++ evolution-data-server-3.12.11/calendar/backends/weather/e-cal-backend-weather.c 2015-05-21 16:07:41.897961486 +0200 @@ -46,7 +46,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, @@ -157,6 +158,27 @@ put_component_to_store (ECalBackendWeath 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) @@ -202,31 +224,83 @@ finished_retrieval_cb (GWeatherInfo *inf 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, ¤t_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); } } @@ -341,11 +415,53 @@ cal_backend_weather_get_temp (gdouble va return g_strdup_printf (_("%.1f"), value); } +static gchar * +describe_forecast (GWeatherInfo *nfo, + GWeatherTemperatureUnit unit) +{ + 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 (gweather_info_get_value_temp_min (nfo, unit, &tmin) && + gweather_info_get_value_temp_max (nfo, unit, &tmax) && + tmin != tmax) { + gchar *min, *max; + + min = cal_backend_weather_get_temp (tmin, unit); + max = cal_backend_weather_get_temp (tmax, unit); + + temp = g_strdup_printf ("%s / %s", min, max); + + 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); + } + + str = g_strdup_printf (" * %s: %s, %s", date, summary, temp); + + g_free (date); + g_free (summary); + g_free (temp); + + 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; @@ -353,7 +469,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; @@ -435,12 +551,12 @@ create_weather (ECalBackendWeather *cbw, e_cal_component_set_summary (cal_comp, &comp_summary); g_free ((gchar *) comp_summary.value); - tmp = gweather_info_get_forecast (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); @@ -448,12 +564,60 @@ create_weather (ECalBackendWeather *cbw, g_string_append (builder, comp_summary.value); g_string_append_c (builder, '\n'); } - if (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);