[evolution-data-server] Build against new gweather

Matthias Clasen mclasen at fedoraproject.org
Wed Jun 27 10:57:31 UTC 2012


commit 36770b9ab75d31e46fae7f27dc0026538b3560ab
Author: Matthias Clasen <mclasen at redhat.com>
Date:   Wed Jun 27 06:58:37 2012 -0400

    Build against new gweather

 evolution-data-server.spec |    9 +-
 new-gweather-api.patch     | 1032 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1040 insertions(+), 1 deletions(-)
---
diff --git a/evolution-data-server.spec b/evolution-data-server.spec
index d17f1c5..4394a38 100644
--- a/evolution-data-server.spec
+++ b/evolution-data-server.spec
@@ -27,7 +27,7 @@
 
 Name: evolution-data-server
 Version: 3.5.3
-Release: 1%{?dist}
+Release: 2%{?dist}
 Group: System Environment/Libraries
 Summary: Backend data server for Evolution
 License: LGPLv2+
@@ -43,6 +43,9 @@ Obsoletes: evolution-webcal < 2.24.0
 # RH bug #243296
 Patch01: evolution-data-server-1.11.5-fix-64bit-acinclude.patch
 
+# http://bugzilla.gnome.org/show_bug.cgi?id=672805
+Patch2: new-gweather-api.patch
+
 ### Build Dependencies ###
 
 BuildRequires: bison
@@ -123,6 +126,7 @@ This package contains developer documentation for %{name}.
 %setup -q
 
 %patch01 -p1 -b .fix-64bit-acinclude
+%patch2 -p1 -b .new-gweather-api
 
 mkdir -p krb5-fakeprefix/include
 mkdir -p krb5-fakeprefix/lib
@@ -367,6 +371,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &>/dev/null || :
 %{_datadir}/gtk-doc/html/libedataserverui
 
 %changelog
+* Wed Jun 27 2012 Matthias Clasen <mclasen at redhat.com> - 3.5.3-2
+- Build against libgweather 3.5
+
 * Mon Jun 25 2012 Matthew Barnes <mbarnes at redhat.com> - 3.5.3-1
 - Update to 3.5.3
 - Add BR: gcr-devel >= 3.4
diff --git a/new-gweather-api.patch b/new-gweather-api.patch
new file mode 100644
index 0000000..dd27d51
--- /dev/null
+++ b/new-gweather-api.patch
@@ -0,0 +1,1032 @@
+From 1b5f527757ea7e6aa1ccc822c91449b541521a40 Mon Sep 17 00:00:00 2001
+From: Giovanni Campagna <gcampagna at src.gnome.org>
+Date: Sat, 24 Mar 2012 01:06:02 +0100
+Subject: [PATCH] weather: update for newer GWeather
+
+GWeather 3.6 changed API to be properly namespaced and GObject based.
+Also, WeatherLocation was removed and replaced with GWeatherLocation
+in all public API (with additionally the possibility to retrieve one
+particular GWeatherLocation by station code)
+At the same time, remove a old and now useless abstration by folding
+EWeatherSourceCCF into EWeatherSource.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=672805
+---
+ calendar/backends/weather/Makefile.am             |    4 +-
+ calendar/backends/weather/e-cal-backend-weather.c |  112 +++--
+ calendar/backends/weather/e-weather-source-ccf.c  |  468 ---------------------
+ calendar/backends/weather/e-weather-source-ccf.h  |   76 ----
+ calendar/backends/weather/e-weather-source.c      |   87 +++-
+ calendar/backends/weather/e-weather-source.h      |   44 +-
+ configure.ac                                      |    7 +-
+ 7 files changed, 133 insertions(+), 665 deletions(-)
+ delete mode 100644 calendar/backends/weather/e-weather-source-ccf.c
+ delete mode 100644 calendar/backends/weather/e-weather-source-ccf.h
+
+diff --git a/calendar/backends/weather/Makefile.am b/calendar/backends/weather/Makefile.am
+index ed41cf2..25ee7a9 100644
+--- a/calendar/backends/weather/Makefile.am
++++ b/calendar/backends/weather/Makefile.am
+@@ -25,9 +25,7 @@ libecalbackendweather_la_SOURCES =	\
+ 	e-source-weather.c		\
+ 	e-source-weather.h		\
+ 	e-weather-source.c		\
+-	e-weather-source.h		\
+-	e-weather-source-ccf.c		\
+-	e-weather-source-ccf.h
++	e-weather-source.h
+ 
+ libecalbackendweather_la_LIBADD =					\
+ 	$(top_builddir)/calendar/libecal/libecal-1.2.la			\
+diff --git a/calendar/backends/weather/e-cal-backend-weather.c b/calendar/backends/weather/e-cal-backend-weather.c
+index 62357ae..632c5f2 100644
+--- a/calendar/backends/weather/e-cal-backend-weather.c
++++ b/calendar/backends/weather/e-cal-backend-weather.c
+@@ -27,7 +27,7 @@
+ #include "e-weather-source.h"
+ 
+ #define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+-#include <libgweather/weather.h>
++#include <libgweather/gweather-weather.h>
+ #undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+ 
+ #define WEATHER_UID_EXT "-weather"
+@@ -43,7 +43,7 @@ G_DEFINE_TYPE (ECalBackendWeather, e_cal_backend_weather, E_TYPE_CAL_BACKEND_SYN
+ 
+ static gboolean reload_cb (ECalBackendWeather *cbw);
+ static gboolean begin_retrieval_cb (ECalBackendWeather *cbw);
+-static ECalComponent * create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_forecast);
++static ECalComponent * create_weather (ECalBackendWeather *cbw, GWeatherInfo *report, gboolean is_forecast);
+ static void e_cal_backend_weather_add_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzobj, GError **perror);
+ 
+ /* Private part of the ECalBackendWeather structure */
+@@ -158,7 +158,7 @@ put_component_to_store (ECalBackendWeather *cb,
+ }
+ 
+ static void
+-finished_retrieval_cb (WeatherInfo *info,
++finished_retrieval_cb (GWeatherInfo *info,
+                        ECalBackendWeather *cbw)
+ {
+ 	ECalBackendWeatherPrivate *priv;
+@@ -197,13 +197,13 @@ finished_retrieval_cb (WeatherInfo *info,
+ 		e_cal_backend_notify_component_created (E_CAL_BACKEND (cbw), comp);
+ 		g_object_unref (comp);
+ 
+-		forecasts = weather_info_get_forecast_list (info);
++		forecasts = gweather_info_get_forecast_list (info);
+ 		if (forecasts) {
+ 			GSList *f;
+ 
+ 			/* skip the first one, it's for today, which has been added above */
+ 			for (f = forecasts->next; f; f = f->next) {
+-				WeatherInfo *nfo = f->data;
++				GWeatherInfo *nfo = f->data;
+ 
+ 				if (nfo) {
+ 					comp = create_weather (cbw, nfo, TRUE);
+@@ -267,7 +267,7 @@ begin_retrieval_cb (ECalBackendWeather *cbw)
+ }
+ 
+ static const gchar *
+-getCategory (WeatherInfo *report)
++getCategory (GWeatherInfo *report)
+ {
+ 	struct {
+ 		const gchar *description;
+@@ -286,7 +286,7 @@ getCategory (WeatherInfo *report)
+ 	};
+ 
+ 	gint i;
+-	const gchar *icon_name = weather_info_get_icon_name (report);
++	const gchar *icon_name = gweather_info_get_icon_name (report);
+ 
+ 	if (!icon_name)
+ 		return NULL;
+@@ -302,7 +302,7 @@ getCategory (WeatherInfo *report)
+ 
+ static ECalComponent *
+ create_weather (ECalBackendWeather *cbw,
+-                WeatherInfo *report,
++                GWeatherInfo *report,
+                 gboolean is_forecast)
+ {
+ 	ECalBackendWeatherPrivate *priv;
+@@ -314,34 +314,19 @@ create_weather (ECalBackendWeather *cbw,
+ 	gchar			  *uid;
+ 	GSList                    *text_list = NULL;
+ 	ECalComponentText         *description;
+-	ESource                   *source;
+-	const gchar               *tmp;
++	gchar                     *tmp;
+ 	time_t			   update_time;
+ 	icaltimezone		  *update_zone = NULL;
+-	ESourceWeather            *extension;
+-	const gchar               *extension_name;
+-	const WeatherLocation     *location;
+-	ESourceWeatherUnits        units;
++	const GWeatherLocation    *location;
++	const GWeatherTimezone    *w_timezone;
+ 
+ 	g_return_val_if_fail (E_IS_CAL_BACKEND_WEATHER (cbw), NULL);
+ 
+-	if (!weather_info_get_value_update (report, &update_time))
++	if (!gweather_info_get_value_update (report, &update_time))
+ 		return NULL;
+ 
+ 	priv = cbw->priv;
+ 
+-	source = e_backend_get_source (E_BACKEND (cbw));
+-
+-	extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
+-	extension = e_source_get_extension (source, extension_name);
+-	units = e_source_weather_get_units (extension);
+-
+-	/* Prefer metric if units is invalid. */
+-	if (units == E_SOURCE_WEATHER_UNITS_IMPERIAL)
+-		weather_info_to_imperial (report);
+-	else
+-		weather_info_to_metric (report);
+-
+ 	/* create the component and event object */
+ 	ical_comp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
+ 	cal_comp = e_cal_component_new ();
+@@ -353,9 +338,9 @@ create_weather (ECalBackendWeather *cbw,
+ 	g_free (uid);
+ 
+ 	/* use timezone of the location to determine date for which this is set */
+-	location = weather_info_get_location (report);
+-	if (location && location->tz_hint && *location->tz_hint)
+-		update_zone = icaltimezone_get_builtin_timezone (location->tz_hint);
++	location = gweather_info_get_location (report);
++	if (location && (w_timezone = gweather_location_get_timezone ((GWeatherLocation *)location)))
++		update_zone = icaltimezone_get_builtin_timezone (gweather_timezone_get_tzid ((GWeatherTimezone*)w_timezone));
+ 
+ 	if (!update_zone)
+ 		update_zone = icaltimezone_get_utc_timezone ();
+@@ -380,53 +365,56 @@ create_weather (ECalBackendWeather *cbw,
+ 	/* We have to add 1 day to DTEND, as it is not inclusive. */
+ 	e_cal_component_set_dtend (cal_comp, &dt);
+ 
+-	if (is_forecast) {
++	{
+ 		gdouble tmin = 0.0, tmax = 0.0;
+ 
+-		if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) &&
+-		    weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &tmax) &&
++		if (gweather_info_get_value_temp_min (report, GWEATHER_TEMP_UNIT_DEFAULT, &tmin) &&
++		    gweather_info_get_value_temp_max (report, GWEATHER_TEMP_UNIT_DEFAULT, &tmax) &&
+ 		    tmin != tmax) {
+-			/* because weather_info_get_temp* uses one internal buffer, thus finally
+-			 * the last value is shown for both, which is obviously wrong */
+-			GString *str = g_string_new (priv->city);
++			gchar *min, *max;
+ 
+-			g_string_append (str, " : ");
+-			g_string_append (str, weather_info_get_temp_min (report));
+-			g_string_append (str, "/");
+-			g_string_append (str, weather_info_get_temp_max (report));
++			min = gweather_info_get_temp_min (report);
++			max = gweather_info_get_temp_max (report);
++			comp_summary.value = g_strdup_printf ("%s : %s / %s", priv->city, min, max);
+ 
+-			comp_summary.value = g_string_free (str, FALSE);
++			g_free (min); g_free (max);
+ 		} else {
+-			comp_summary.value = g_strdup_printf ("%s : %s", priv->city, weather_info_get_temp (report));
+-		}
+-	} else {
+-		gdouble tmin = 0.0, tmax = 0.0;
+-		/* because weather_info_get_temp* uses one internal buffer, thus finally
+-		 * the last value is shown for both, which is obviously wrong */
+-		GString *str = g_string_new (priv->city);
++			gchar *temp;
+ 
+-		g_string_append (str, " : ");
+-		if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) &&
+-		    weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &tmax) &&
+-		    tmin != tmax) {
+-			g_string_append (str, weather_info_get_temp_min (report));
+-			g_string_append (str, "/");
+-			g_string_append (str, weather_info_get_temp_max (report));
+-		} else {
+-			g_string_append (str, weather_info_get_temp (report));
+-		}
++			temp = gweather_info_get_temp (report);
++			comp_summary.value = g_strdup_printf ("%s : %s", priv->city, temp);
+ 
+-		comp_summary.value = g_string_free (str, FALSE);
++			g_free (temp);
++		}
+ 	}
+ 	comp_summary.altrep = NULL;
+ 	e_cal_component_set_summary (cal_comp, &comp_summary);
+ 	g_free ((gchar *) comp_summary.value);
+ 
+-	tmp = weather_info_get_forecast (report);
+-	comp_summary.value = weather_info_get_weather_summary (report);
++	tmp = gweather_info_get_forecast (report);
++	comp_summary.value = gweather_info_get_weather_summary (report);
+ 
+ 	description = g_new0 (ECalComponentText, 1);
+-	description->value = g_strconcat (is_forecast ? "" : comp_summary.value, is_forecast ? "" : "\n", tmp ? _("Forecast") : "", tmp ? ":" : "", tmp && !is_forecast ? "\n" : "", tmp ? tmp : "", NULL);
++	{
++		GString *builder;
++
++		builder = g_string_new (NULL);
++
++		if (!is_forecast) {
++			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);
++		}
++
++		description->value = g_string_free (builder, FALSE);
++		g_free (tmp);
++	}
+ 	description->altrep = "";
+ 	text_list = g_slist_append (text_list, description);
+ 	e_cal_component_set_description_list (cal_comp, text_list);
+diff --git a/calendar/backends/weather/e-weather-source-ccf.c b/calendar/backends/weather/e-weather-source-ccf.c
+deleted file mode 100644
+index 2bb76a5..0000000
+--- a/calendar/backends/weather/e-weather-source-ccf.c
++++ /dev/null
+@@ -1,468 +0,0 @@
+-/* Evolution calendar - weather backend source class for parsing
+- *	CCF (coded cities forecast) formatted NWS reports
+- *
+- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+- *
+- * Authors: David Trowbridge <trowbrds at cs.colorado.edu>
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of version 2 of the GNU Lesser General Public
+- * License as published by the Free Software Foundation.
+- *
+- * 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 Lesser General Public License for more details.
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#include <config.h>
+-#endif
+-
+-#include <string.h>
+-#include <stdlib.h>
+-
+-#include <glib/gi18n-lib.h>
+-
+-#include "e-weather-source-ccf.h"
+-
+-#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+-#include <libgweather/weather.h>
+-#include <libgweather/gweather-xml.h>
+-#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+-
+-#ifdef G_OS_WIN32
+-
+-#ifdef localtime_r
+-#undef localtime_r
+-#endif
+-
+-/* The localtime() in Microsoft's C library is MT-safe */
+-#define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
+-
+-/* strtok() is also MT-safe (but not stateless, still uses only one
+- * buffer pointer per thread, but for the use of strtok_r() here
+- * that's enough).
+- */
+-#define strtok_r(s,sep,lasts) (*(lasts)=strtok((s),(sep)))
+-#endif
+-
+-G_DEFINE_TYPE (EWeatherSourceCCF, e_weather_source_ccf, E_TYPE_WEATHER_SOURCE)
+-
+-struct search_struct
+-{
+-	const gchar *code;
+-	const gchar *name;
+-	gboolean is_old;
+-	WeatherLocation *location;
+-};
+-
+-static gboolean
+-find_location_func (GtkTreeModel *model,
+-                    GtkTreePath *path,
+-                    GtkTreeIter *node,
+-                    gpointer data)
+-{
+-	WeatherLocation *wl = NULL;
+-	struct search_struct *search = (struct search_struct *) data;
+-
+-	gtk_tree_model_get (model, node, GWEATHER_XML_COL_POINTER, &wl, -1);
+-	if (!wl || !wl->name || !wl->code || !search || search->location)
+-		return FALSE;
+-
+-	if (((!strcmp (wl->code, search->code)) || (search->is_old && !strcmp (wl->code + 1, search->code))) &&
+-	     (!strcmp (wl->name, search->name))) {
+-		search->location = weather_location_clone (wl);
+-		return TRUE;
+-	}
+-
+-	return FALSE;
+-}
+-
+-static WeatherLocation *
+-find_location (const gchar *code_name,
+-               gboolean is_old)
+-{
+-	GtkTreeModel *model;
+-	gchar **ids;
+-	struct search_struct search;
+-
+-	search.location = NULL;
+-
+-	ids = g_strsplit (code_name, "/", 2);
+-
+-	if (!ids || !ids[0] || !ids[1])
+-		goto done;
+-
+-	model = gweather_xml_load_locations ();
+-	if (!model)
+-		goto done;
+-
+-	search.code = ids[0];
+-	search.name = ids[1];
+-	search.is_old = is_old;
+-	search.location = NULL;
+-
+-	gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) find_location_func, &search);
+-
+-	gweather_xml_free_locations (model);
+-	g_strfreev (ids);
+-
+-done:
+-	return search.location;
+-}
+-
+-#if 0
+-static GSList *
+-tokenize (gchar *buffer)
+-{
+-	gchar *token;
+-	gchar *tokbuf;
+-	GSList *ret;
+-
+-	token = strtok_r (buffer, " \n", &tokbuf);
+-	ret = g_slist_append (NULL, g_strdup (token));
+-	while ((token = strtok_r (NULL, " \n/", &tokbuf)))
+-		ret = g_slist_append (ret, g_strdup (token));
+-	return ret;
+-}
+-
+-static void
+-date2tm (gchar *date,
+-         struct tm *times)
+-{
+-	gchar tmp[3];
+-	time_t curtime = time (NULL);
+-	tmp[2] = '\0';
+-
+-	localtime_r (&curtime, times);
+-
+-	tmp[0] = date[0]; tmp[1] = date[1];
+-	times->tm_mday = atoi (tmp);
+-	tmp[0] = date[2]; tmp[1] = date[3];
+-	times->tm_hour = atoi (tmp);
+-	tmp[0] = date[4]; tmp[1] = date[5];
+-	times->tm_min = atoi (tmp);
+-}
+-
+-static WeatherConditions
+-decodeConditions (gchar code)
+-{
+-	switch (code) {
+-		case 'A': return WEATHER_FAIR;
+-		case 'B': return WEATHER_PARTLY_CLOUDY;
+-		case 'C': return WEATHER_CLOUDY;
+-		case 'D': return WEATHER_DUST;
+-		case 'E': return WEATHER_MOSTLY_CLOUDY;
+-		case 'F': return WEATHER_FOGGY;
+-		case 'G': return WEATHER_VERY_HOT_OR_HOT_HUMID;
+-		case 'H': return WEATHER_HAZE;
+-		case 'I': return WEATHER_VERY_COLD_WIND_CHILL;
+-		case 'J': return WEATHER_SNOW_SHOWERS;
+-		case 'K': return WEATHER_SMOKE;
+-		case 'L': return WEATHER_DRIZZLE;
+-		case 'M': return WEATHER_SNOW_SHOWERS;
+-		case 'N': return WEATHER_WINDY;
+-		case 'O': return WEATHER_RAIN_OR_SNOW_MIXED;
+-		case 'P': return WEATHER_BLIZZARD;
+-		case 'Q': return WEATHER_BLOWING_SNOW;
+-		case 'R': return WEATHER_RAIN;
+-		case 'S': return WEATHER_SNOW;
+-		case 'T': return WEATHER_THUNDERSTORMS;
+-		case 'U': return WEATHER_SUNNY;
+-		case 'V': return WEATHER_CLEAR;
+-		case 'W': return WEATHER_RAIN_SHOWERS;
+-		case 'X': return WEATHER_SLEET;
+-		case 'Y': return WEATHER_FREEZING_RAIN;
+-		case 'Z': return WEATHER_FREEZING_DRIZZLE;
+-		/* hmm, this should never happen. */
+-		default: return WEATHER_SUNNY;
+-	}
+-}
+-
+-static gint
+-decodePOP (gchar data)
+-{
+-	gint ret;
+-
+-	switch (data) {
+-		case '-':
+-			ret = 5;
+-			break;
+-		case '+':
+-			ret = 95;
+-			break;
+-		case '/':
+-			ret = -1;	/* missing data */
+-			break;
+-		default:
+-			ret = (data - '0') * 10;
+-	}
+-	return ret;
+-}
+-
+-static void
+-decodeSnowfall (gchar *data,
+-                gfloat *low,
+-                gfloat *high)
+-{
+-	gchar num[3];
+-	num[2] = '\0';
+-
+-	num[0] = data[0]; num[1] = data[1];
+-	*low = atof (num) * 2.54f;
+-	num[0] = data[2]; num[1] = data[3];
+-	*high = atof (num) * 2.54f;
+-}
+-
+-static float
+-ftoc (gchar *data)
+-{
+-	gint fahrenheit = atoi (data);
+-	if (fahrenheit >= 900)
+-		fahrenheit = (fahrenheit - 900) * -1;
+-	return ((gfloat)(fahrenheit - 32)) * 5.0f / 9.0f;
+-}
+-
+-static void
+-e_weather_source_ccf_do_parse (EWeatherSourceCCF *source,
+-                               gchar *buffer)
+-{
+-	/* CCF gives us either 2 or 7 days of forecast data. IFPS WFO's
+-	 * will produce 7 day forecasts, whereas pre-IFPS WFO's are only
+-	 * mandated 2 (but may do 7). The morning forecast will give us either 2
+-	 * or 7 days worth of data. The evening forecast will give us the evening's
+-	 * low temperature plus 2 or 7 days forecast.
+-	 *
+-	 * The CCF format is described in NWS directive 10-503, but it's usually
+-	 * easier to look at a summary put up by one of the stations:
+-	 * http://www.crh.noaa.gov/lmk/product_guide/products/forecast/ccf.htm
+-	 */
+-	WeatherForecast *forecasts = g_new0 (WeatherForecast, 7);
+-	GSList *tokens = tokenize (buffer);
+-	GSList *date;
+-	GSList *current = tokens;
+-	GList *fc = NULL;
+-	struct tm tms;
+-	gint i;
+-	time_t base;
+-	gint n;
+-
+-	date = g_slist_nth (tokens, 3);
+-	date2tm (date->data, &tms);
+-
+-	/* fast-forward to the particular station we're interested in */
+-	current = g_slist_nth (tokens, 5);
+-	while (strcmp (current->data, source->substation))
+-		current = g_slist_next (current);
+-	current = g_slist_next (current);
+-	/* pick up the first two conditions reports */
+-	forecasts[0].conditions = decodeConditions (((gchar *)(current->data))[0]);
+-	forecasts[1].conditions = decodeConditions (((gchar *)(current->data))[1]);
+-
+-	current = g_slist_next (current);
+-	if (tms.tm_hour < 12) {
+-		for (i = 0; i < 2; i++) {
+-			forecasts[i].high = ftoc (current->data);
+-			current = g_slist_next (current);
+-			forecasts[i].low  = ftoc (current->data);
+-			current = g_slist_next (current);
+-		}
+-		forecasts[2].high = ftoc (current->data);
+-		current = g_slist_next (current);
+-		forecasts[0].pop = decodePOP (((gchar *)(current->data))[2]);
+-		forecasts[1].pop = decodePOP (((gchar *)(current->data))[4]);
+-	} else {
+-		for (i = 0; i < 2; i++) {
+-			current = g_slist_next (current);
+-			forecasts[i].high = ftoc (current->data);
+-			current = g_slist_next (current);
+-			forecasts[i].low  = ftoc (current->data);
+-		}
+-		current = g_slist_next (current);
+-		forecasts[0].pop = decodePOP (((gchar *)(current->data))[1]);
+-		forecasts[1].pop = decodePOP (((gchar *)(current->data))[3]);
+-	}
+-
+-	current = g_slist_next (current);
+-	if (strlen (current->data) == 4) {
+-		/* we've got the optional snowfall field */
+-		if (tms.tm_hour < 12) {
+-			decodeSnowfall (current->data, &forecasts[0].low, &forecasts[0].high);
+-			current = g_slist_next (g_slist_next (current));
+-			decodeSnowfall (current->data, &forecasts[1].low, &forecasts[1].high);
+-		} else {
+-			current = g_slist_next (current);
+-			decodeSnowfall (current->data, &forecasts[0].low, &forecasts[0].high);
+-		}
+-		current = g_slist_next (current);
+-	}
+-
+-	/* set dates */
+-	base = mktime (&tms);
+-	if (tms.tm_hour >= 12)
+-		base += 43200;
+-	for (i = 0; i < 7; i++)
+-		forecasts[i].date = base + 86400 * i;
+-
+-	if (current == NULL || strlen (current->data) == 3) {
+-		/* We've got a pre-IFPS station. Realloc and return */
+-		WeatherForecast *f = g_new0 (WeatherForecast, 2);
+-		memcpy (f, forecasts, sizeof (WeatherForecast) * 2);
+-		fc = g_list_append (fc, &f[0]);
+-		fc = g_list_append (fc, &f[1]);
+-		source->done (fc, source->finished_data);
+-	}
+-
+-	/* Grab the conditions for the next 5 days */
+-	forecasts[2].conditions = decodeConditions (((gchar *)(current->data))[0]);
+-	forecasts[3].conditions = decodeConditions (((gchar *)(current->data))[1]);
+-	forecasts[4].conditions = decodeConditions (((gchar *)(current->data))[2]);
+-	forecasts[5].conditions = decodeConditions (((gchar *)(current->data))[3]);
+-	forecasts[6].conditions = decodeConditions (((gchar *)(current->data))[4]);
+-
+-	/* Temperature forecasts */
+-	current = g_slist_next (current);
+-	if (tms.tm_hour < 12) {
+-		forecasts[2].low  = ftoc (current->data);
+-		for  (i = 3; i < 6; i++) {
+-			current = g_slist_next (current);
+-			forecasts[i].high = ftoc (current->data);
+-			current = g_slist_next (current);
+-			forecasts[i].low  = ftoc (current->data);
+-		}
+-		current = g_slist_next (current);
+-		forecasts[6].high = ftoc (current->data);
+-		forecasts[6].low  = forecasts[6].high;
+-		current = g_slist_next (current);
+-		forecasts[2].pop = decodePOP (((gchar *)(current->data))[1]);
+-		forecasts[3].pop = decodePOP (((gchar *)(current->data))[3]);
+-		forecasts[4].pop = decodePOP (((gchar *)(current->data))[5]);
+-		forecasts[5].pop = decodePOP (((gchar *)(current->data))[7]);
+-		forecasts[6].pop = decodePOP (((gchar *)(current->data))[9]);
+-		n = 7;
+-	} else {
+-		for (i = 2; i < 6; i++) {
+-			forecasts[i].high = ftoc (current->data);
+-			current = g_slist_next (current);
+-			forecasts[i].low  = ftoc (current->data);
+-			current = g_slist_next (current);
+-		}
+-		n = 6;
+-		/* hack for people who put out bad data, like Pueblo, CO. Yes, PUB, that means you */
+-		if (strlen (current->data) == 3)
+-			current = g_slist_next (current);
+-		forecasts[1].pop = decodePOP (((gchar *)(current->data))[0]);
+-		forecasts[2].pop = decodePOP (((gchar *)(current->data))[2]);
+-		forecasts[3].pop = decodePOP (((gchar *)(current->data))[4]);
+-		forecasts[4].pop = decodePOP (((gchar *)(current->data))[6]);
+-		forecasts[5].pop = decodePOP (((gchar *)(current->data))[8]);
+-	}
+-
+-	for (i = 0; i < n; i++) {
+-		fc = g_list_append (fc, &forecasts[i]);
+-	}
+-	source->done (fc, source->finished_data);
+-
+-	g_free (forecasts);
+-	g_list_free (fc);
+-}
+-#endif
+-
+-static void
+-parse_done (WeatherInfo *info,
+-            gpointer data)
+-{
+-	EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF *) data;
+-
+-	if (!ccfsource)
+-		return;
+-
+-	if (!info || !weather_info_is_valid (info)) {
+-		ccfsource->done (NULL, ccfsource->finished_data);
+-		return;
+-	}
+-
+-	ccfsource->done (info, ccfsource->finished_data);
+-}
+-
+-static void
+-e_weather_source_ccf_parse (EWeatherSource *source,
+-                            EWeatherSourceFinished done,
+-                            gpointer data)
+-{
+-	EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF *) source;
+-	WeatherPrefs prefs;
+-
+-	ccfsource->finished_data = data;
+-	ccfsource->done = done;
+-
+-	prefs.type = FORECAST_LIST;
+-	prefs.radar = FALSE;
+-	prefs.radar_custom_url = NULL;
+-	prefs.temperature_unit = TEMP_UNIT_CENTIGRADE;
+-	prefs.speed_unit = SPEED_UNIT_MS;
+-	prefs.pressure_unit = PRESSURE_UNIT_HPA;
+-	prefs.distance_unit = DISTANCE_UNIT_METERS;
+-
+-	if (ccfsource->location && !ccfsource->info) {
+-		ccfsource->info = weather_info_new (ccfsource->location, &prefs, parse_done, source);
+-		weather_location_free (ccfsource->location);
+-		ccfsource->location = NULL;
+-	} else {
+-		ccfsource->info = weather_info_update (ccfsource->info, &prefs, parse_done, source);
+-	}
+-}
+-
+-static void
+-e_weather_source_ccf_class_init (EWeatherSourceCCFClass *class)
+-{
+-	EWeatherSourceClass *source_class;
+-
+-	source_class = E_WEATHER_SOURCE_CLASS (class);
+-	source_class->parse = e_weather_source_ccf_parse;
+-}
+-
+-static void
+-e_weather_source_ccf_init (EWeatherSourceCCF *source)
+-{
+-	source->location = NULL;
+-	source->info = NULL;
+-}
+-
+-EWeatherSource *
+-e_weather_source_ccf_new (const gchar *location)
+-{
+-	/* Old location is formatted as ccf/AAA[/BBB] - AAA is the 3-letter
+-	 * station code for identifying the providing station (subdirectory
+-	 * within the crh data repository). BBB is an optional additional
+-	 * station ID for the station within the CCF file. If not present,
+-	 * BBB is assumed to be the same station as AAA.  But the new
+-	 * location is code/name, where code is 4-letter code.  So if we
+-	 * got the old format, then migrate to the new one, if possible.
+-	 */
+-
+-	WeatherLocation *wl;
+-	EWeatherSourceCCF *source;
+-
+-	if (location == NULL)
+-		return NULL;
+-
+-	if (strncmp (location, "ccf/", 4) == 0)
+-		wl = find_location (location + 4, TRUE);
+-	else
+-		wl = find_location (location, FALSE);
+-
+-	if (wl == NULL)
+-		return NULL;
+-
+-	source = g_object_new (E_TYPE_WEATHER_SOURCE_CCF, NULL);
+-	source->location = wl;
+-	source->info = NULL;
+-
+-	return E_WEATHER_SOURCE (source);
+-}
+diff --git a/calendar/backends/weather/e-weather-source-ccf.h b/calendar/backends/weather/e-weather-source-ccf.h
+deleted file mode 100644
+index e0ae161..0000000
+--- a/calendar/backends/weather/e-weather-source-ccf.h
++++ /dev/null
+@@ -1,76 +0,0 @@
+-/* Evolution calendar - weather backend source class for parsing
+- *	CCF (coded cities forecast) formatted NWS reports
+- *
+- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+- *
+- * Authors: David Trowbridge <trowbrds at cs.colorado.edu>
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of version 2 of the GNU Lesser General Public
+- * License as published by the Free Software Foundation.
+- *
+- * 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 Lesser General Public License for more details.
+- *
+- * You should have received a copy of the GNU Lesser General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+- */
+-
+-#ifndef E_WEATHER_SOURCE_CCF_H
+-#define E_WEATHER_SOURCE_CCF_H
+-
+-#include <libsoup/soup-session-async.h>
+-#include <libsoup/soup-uri.h>
+-#include "e-weather-source.h"
+-
+-#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+-#include <libgweather/weather.h>
+-#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+-
+-/* Standard GObject macros */
+-#define E_TYPE_WEATHER_SOURCE_CCF \
+-	(e_weather_source_ccf_get_type ())
+-#define E_WEATHER_SOURCE_CCF(obj) \
+-	(G_TYPE_CHECK_INSTANCE_CAST \
+-	((obj), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
+-#define E_WEATHER_SOURCE_CCF_CLASS(cls) \
+-	(G_TYPE_CHECK_CLASS_CAST \
+-	((cls), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
+-#define E_IS_WEATHER_SOURCE_CCF(obj) \
+-	(G_TYPE_CHECK_INSTANCE_TYPE \
+-	((obj), E_TYPE_WEATHER_SOURCE_CCF))
+-#define E_IS_WEATHER_SOURCE_CCF_CLASS(cls) \
+-	(G_TYPE_CHECK_CLASS_TYPE \
+-	((cls), E_TYPE_WEATHER_SOURCE_CCF))
+-#define E_WEATHER_SOURCE_CCF_GET_CLASS(obj) \
+-	(G_TYPE_INSTANCE_GET_CLASS \
+-	((obj), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
+-
+-G_BEGIN_DECLS
+-
+-typedef struct _EWeatherSourceCCF EWeatherSourceCCF;
+-typedef struct _EWeatherSourceCCFClass EWeatherSourceCCFClass;
+-
+-struct _EWeatherSourceCCF {
+-	EWeatherSource parent;
+-
+-	WeatherLocation *location;
+-	WeatherInfo *info;
+-
+-	EWeatherSourceFinished done;
+-	gpointer finished_data;
+-};
+-
+-struct _EWeatherSourceCCFClass {
+-	EWeatherSourceClass parent_class;
+-};
+-
+-GType		e_weather_source_ccf_get_type	(void);
+-EWeatherSource *e_weather_source_ccf_new	(const gchar *location);
+-
+-G_END_DECLS
+-
+-#endif /* E_WEATHER_SOURCE_CCF_H */
+diff --git a/calendar/backends/weather/e-weather-source.c b/calendar/backends/weather/e-weather-source.c
+index 3dd3431..3cdbe3a 100644
+--- a/calendar/backends/weather/e-weather-source.c
++++ b/calendar/backends/weather/e-weather-source.c
+@@ -19,43 +19,102 @@
+  */
+ 
+ #include "e-weather-source.h"
+-#include "e-weather-source-ccf.h"
+ 
+ #include <string.h>
+ 
+ G_DEFINE_TYPE (EWeatherSource, e_weather_source, G_TYPE_OBJECT)
+ 
++static void
++parse_done (GWeatherInfo *info,
++            gpointer      data)
++{
++	EWeatherSource *source = (EWeatherSource *) data;
++
++	if (!source)
++		return;
++
++	if (!info || !gweather_info_is_valid (info)) {
++		source->done (NULL, source->finished_data);
++		return;
++	}
++
++	source->done (info, source->finished_data);
++}
++
+ void
+-e_weather_source_parse (EWeatherSource *source,
+-                        EWeatherSourceFinished done,
+-                        gpointer data)
++e_weather_source_parse (EWeatherSource         *source,
++			EWeatherSourceFinished  done,
++			gpointer                data)
+ {
+-	EWeatherSourceClass *class;
++	source->finished_data = data;
++	source->done = done;
+ 
+-	g_return_if_fail (source != NULL);
++	if (!source->info) {
++		source->info = gweather_info_new (source->location, GWEATHER_FORECAST_LIST);
++		g_signal_connect (source->info, "updated", G_CALLBACK (parse_done), source);
++	} else {
++		gweather_info_update (source->info);
++	}
++}
+ 
+-	class = E_WEATHER_SOURCE_GET_CLASS (source);
+-	g_return_if_fail (class->parse != NULL);
++static void
++e_weather_source_finalize (GObject *object)
++{
++	EWeatherSource *self = (EWeatherSource*) object;
++
++	if (self->location)
++		gweather_location_unref (self->location);
++	g_clear_object (&self->info);
+ 
+-	class->parse (source, done, data);
++	G_OBJECT_CLASS (e_weather_source_parent_class)->finalize (object);
+ }
+ 
+ static void
+-e_weather_source_class_init (EWeatherSourceClass *class)
++e_weather_source_class_init (EWeatherSourceClass *klass)
+ {
+-	/* nothing to do here */
++	GObjectClass *gobject_class;
++
++	gobject_class = G_OBJECT_CLASS (klass);
++	gobject_class->finalize = e_weather_source_finalize;
+ }
+ 
+ static void
+ e_weather_source_init (EWeatherSource *source)
+ {
+-	/* nothing to do here */
+ }
+ 
+ EWeatherSource *
+ e_weather_source_new (const gchar *location)
+ {
+-	g_return_val_if_fail (location != NULL, NULL);
++	GWeatherLocation *world, *glocation;
++	EWeatherSource *source;
++
++	/* Old location is formatted as ccf/AAA[/BBB] - AAA is the 3-letter station
++	 * code for identifying the providing station (subdirectory within the crh data
++	 * repository). BBB is an optional additional station ID for the station within
++	 * the CCF file. If not present, BBB is assumed to be the same station as AAA.
++	 * But the new location is code/name, where code is 4-letter code.
++	 * So if got the old format, then migrate to the new one, if possible.
++	 */
++
++	if (!location)
++		return NULL;
++
++	world = gweather_location_new_world (FALSE);
++	if (strncmp (location, "ccf/", 4) == 0)
++		glocation = gweather_location_find_by_station_code (world, location + 4);
++	else
++		glocation = gweather_location_find_by_station_code (world, location);
++	if (glocation)
++		gweather_location_ref (glocation);
++	gweather_location_unref (world);
++
++	if (!location)
++		return NULL;
++
++	source = E_WEATHER_SOURCE (g_object_new (e_weather_source_get_type (), NULL));
++	source->location = glocation;
++	source->info = NULL;
+ 
+-	return e_weather_source_ccf_new (location);
++	return source;
+ }
+diff --git a/calendar/backends/weather/e-weather-source.h b/calendar/backends/weather/e-weather-source.h
+index e36793e..793c2fa 100644
+--- a/calendar/backends/weather/e-weather-source.h
++++ b/calendar/backends/weather/e-weather-source.h
+@@ -25,7 +25,7 @@
+ #include <time.h>
+ 
+ #define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+-#include <libgweather/weather.h>
++#include <libgweather/gweather-weather.h>
+ #undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+ 
+ /* Standard GObject macros */
+@@ -49,35 +49,7 @@
+ 
+ G_BEGIN_DECLS
+ 
+-typedef enum {
+-	WEATHER_FAIR,
+-	WEATHER_SNOW_SHOWERS,
+-	WEATHER_SNOW,
+-	WEATHER_PARTLY_CLOUDY,
+-	WEATHER_SMOKE,
+-	WEATHER_THUNDERSTORMS,
+-	WEATHER_CLOUDY,
+-	WEATHER_DRIZZLE,
+-	WEATHER_SUNNY,
+-	WEATHER_DUST,
+-	WEATHER_CLEAR,
+-	WEATHER_MOSTLY_CLOUDY,
+-	WEATHER_WINDY,
+-	WEATHER_RAIN_SHOWERS,
+-	WEATHER_FOGGY,
+-	WEATHER_RAIN_OR_SNOW_MIXED,
+-	WEATHER_SLEET,
+-	WEATHER_VERY_HOT_OR_HOT_HUMID,
+-	WEATHER_BLIZZARD,
+-	WEATHER_FREEZING_RAIN,
+-	WEATHER_HAZE,
+-	WEATHER_BLOWING_SNOW,
+-	WEATHER_FREEZING_DRIZZLE,
+-	WEATHER_VERY_COLD_WIND_CHILL,
+-	WEATHER_RAIN,
+-} WeatherConditions;
+-
+-typedef void (*EWeatherSourceFinished)(WeatherInfo *result, gpointer data);
++typedef void (*EWeatherSourceFinished)(GWeatherInfo *result, gpointer data);
+ 
+ typedef struct _EWeatherSource EWeatherSource;
+ typedef struct _EWeatherSourceClass EWeatherSourceClass;
+@@ -87,16 +59,16 @@ typedef struct _EWeatherSourceClass EWeatherSourceClass;
+  * to know how to do is parse the specific format. */
+ struct _EWeatherSource {
+ 	GObject parent;
++
++	GWeatherLocation *location;
++	GWeatherInfo *info;
++
++	EWeatherSourceFinished done;
++	gpointer finished_data;
+ };
+ 
+ struct _EWeatherSourceClass {
+ 	GObjectClass parent_class;
+-
+-	/* Returns a list of WeatherForecast objects containing the
+-	 * data for the forecast. */
+-	void		(*parse)	(EWeatherSource *source,
+-					 EWeatherSourceFinished done,
+-					 gpointer data);
+ };
+ 
+ GType		e_weather_source_get_type	(void);
+diff --git a/configure.ac b/configure.ac
+index 6afe83d..41a7f7a 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -46,7 +46,7 @@ m4_define([libical_minimum_version], [0.43])
+ 
+ dnl Optional Packages
+ m4_define([goa_minimum_version], [3.2])
+-m4_define([gweather_minimum_version], [2.90.0])
++m4_define([gweather_minimum_version], [3.5.0])
+ 
+ AC_SUBST([BASE_VERSION],[base_version])
+ AC_SUBST([API_VERSION],[api_version])
+@@ -1103,11 +1103,6 @@ AC_MSG_RESULT([$use_gweather])
+ if test "x$use_gweather" = "xyes"; then
+ 	PKG_CHECK_MODULES([LIBGWEATHER], [gweather-3.0 >= gweather_minimum_version],[],
+ 	[AC_MSG_ERROR([The weather calendar backend requires GWeather >= gweather_minimum_version. Alternatively, you may specify --disable-weather as a configure option to avoid building the backend.])])
+-
+-	dnl gweather-3.5 introduces API changes we do not yet support.
+-	if `$PKG_CONFIG --atleast-version=3.5 gweather-3.0`; then
+-		AC_MSG_ERROR([gweather-3.5 is not yet supported.  Install gweather-3.4 or specify --disable-weather as a configure option to avoid building the backend.])
+-	fi
+ fi
+ AM_CONDITIONAL(ENABLE_WEATHER, [test $use_gweather = yes])
+ 
+-- 
+1.7.10.2
\ No newline at end of file


More information about the scm-commits mailing list