Index: configure.in
===================================================================
--- configure.in	(revision 9776)
+++ configure.in	(working copy)
@@ -32,6 +32,7 @@ m4_define([libxml_minimum_version], [2.0
 m4_define([libsoup_minimum_version], [2.3.0])
 m4_define([gnome_keyring_minimum_version], [2.20.1])
 m4_define([sqlite_minimum_version], [3.5])
+m4_define([gweather_minimum_version], [2.24.2])
 
 dnl *************************************************************************************************
 dnl Base Version
@@ -239,7 +240,8 @@ PKG_CHECK_MODULES(GNOME_PLATFORM,
          libglade-2.0 >= libglade_minimum_version
          libgnome-2.0 >= libgnome_minimum_version
          libxml-2.0 >= libxml_minimum_version
-         libsoup-2.4 >= libsoup_minimum_version])
+         libsoup-2.4 >= libsoup_minimum_version
+	 gweather >= gweather_minimum_version])
 
 dnl **************************************************
 dnl * regex checking
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 9776)
+++ ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+2008-11-21  Milan Crha  <mcrha@redhat.com>
+
+	** Part of fix for bug #352287
+
+	* configure.in: Require libgweather in configure stage.
+
 2008-11-12  Suman Manjunath  <msuman@novell.com>
 
 	* libedataserver/e-source.c (e_source_set_color), 
Index: calendar/ChangeLog
===================================================================
--- calendar/ChangeLog	(revision 9776)
+++ calendar/ChangeLog	(working copy)
@@ -1,3 +1,18 @@
+2008-11-21  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #352287
+
+	* backends/weather/Makefile.am:
+	* backends/weather/e-weather-source.h:
+	* backends/weather/e-weather-source.c: (e_weather_source_new):
+	* backends/weather/e-cal-backend-weather.c: (create_weather),
+	(finished_retrieval_cb), (getCategory):
+	* backends/weather/e-weather-source-ccf.h:
+	* backends/weather/e-weather-source-ccf.c: (e_weather_source_ccf_new),
+	(e_weather_source_ccf_parse), (find_location), (struct search_struct),
+	(parse_done), (find_location_func), (e_weather_source_ccf_init):
+	Share locations and forecast retrieving with libgweather.
+
 2008-11-19  Andrew McMillan  <andrew@morphoss.com>
 
 	** Fix for bug #560981
Index: calendar/backends/weather/e-weather-source.c
===================================================================
--- calendar/backends/weather/e-weather-source.c	(revision 9776)
+++ calendar/backends/weather/e-weather-source.c	(working copy)
@@ -70,7 +70,5 @@ EWeatherSource*	e_weather_source_new (co
 {
 	const char *base = uri + 10; /* skip weather:// */
 
-	if (strncmp (base, "ccf/", 4) == 0)
-		return e_weather_source_ccf_new (base);
-	return NULL;
+	return e_weather_source_ccf_new (base);
 }
Index: calendar/backends/weather/e-cal-backend-weather.c
===================================================================
--- calendar/backends/weather/e-cal-backend-weather.c	(revision 9776)
+++ calendar/backends/weather/e-cal-backend-weather.c	(working copy)
@@ -27,11 +27,15 @@
 #include "e-cal-backend-weather.h"
 #include "e-weather-source.h"
 
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include <libgweather/weather.h>
+#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+
 #define WEATHER_UID_EXT "-weather"
 
 static gboolean reload_cb (ECalBackendWeather *cbw);
 static gboolean begin_retrieval_cb (ECalBackendWeather *cbw);
-static ECalComponent* create_weather (ECalBackendWeather *cbw, WeatherForecast *report);
+static ECalComponent* create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_forecast);
 static ECalBackendSyncStatus
 e_cal_backend_weather_add_timezone (ECalBackendSync *backend, EDataCal *cal, const char *tzobj);
 
@@ -131,16 +135,17 @@ maybe_start_reload_timeout (ECalBackendW
 }
 
 static void
-finished_retrieval_cb (GList *forecasts, ECalBackendWeather *cbw)
+finished_retrieval_cb (WeatherInfo *info, ECalBackendWeather *cbw)
 {
 	ECalBackendWeatherPrivate *priv;
 	ECalComponent *comp;
 	icalcomponent *icomp;
 	GList *l;
+	char *obj;
 
 	priv = cbw->priv;
 
-	if (forecasts == NULL) {
+	if (info == NULL) {
 		e_cal_backend_notify_error (E_CAL_BACKEND (cbw), _("Could not retrieve weather data"));
 		return;
 	}
@@ -167,14 +172,36 @@ finished_retrieval_cb (GList *forecasts,
 	g_list_free (l);
 	e_file_cache_clean (E_FILE_CACHE (priv->cache));
 
-	for (l = forecasts; l != NULL; l = g_list_next (l)) {
-		char *obj;
-		comp = create_weather (cbw, l->data);
+	comp = create_weather (cbw, info, FALSE);
+	if (comp) {
+		GSList *forecasts;
+
 		e_cal_backend_cache_put_component (priv->cache, comp);
 		icomp = e_cal_component_get_icalcomponent (comp);
 		obj = icalcomponent_as_ical_string (icomp);
 		e_cal_backend_notify_object_created (E_CAL_BACKEND (cbw), obj);
 		g_free (obj);
+
+		forecasts = weather_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;
+
+				if (nfo) {
+					comp = create_weather (cbw, nfo, TRUE);
+					if (comp) {
+						e_cal_backend_cache_put_component (priv->cache, comp);
+						icomp = e_cal_component_get_icalcomponent (comp);
+						obj = icalcomponent_as_ical_string (icomp);
+						e_cal_backend_notify_object_created (E_CAL_BACKEND (cbw), obj);
+						g_free (obj);
+					}
+				}
+			}
+		}
 	}
 
 	priv->is_loading = FALSE;
@@ -210,86 +237,40 @@ begin_retrieval_cb (ECalBackendWeather *
 }
 
 static const char*
-getConditions (WeatherForecast *report)
-{
-	switch (report->conditions) {
-		case WEATHER_FAIR:			return _("Fair");
-		case WEATHER_SNOW_SHOWERS:		return _("Snow showers");
-		case WEATHER_SNOW:			return _("Snow");
-		case WEATHER_PARTLY_CLOUDY:		return _("Partly cloudy");
-		case WEATHER_SMOKE:			return _("Smoke");
-		case WEATHER_THUNDERSTORMS:		return _("Thunderstorms");
-		case WEATHER_CLOUDY:			return _("Cloudy");
-		case WEATHER_DRIZZLE:			return _("Drizzle");
-		case WEATHER_SUNNY:			return _("Sunny");
-		case WEATHER_DUST:			return _("Dust");
-		case WEATHER_CLEAR:			return _("Clear");
-		case WEATHER_MOSTLY_CLOUDY:		return _("Mostly cloudy");
-		case WEATHER_WINDY:			return _("Windy");
-		case WEATHER_RAIN_SHOWERS:		return _("Rain showers");
-		case WEATHER_FOGGY:			return _("Foggy");
-		case WEATHER_RAIN_OR_SNOW_MIXED:	return _("Rain/snow mixed");
-		case WEATHER_SLEET:			return _("Sleet");
-		case WEATHER_VERY_HOT_OR_HOT_HUMID:	return _("Very hot/humid");
-		case WEATHER_BLIZZARD:			return _("Blizzard");
-		case WEATHER_FREEZING_RAIN:		return _("Freezing rain");
-		case WEATHER_HAZE:			return _("Haze");
-		case WEATHER_BLOWING_SNOW:		return _("Blowing snow");
-		case WEATHER_FREEZING_DRIZZLE:		return _("Freezing drizzle");
-		case WEATHER_VERY_COLD_WIND_CHILL:	return _("Very cold/wind chill");
-		case WEATHER_RAIN:			return _("Rain");
-		default:				return NULL;
-	}
-}
-
-static const char*
-getCategory (WeatherForecast *report)
+getCategory (WeatherInfo *report)
 {
-	/* Right now this is based on which icons we have available */
-	switch (report->conditions) {
-		case WEATHER_FAIR:			return _("Weather: Sunny");
-		case WEATHER_SNOW_SHOWERS:		return _("Weather: Snow");
-		case WEATHER_SNOW:			return _("Weather: Snow");
-		case WEATHER_PARTLY_CLOUDY:		return _("Weather: Partly Cloudy");
-		case WEATHER_SMOKE:			return _("Weather: Fog");
-		case WEATHER_THUNDERSTORMS:		return _("Weather: Thunderstorms");
-		case WEATHER_CLOUDY:			return _("Weather: Cloudy");
-		case WEATHER_DRIZZLE:			return _("Weather: Rain");
-		case WEATHER_SUNNY:			return _("Weather: Sunny");
-		case WEATHER_DUST:			return _("Weather: Fog");
-		case WEATHER_CLEAR:			return _("Weather: Sunny");
-		case WEATHER_MOSTLY_CLOUDY:		return _("Weather: Cloudy");
-		case WEATHER_WINDY:			return "";
-		case WEATHER_RAIN_SHOWERS:		return _("Weather: Rain");
-		case WEATHER_FOGGY:			return _("Weather: Fog");
-		case WEATHER_RAIN_OR_SNOW_MIXED:	return _("Weather: Rain");
-		case WEATHER_SLEET:			return _("Weather: Rain");
-		case WEATHER_VERY_HOT_OR_HOT_HUMID:	return _("Weather: Sunny");
-		case WEATHER_BLIZZARD:			return _("Weather: Snow");
-		case WEATHER_FREEZING_RAIN:		return _("Weather: Rain");
-		case WEATHER_HAZE:			return _("Weather: Fog");
-		case WEATHER_BLOWING_SNOW:		return _("Weather: Snow");
-		case WEATHER_FREEZING_DRIZZLE:		return _("Weather: Rain");
-		case WEATHER_VERY_COLD_WIND_CHILL:	return "";
-		case WEATHER_RAIN:			return _("Weather: Rain");
-		default:				return NULL;
+	struct {
+		const char *description;
+		const char *icon_name;
+	} categories[] = {
+		{ N_("Weather: Fog"), 		"weather-fog" },
+		{ N_("Weather: Cloudy"), 	"weather-few-clouds" },
+		{ N_("Weather: Cloudy Night"),	"weather-few-clouds-night" },
+		{ N_("Weather: Overcast"),	"weather-overcast" },
+		{ N_("Weather: Showers"), 	"weather-showers" },
+		{ N_("Weather: Snow"), 		"weather-snow" },
+		{ N_("Weather: Sunny"), 	"weather-clear" },
+		{ N_("Weather: Clear Night"), 	"weather-clear-night" },
+		{ N_("Weather: Thunderstorms"), "weather-storm" },
+		{ NULL,				NULL }
+	};
+
+	int i;
+	const char *icon_name = weather_info_get_icon_name (report);
+
+	if (!icon_name)
+		return NULL;
+
+	for (i = 0; categories [i].description; i++) {
+		if (g_str_equal (categories [i].icon_name, icon_name))
+			return _(categories [i].description);
 	}
-}
 
-static float
-ctof (float c)
-{
-	return ((c * 9.0f / 5.0f) + 32.0f);
-}
-
-static float
-cmtoin (float cm)
-{
-	return cm / 2.54f;
+	return NULL;
 }
 
 static ECalComponent*
-create_weather (ECalBackendWeather *cbw, WeatherForecast *report)
+create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_forecast)
 {
 	ECalBackendWeatherPrivate *priv;
 	ECalComponent             *cal_comp;
@@ -300,27 +281,35 @@ create_weather (ECalBackendWeather *cbw,
 	const char                *uid;
 	GSList                    *text_list = NULL;
 	ECalComponentText         *description;
-	char                      *pop, *snow;
 	ESource                   *source;
 	gboolean                   metric;
-	const char                *format;
+	const char                *tmp;
+	time_t			   update_time;
 
 	g_return_val_if_fail (E_IS_CAL_BACKEND_WEATHER (cbw), NULL);
 
+	if (!weather_info_get_value_update (report, &update_time))
+		return NULL;
+
 	priv = cbw->priv;
 
 	source = e_cal_backend_get_source (E_CAL_BACKEND (cbw));
-	format = e_source_get_property (source, "units");
-	if (format == NULL) {
-		format = e_source_get_property (source, "temperature");
-		if (format == NULL)
+	tmp = e_source_get_property (source, "units");
+	if (tmp == NULL) {
+		tmp = e_source_get_property (source, "temperature");
+		if (tmp == NULL)
 			metric = FALSE;
 		else
-			metric = (strcmp (format, "fahrenheit") != 0);
+			metric = (strcmp (tmp, "fahrenheit") != 0);
 	} else {
-		metric = (strcmp (format, "metric") == 0);
+		metric = (strcmp (tmp, "metric") == 0);
 	}
 
+	if (metric)
+		weather_info_to_metric (report);
+	else
+		weather_info_to_imperial (report);
+
 	/* create the component and event object */
 	ical_comp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
 	cal_comp = e_cal_component_new ();
@@ -331,52 +320,55 @@ create_weather (ECalBackendWeather *cbw,
 	e_cal_component_set_uid (cal_comp, uid);
 
 	/* Set all-day event's date from forecast data */
-	itt = icaltime_from_timet (report->date, 1);
+	itt = icaltime_from_timet (update_time, 1);
 	dt.value = &itt;
 	dt.tzid = NULL;
 	e_cal_component_set_dtstart (cal_comp, &dt);
 
-	itt = icaltime_from_timet (report->date, 1);
+	itt = icaltime_from_timet (update_time, 1);
 	icaltime_adjust (&itt, 1, 0, 0, 0);
 	dt.value = &itt;
 	dt.tzid = NULL;
 	/* We have to add 1 day to DTEND, as it is not inclusive. */
 	e_cal_component_set_dtend (cal_comp, &dt);
 
-	/* The summary is the high or high/low temperatures */
-	if (report->high == report->low) {
-		if (metric)
-			comp_summary.value = g_strdup_printf (_("%.1f°C - %s"), report->high, priv->city);
-		else
-			comp_summary.value = g_strdup_printf (_("%.1f°F - %s"), ctof (report->high), priv->city);
+	if (is_forecast) {
+		gdouble tmin, tmax;
+
+		if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) && 
+		    weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &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 (weather_info_get_temp_min (report));
+
+			g_string_append (str, "/");
+			g_string_append (str, weather_info_get_temp_max (report));
+			g_string_append (str, " : ");
+			g_string_append (str, priv->city);
+
+			comp_summary.value = g_string_free (str, FALSE);
+		} else {
+			comp_summary.value = g_strdup_printf ("%s : %s", weather_info_get_temp (report), priv->city);
+		}
 	} else {
-		if (metric)
-			comp_summary.value = g_strdup_printf (_("%.1f/%.1f°C - %s"), report->high, report->low, priv->city);
-		else
-			comp_summary.value = g_strdup_printf (_("%.1f/%.1f°F - %s"), ctof (report->high), ctof (report->low), priv->city);
+		/* 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 (weather_info_get_temp (report));
+
+		g_string_append (str, "/");
+		g_string_append (str, weather_info_get_dew (report));
+		g_string_append (str, " : ");
+		g_string_append (str, priv->city);
+
+		comp_summary.value = g_string_free (str, FALSE);
 	}
 	comp_summary.altrep = NULL;
 	e_cal_component_set_summary (cal_comp, &comp_summary);
 
-	if (report->pop != 0)
-		pop = g_strdup_printf (_("%d%% chance of precipitation\n"), report->pop);
-	else
-		pop = g_strdup ("");
-	if (report->snowhigh == 0)
-		snow = g_strdup ("");
-	else if (report->snowhigh == report->snowlow) {
-		if (metric)
-			snow = g_strdup_printf (_("%.1fcm snow\n"), report->snowhigh);
-		else
-			snow = g_strdup_printf (_("%.1fin snow\n"), cmtoin(report->snowhigh));
-	} else {
-		if (metric)
-			snow = g_strdup_printf (_("%.1f-%.1fcm snow\n"), report->snowlow, report->snowhigh);
-		else
-			snow = g_strdup_printf (_("%.1f-%.1fin snow\n"), cmtoin(report->snowlow), cmtoin(report->snowhigh));
-	}
+	tmp = weather_info_get_forecast (report);
+
 	description = g_new0 (ECalComponentText, 1);
-	description->value = g_strdup_printf ("%s\n%s%s", getConditions (report), pop, snow);
+	description->value = g_strconcat (is_forecast ? "" : weather_info_get_weather_summary (report), is_forecast ? "" : "\n", tmp ? _("Forecast") : "", tmp ? ":" : "", tmp && !is_forecast ? "\n" : "", tmp ? tmp : "", NULL);
 	description->altrep = "";
 	text_list = g_slist_append (text_list, description);
 	e_cal_component_set_description_list (cal_comp, text_list);
@@ -390,9 +382,6 @@ create_weather (ECalBackendWeather *cbw,
 
 	e_cal_component_commit_sequence (cal_comp);
 
-	g_free (pop);
-	g_free (snow);
-
 	return cal_comp;
 }
 
Index: calendar/backends/weather/e-weather-source.h
===================================================================
--- calendar/backends/weather/e-weather-source.h	(revision 9776)
+++ calendar/backends/weather/e-weather-source.h	(working copy)
@@ -24,6 +24,10 @@
 #include <glib-object.h>
 #include <time.h>
 
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include <libgweather/weather.h>
+#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+
 G_BEGIN_DECLS
 
 typedef enum {
@@ -54,21 +58,7 @@ typedef enum {
 	WEATHER_RAIN,
 } WeatherConditions;
 
-typedef struct {
-	/* date, in UTC */
-	time_t date;
-	/* expected conditions */
-	WeatherConditions conditions;
-	/* internal storage is always in celcius and should be
-	 * converted based on the user's current locale setting */
-	float high, low;
-	/* probability of precipitation */
-	int pop;
-	/* snowfall forecast - internal storage in cm */
-	float snowhigh, snowlow;
-} WeatherForecast;
-
-typedef void (*EWeatherSourceFinished)(GList *results, gpointer data);
+typedef void (*EWeatherSourceFinished)(WeatherInfo *result, gpointer data);
 
 #define E_TYPE_WEATHER_SOURCE            (e_weather_source_get_type ())
 #define E_WEATHER_SOURCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_WEATHER_SOURCE, EWeatherSource))
Index: calendar/backends/weather/Makefile.am
===================================================================
--- calendar/backends/weather/Makefile.am	(revision 9776)
+++ calendar/backends/weather/Makefile.am	(working copy)
@@ -13,7 +13,8 @@ INCLUDES =						\
 	-DE_DATA_SERVER_PREFIX=\"$(prefix)\"		\
 	-DWEATHER_DATADIR=\""$(weatherdatadir)"\"	\
 	$(EVOLUTION_CALENDAR_CFLAGS)			\
-	$(SOUP_CFLAGS)
+	$(SOUP_CFLAGS)					\
+	`pkg-config --cflags gweather`
 
 extension_LTLIBRARIES = libecalbackendweather.la
 
@@ -33,10 +34,13 @@ libecalbackendweather_la_LIBADD =						\
 	$(top_builddir)/libedataserver/libedataserver-1.2.la			\
 	$(top_builddir)/libebackend/libebackend-1.2.la			\
 	$(EVOLUTION_CALENDAR_LIBS)						\
-	$(SOUP_LIBS)
+	$(SOUP_LIBS)								\
+	-lgweather
 
-libecalbackendweather_la_LDFLAGS =	\
-	-module -avoid-version $(NO_UNDEFINED)
+libecalbackendweather_la_LDFLAGS =		\
+	-module -avoid-version $(NO_UNDEFINED)	\
+	`pkg-config --libs gweather`
+	
 
 weatherdata_in_files = Locations.xml.in
 weatherdata_DATA = $(weatherdata_in_files:.xml.in=.xml)
Index: calendar/backends/weather/e-weather-source-ccf.c
===================================================================
--- calendar/backends/weather/e-weather-source-ccf.c	(revision 9776)
+++ calendar/backends/weather/e-weather-source-ccf.c	(working copy)
@@ -26,18 +26,14 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
 #include <glib/gi18n-lib.h>
 
-#include <gconf/gconf-client.h>
-
-#include "libedataserver/e-xml-utils.h"
-
 #include "e-weather-source-ccf.h"
 
-#define DATA_SIZE 5000
+#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
 
@@ -58,86 +54,98 @@
 #define strtok_r(s,sep,lasts) (*(lasts)=strtok((s),(sep)))
 #endif
 
-static gchar *
-parse_for_url (char *code, char *name, xmlNode *parent)
+struct search_struct
 {
-	xmlNode *child;
-	if (parent->type == XML_ELEMENT_NODE) {
-		if (strcmp ((char*)parent->name, "location") == 0) {
-			child = parent->children;
-			g_assert (child->type == XML_TEXT_NODE);
-			if (strcmp ((char*)child->content, name) == 0) {
-				xmlAttr *attr;
-				gchar *url = NULL;
-				for (attr = parent->properties; attr; attr = attr->next) {
-					if (strcmp ((char*)attr->name, "code") == 0) {
-						if (strcmp ((char*)attr->children->content, code) != 0)
-							return NULL;
-					}
-					if (strcmp ((char*)attr->name, "url") == 0)
-						url = (char*)attr->children->content;
-				}
-				return g_strdup (url);
-			}
-			return NULL;
-		} else {
-			for (child = parent->children; child; child = child->next) {
-				gchar *url = parse_for_url (code, name, child);
-				if (url)
-					return url;
-			}
-		}
+	const char *code;
+	const char *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 NULL;
+
+	return FALSE;
 }
 
-static void
-find_station_url (gchar *station, EWeatherSourceCCF *source)
+static WeatherLocation *
+find_location (const gchar *code_name, gboolean is_old)
 {
-	xmlDoc *doc;
-	xmlNode *root;
-	gchar **sstation;
-	gchar *url;
-	gchar *filename;
-
-	sstation = g_strsplit (station, "/", 2);
-
-#ifndef G_OS_WIN32
-	filename = g_strdup (WEATHER_DATADIR "/Locations.xml");
-#else
-	filename = e_util_replace_prefix (E_DATA_SERVER_PREFIX,
-					  e_util_get_prefix (),
-					  WEATHER_DATADIR "/Locations.xml");
-#endif
+	GtkTreeModel *model;
+	gchar **ids;
+	struct search_struct search;
+
+	search.location = NULL;
 
-	doc = e_xml_parse_file (filename);
+	ids = g_strsplit (code_name, "/", 2);
 
-	g_assert (doc != NULL);
+	if (!ids || !ids [0] || !ids [1])
+		goto done;
 
-	root = xmlDocGetRootElement (doc);
+	model = gweather_xml_load_locations ();
+	if (!model)
+		goto done;
 
-	url = parse_for_url (sstation[0], sstation[1], root);
+	search.code = ids [0];
+	search.name = ids [1];
+	search.is_old = is_old;
+	search.location = NULL;
 
-	source->url = g_strdup (url);
-	source->substation = g_strdup (sstation[0]);
+	gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) find_location_func, &search);
 
-	g_strfreev (sstation);
+	g_object_unref (model);
+	g_strfreev (ids);
+
+done:
+	return search.location;
 }
 
 EWeatherSource*
 e_weather_source_ccf_new (const char *uri)
 {
-	/* Our URI is formatted as weather://ccf/AAA[/BBB] - AAA is the 3-letter station
+	/* Old URI is formatted as weather://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 URI is as weather://code/name, where code is 4-letter code.
+	 * So if got the old URI, then migrate to the new one, if possible.
 	 */
-	EWeatherSourceCCF *source = E_WEATHER_SOURCE_CCF (g_object_new (e_weather_source_ccf_get_type (), NULL));
 
-	find_station_url (strchr (uri, '/') + 1, source);
+	WeatherLocation *wl;
+	EWeatherSourceCCF *source;
+
+	if (!uri)
+		return NULL;
+
+	if (strncmp (uri, "ccf/", 4) == 0)
+		wl = find_location (uri + 4, TRUE);
+	else
+		wl = find_location (uri, FALSE);
+
+	if (!wl)
+		return NULL;
+
+	source = E_WEATHER_SOURCE_CCF (g_object_new (e_weather_source_ccf_get_type (), NULL));
+	source->location = wl;
+	source->info = NULL;
+
 	return E_WEATHER_SOURCE (source);
 }
 
+#if 0
 static GSList*
 tokenize (char *buffer)
 {
@@ -388,74 +396,48 @@ e_weather_source_ccf_do_parse (EWeatherS
 	g_free (forecasts);
 	g_list_free (fc);
 }
+#endif
 
 static void
-retrieval_done (SoupSession *session, SoupMessage *message, EWeatherSourceCCF *source)
+parse_done (WeatherInfo *info, gpointer data)
 {
-	/* check status code */
-	if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
-		source->done (NULL, source->finished_data);
+	EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF *) data;
+
+	if (!ccfsource)
+		return;
+
+	if (!info || !weather_info_is_valid (info)) {
+		ccfsource->done (NULL, ccfsource->finished_data);
 		return;
 	}
 
-	e_weather_source_ccf_do_parse (source, (char *)message->response_body->data);
+	ccfsource->done (info, ccfsource->finished_data);
 }
 
 static void
 e_weather_source_ccf_parse (EWeatherSource *source, EWeatherSourceFinished done, gpointer data)
 {
 	EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF*) source;
-	SoupMessage *soup_message;
+	WeatherPrefs prefs;
 
 	ccfsource->finished_data = data;
-
 	ccfsource->done = done;
 
-	if (!ccfsource->soup_session) {
-		GConfClient *conf_client;
-		ccfsource->soup_session = soup_session_async_new ();
-
-		/* set the HTTP proxy, if configuration is set to do so */
-		conf_client = gconf_client_get_default ();
-		if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_http_proxy", NULL)) {
-			char *server, *proxy_uri;
-			int port;
-
-			server = gconf_client_get_string (conf_client, "/system/http_proxy/host", NULL);
-			port = gconf_client_get_int (conf_client, "/system/http_proxy/port", NULL);
-
-			if (server && server[0]) {
-				SoupURI *suri;
-				if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_authentication", NULL)) {
-					char *user, *password;
-
-					user = gconf_client_get_string (conf_client,
-									"/system/http_proxy/authentication_user",
-									NULL);
-					password = gconf_client_get_string (conf_client,
-									    "/system/http_proxy/authentication_password",
-									    NULL);
-
-					proxy_uri = g_strdup_printf("http://%s:%s@%s:%d", user, password, server, port);
-
-					g_free (user);
-					g_free (password);
-				} else
-					proxy_uri = g_strdup_printf ("http://%s:%d", server, port);
-
-				suri = soup_uri_new (proxy_uri);
-				g_object_set (G_OBJECT (ccfsource->soup_session), SOUP_SESSION_PROXY_URI, suri, NULL);
-
-				soup_uri_free (suri);
-				g_free (server);
-				g_free (proxy_uri);
-			}
-		}
-		g_object_unref (conf_client);
+	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);
 	}
-
-	soup_message = soup_message_new (SOUP_METHOD_GET, ccfsource->url);
-	soup_session_queue_message (ccfsource->soup_session, soup_message, (SoupSessionCallback) retrieval_done, source);
 }
 
 static void
@@ -471,9 +453,8 @@ e_weather_source_ccf_class_init (EWeathe
 static void
 e_weather_source_ccf_init (EWeatherSourceCCF *source)
 {
-	source->url = NULL;
-	source->substation = NULL;
-	source->soup_session = NULL;
+	source->location = NULL;
+	source->info = NULL;
 }
 
 GType
Index: calendar/backends/weather/e-weather-source-ccf.h
===================================================================
--- calendar/backends/weather/e-weather-source-ccf.h	(revision 9776)
+++ calendar/backends/weather/e-weather-source-ccf.h	(working copy)
@@ -26,6 +26,10 @@
 #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
+
 G_BEGIN_DECLS
 
 #define E_TYPE_WEATHER_SOURCE_CCF            (e_weather_source_ccf_get_type ())
@@ -40,10 +44,10 @@ typedef struct _EWeatherSourceCCFClass E
 struct _EWeatherSourceCCF {
 	EWeatherSource parent;
 
-	char *url;
-	char *substation;
+	WeatherLocation *location;
+	WeatherInfo *info;
+
 	EWeatherSourceFinished done;
-	SoupSession *soup_session;
 	gpointer finished_data;
 };
 
