1
From c51c56fec9f9d45a5e36619ad650c534293191e3 Mon Sep 17 00:00:00 2001
2
From: Giovanni Campagna <gcampagna@src.gnome.org>
3
Date: Sat, 24 Mar 2012 00:06:02 +0000
4
Subject: weather: update for newer GWeather
6
GWeather 3.6 changed API to be properly namespaced and GObject based.
7
Also, WeatherLocation was removed and replaced with GWeatherLocation
8
in all public API (with additionally the possibility to retrieve one
9
particular GWeatherLocation by station code)
10
At the same time, remove a old and now useless abstration by folding
11
EWeatherSourceCCF into EWeatherSource.
13
https://bugzilla.gnome.org/show_bug.cgi?id=672805
15
diff --git a/calendar/backends/weather/Makefile.am b/calendar/backends/weather/Makefile.am
16
index ed41cf2..25ee7a9 100644
17
--- a/calendar/backends/weather/Makefile.am
18
+++ b/calendar/backends/weather/Makefile.am
19
@@ -25,9 +25,7 @@ libecalbackendweather_la_SOURCES = \
23
- e-weather-source.h \
24
- e-weather-source-ccf.c \
25
- e-weather-source-ccf.h
28
libecalbackendweather_la_LIBADD = \
29
$(top_builddir)/calendar/libecal/libecal-1.2.la \
30
diff --git a/calendar/backends/weather/e-cal-backend-weather.c b/calendar/backends/weather/e-cal-backend-weather.c
31
index 62357ae..632c5f2 100644
32
--- a/calendar/backends/weather/e-cal-backend-weather.c
33
+++ b/calendar/backends/weather/e-cal-backend-weather.c
35
#include "e-weather-source.h"
37
#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
38
-#include <libgweather/weather.h>
39
+#include <libgweather/gweather-weather.h>
40
#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
42
#define WEATHER_UID_EXT "-weather"
43
@@ -43,7 +43,7 @@ G_DEFINE_TYPE (ECalBackendWeather, e_cal_backend_weather, E_TYPE_CAL_BACKEND_SYN
45
static gboolean reload_cb (ECalBackendWeather *cbw);
46
static gboolean begin_retrieval_cb (ECalBackendWeather *cbw);
47
-static ECalComponent * create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_forecast);
48
+static ECalComponent * create_weather (ECalBackendWeather *cbw, GWeatherInfo *report, gboolean is_forecast);
49
static void e_cal_backend_weather_add_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzobj, GError **perror);
51
/* Private part of the ECalBackendWeather structure */
52
@@ -158,7 +158,7 @@ put_component_to_store (ECalBackendWeather *cb,
56
-finished_retrieval_cb (WeatherInfo *info,
57
+finished_retrieval_cb (GWeatherInfo *info,
58
ECalBackendWeather *cbw)
60
ECalBackendWeatherPrivate *priv;
61
@@ -197,13 +197,13 @@ finished_retrieval_cb (WeatherInfo *info,
62
e_cal_backend_notify_component_created (E_CAL_BACKEND (cbw), comp);
63
g_object_unref (comp);
65
- forecasts = weather_info_get_forecast_list (info);
66
+ forecasts = gweather_info_get_forecast_list (info);
70
/* skip the first one, it's for today, which has been added above */
71
for (f = forecasts->next; f; f = f->next) {
72
- WeatherInfo *nfo = f->data;
73
+ GWeatherInfo *nfo = f->data;
76
comp = create_weather (cbw, nfo, TRUE);
77
@@ -267,7 +267,7 @@ begin_retrieval_cb (ECalBackendWeather *cbw)
81
-getCategory (WeatherInfo *report)
82
+getCategory (GWeatherInfo *report)
85
const gchar *description;
86
@@ -286,7 +286,7 @@ getCategory (WeatherInfo *report)
90
- const gchar *icon_name = weather_info_get_icon_name (report);
91
+ const gchar *icon_name = gweather_info_get_icon_name (report);
95
@@ -302,7 +302,7 @@ getCategory (WeatherInfo *report)
97
static ECalComponent *
98
create_weather (ECalBackendWeather *cbw,
99
- WeatherInfo *report,
100
+ GWeatherInfo *report,
101
gboolean is_forecast)
103
ECalBackendWeatherPrivate *priv;
104
@@ -314,34 +314,19 @@ create_weather (ECalBackendWeather *cbw,
106
GSList *text_list = NULL;
107
ECalComponentText *description;
112
icaltimezone *update_zone = NULL;
113
- ESourceWeather *extension;
114
- const gchar *extension_name;
115
- const WeatherLocation *location;
116
- ESourceWeatherUnits units;
117
+ const GWeatherLocation *location;
118
+ const GWeatherTimezone *w_timezone;
120
g_return_val_if_fail (E_IS_CAL_BACKEND_WEATHER (cbw), NULL);
122
- if (!weather_info_get_value_update (report, &update_time))
123
+ if (!gweather_info_get_value_update (report, &update_time))
128
- source = e_backend_get_source (E_BACKEND (cbw));
130
- extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
131
- extension = e_source_get_extension (source, extension_name);
132
- units = e_source_weather_get_units (extension);
134
- /* Prefer metric if units is invalid. */
135
- if (units == E_SOURCE_WEATHER_UNITS_IMPERIAL)
136
- weather_info_to_imperial (report);
138
- weather_info_to_metric (report);
140
/* create the component and event object */
141
ical_comp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
142
cal_comp = e_cal_component_new ();
143
@@ -353,9 +338,9 @@ create_weather (ECalBackendWeather *cbw,
146
/* use timezone of the location to determine date for which this is set */
147
- location = weather_info_get_location (report);
148
- if (location && location->tz_hint && *location->tz_hint)
149
- update_zone = icaltimezone_get_builtin_timezone (location->tz_hint);
150
+ location = gweather_info_get_location (report);
151
+ if (location && (w_timezone = gweather_location_get_timezone ((GWeatherLocation *)location)))
152
+ update_zone = icaltimezone_get_builtin_timezone (gweather_timezone_get_tzid ((GWeatherTimezone*)w_timezone));
155
update_zone = icaltimezone_get_utc_timezone ();
156
@@ -380,53 +365,56 @@ create_weather (ECalBackendWeather *cbw,
157
/* We have to add 1 day to DTEND, as it is not inclusive. */
158
e_cal_component_set_dtend (cal_comp, &dt);
162
gdouble tmin = 0.0, tmax = 0.0;
164
- if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) &&
165
- weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &tmax) &&
166
+ if (gweather_info_get_value_temp_min (report, GWEATHER_TEMP_UNIT_DEFAULT, &tmin) &&
167
+ gweather_info_get_value_temp_max (report, GWEATHER_TEMP_UNIT_DEFAULT, &tmax) &&
169
- /* because weather_info_get_temp* uses one internal buffer, thus finally
170
- * the last value is shown for both, which is obviously wrong */
171
- GString *str = g_string_new (priv->city);
174
- g_string_append (str, " : ");
175
- g_string_append (str, weather_info_get_temp_min (report));
176
- g_string_append (str, "/");
177
- g_string_append (str, weather_info_get_temp_max (report));
178
+ min = gweather_info_get_temp_min (report);
179
+ max = gweather_info_get_temp_max (report);
180
+ comp_summary.value = g_strdup_printf ("%s : %s / %s", priv->city, min, max);
182
- comp_summary.value = g_string_free (str, FALSE);
183
+ g_free (min); g_free (max);
185
- comp_summary.value = g_strdup_printf ("%s : %s", priv->city, weather_info_get_temp (report));
188
- gdouble tmin = 0.0, tmax = 0.0;
189
- /* because weather_info_get_temp* uses one internal buffer, thus finally
190
- * the last value is shown for both, which is obviously wrong */
191
- GString *str = g_string_new (priv->city);
194
- g_string_append (str, " : ");
195
- if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) &&
196
- weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &tmax) &&
198
- g_string_append (str, weather_info_get_temp_min (report));
199
- g_string_append (str, "/");
200
- g_string_append (str, weather_info_get_temp_max (report));
202
- g_string_append (str, weather_info_get_temp (report));
204
+ temp = gweather_info_get_temp (report);
205
+ comp_summary.value = g_strdup_printf ("%s : %s", priv->city, temp);
207
- comp_summary.value = g_string_free (str, FALSE);
211
comp_summary.altrep = NULL;
212
e_cal_component_set_summary (cal_comp, &comp_summary);
213
g_free ((gchar *) comp_summary.value);
215
- tmp = weather_info_get_forecast (report);
216
- comp_summary.value = weather_info_get_weather_summary (report);
217
+ tmp = gweather_info_get_forecast (report);
218
+ comp_summary.value = gweather_info_get_weather_summary (report);
220
description = g_new0 (ECalComponentText, 1);
221
- description->value = g_strconcat (is_forecast ? "" : comp_summary.value, is_forecast ? "" : "\n", tmp ? _("Forecast") : "", tmp ? ":" : "", tmp && !is_forecast ? "\n" : "", tmp ? tmp : "", NULL);
225
+ builder = g_string_new (NULL);
227
+ if (!is_forecast) {
228
+ g_string_append (builder, comp_summary.value);
229
+ g_string_append_c (builder, '\n');
232
+ g_string_append (builder, _("Forecast"));
233
+ g_string_append_c (builder, ':');
235
+ g_string_append_c (builder, '\n');
236
+ g_string_append (builder, tmp);
239
+ description->value = g_string_free (builder, FALSE);
242
description->altrep = "";
243
text_list = g_slist_append (text_list, description);
244
e_cal_component_set_description_list (cal_comp, text_list);
245
diff --git a/calendar/backends/weather/e-weather-source-ccf.c b/calendar/backends/weather/e-weather-source-ccf.c
246
deleted file mode 100644
247
index 2bb76a5..0000000
248
--- a/calendar/backends/weather/e-weather-source-ccf.c
251
-/* Evolution calendar - weather backend source class for parsing
252
- * CCF (coded cities forecast) formatted NWS reports
254
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
256
- * Authors: David Trowbridge <trowbrds@cs.colorado.edu>
258
- * This program is free software; you can redistribute it and/or
259
- * modify it under the terms of version 2 of the GNU Lesser General Public
260
- * License as published by the Free Software Foundation.
262
- * This program is distributed in the hope that it will be useful,
263
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
264
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
265
- * GNU Lesser General Public License for more details.
267
- * You should have received a copy of the GNU Lesser General Public License
268
- * along with this program; if not, write to the Free Software
269
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
272
-#ifdef HAVE_CONFIG_H
279
-#include <glib/gi18n-lib.h>
281
-#include "e-weather-source-ccf.h"
283
-#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
284
-#include <libgweather/weather.h>
285
-#include <libgweather/gweather-xml.h>
286
-#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
294
-/* The localtime() in Microsoft's C library is MT-safe */
295
-#define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0)
297
-/* strtok() is also MT-safe (but not stateless, still uses only one
298
- * buffer pointer per thread, but for the use of strtok_r() here
301
-#define strtok_r(s,sep,lasts) (*(lasts)=strtok((s),(sep)))
304
-G_DEFINE_TYPE (EWeatherSourceCCF, e_weather_source_ccf, E_TYPE_WEATHER_SOURCE)
306
-struct search_struct
311
- WeatherLocation *location;
315
-find_location_func (GtkTreeModel *model,
320
- WeatherLocation *wl = NULL;
321
- struct search_struct *search = (struct search_struct *) data;
323
- gtk_tree_model_get (model, node, GWEATHER_XML_COL_POINTER, &wl, -1);
324
- if (!wl || !wl->name || !wl->code || !search || search->location)
327
- if (((!strcmp (wl->code, search->code)) || (search->is_old && !strcmp (wl->code + 1, search->code))) &&
328
- (!strcmp (wl->name, search->name))) {
329
- search->location = weather_location_clone (wl);
336
-static WeatherLocation *
337
-find_location (const gchar *code_name,
340
- GtkTreeModel *model;
342
- struct search_struct search;
344
- search.location = NULL;
346
- ids = g_strsplit (code_name, "/", 2);
348
- if (!ids || !ids[0] || !ids[1])
351
- model = gweather_xml_load_locations ();
355
- search.code = ids[0];
356
- search.name = ids[1];
357
- search.is_old = is_old;
358
- search.location = NULL;
360
- gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) find_location_func, &search);
362
- gweather_xml_free_locations (model);
366
- return search.location;
371
-tokenize (gchar *buffer)
377
- token = strtok_r (buffer, " \n", &tokbuf);
378
- ret = g_slist_append (NULL, g_strdup (token));
379
- while ((token = strtok_r (NULL, " \n/", &tokbuf)))
380
- ret = g_slist_append (ret, g_strdup (token));
385
-date2tm (gchar *date,
389
- time_t curtime = time (NULL);
392
- localtime_r (&curtime, times);
394
- tmp[0] = date[0]; tmp[1] = date[1];
395
- times->tm_mday = atoi (tmp);
396
- tmp[0] = date[2]; tmp[1] = date[3];
397
- times->tm_hour = atoi (tmp);
398
- tmp[0] = date[4]; tmp[1] = date[5];
399
- times->tm_min = atoi (tmp);
402
-static WeatherConditions
403
-decodeConditions (gchar code)
406
- case 'A': return WEATHER_FAIR;
407
- case 'B': return WEATHER_PARTLY_CLOUDY;
408
- case 'C': return WEATHER_CLOUDY;
409
- case 'D': return WEATHER_DUST;
410
- case 'E': return WEATHER_MOSTLY_CLOUDY;
411
- case 'F': return WEATHER_FOGGY;
412
- case 'G': return WEATHER_VERY_HOT_OR_HOT_HUMID;
413
- case 'H': return WEATHER_HAZE;
414
- case 'I': return WEATHER_VERY_COLD_WIND_CHILL;
415
- case 'J': return WEATHER_SNOW_SHOWERS;
416
- case 'K': return WEATHER_SMOKE;
417
- case 'L': return WEATHER_DRIZZLE;
418
- case 'M': return WEATHER_SNOW_SHOWERS;
419
- case 'N': return WEATHER_WINDY;
420
- case 'O': return WEATHER_RAIN_OR_SNOW_MIXED;
421
- case 'P': return WEATHER_BLIZZARD;
422
- case 'Q': return WEATHER_BLOWING_SNOW;
423
- case 'R': return WEATHER_RAIN;
424
- case 'S': return WEATHER_SNOW;
425
- case 'T': return WEATHER_THUNDERSTORMS;
426
- case 'U': return WEATHER_SUNNY;
427
- case 'V': return WEATHER_CLEAR;
428
- case 'W': return WEATHER_RAIN_SHOWERS;
429
- case 'X': return WEATHER_SLEET;
430
- case 'Y': return WEATHER_FREEZING_RAIN;
431
- case 'Z': return WEATHER_FREEZING_DRIZZLE;
432
- /* hmm, this should never happen. */
433
- default: return WEATHER_SUNNY;
438
-decodePOP (gchar data)
450
- ret = -1; /* missing data */
453
- ret = (data - '0') * 10;
459
-decodeSnowfall (gchar *data,
466
- num[0] = data[0]; num[1] = data[1];
467
- *low = atof (num) * 2.54f;
468
- num[0] = data[2]; num[1] = data[3];
469
- *high = atof (num) * 2.54f;
475
- gint fahrenheit = atoi (data);
476
- if (fahrenheit >= 900)
477
- fahrenheit = (fahrenheit - 900) * -1;
478
- return ((gfloat)(fahrenheit - 32)) * 5.0f / 9.0f;
482
-e_weather_source_ccf_do_parse (EWeatherSourceCCF *source,
485
- /* CCF gives us either 2 or 7 days of forecast data. IFPS WFO's
486
- * will produce 7 day forecasts, whereas pre-IFPS WFO's are only
487
- * mandated 2 (but may do 7). The morning forecast will give us either 2
488
- * or 7 days worth of data. The evening forecast will give us the evening's
489
- * low temperature plus 2 or 7 days forecast.
491
- * The CCF format is described in NWS directive 10-503, but it's usually
492
- * easier to look at a summary put up by one of the stations:
493
- * http://www.crh.noaa.gov/lmk/product_guide/products/forecast/ccf.htm
495
- WeatherForecast *forecasts = g_new0 (WeatherForecast, 7);
496
- GSList *tokens = tokenize (buffer);
498
- GSList *current = tokens;
505
- date = g_slist_nth (tokens, 3);
506
- date2tm (date->data, &tms);
508
- /* fast-forward to the particular station we're interested in */
509
- current = g_slist_nth (tokens, 5);
510
- while (strcmp (current->data, source->substation))
511
- current = g_slist_next (current);
512
- current = g_slist_next (current);
513
- /* pick up the first two conditions reports */
514
- forecasts[0].conditions = decodeConditions (((gchar *)(current->data))[0]);
515
- forecasts[1].conditions = decodeConditions (((gchar *)(current->data))[1]);
517
- current = g_slist_next (current);
518
- if (tms.tm_hour < 12) {
519
- for (i = 0; i < 2; i++) {
520
- forecasts[i].high = ftoc (current->data);
521
- current = g_slist_next (current);
522
- forecasts[i].low = ftoc (current->data);
523
- current = g_slist_next (current);
525
- forecasts[2].high = ftoc (current->data);
526
- current = g_slist_next (current);
527
- forecasts[0].pop = decodePOP (((gchar *)(current->data))[2]);
528
- forecasts[1].pop = decodePOP (((gchar *)(current->data))[4]);
530
- for (i = 0; i < 2; i++) {
531
- current = g_slist_next (current);
532
- forecasts[i].high = ftoc (current->data);
533
- current = g_slist_next (current);
534
- forecasts[i].low = ftoc (current->data);
536
- current = g_slist_next (current);
537
- forecasts[0].pop = decodePOP (((gchar *)(current->data))[1]);
538
- forecasts[1].pop = decodePOP (((gchar *)(current->data))[3]);
541
- current = g_slist_next (current);
542
- if (strlen (current->data) == 4) {
543
- /* we've got the optional snowfall field */
544
- if (tms.tm_hour < 12) {
545
- decodeSnowfall (current->data, &forecasts[0].low, &forecasts[0].high);
546
- current = g_slist_next (g_slist_next (current));
547
- decodeSnowfall (current->data, &forecasts[1].low, &forecasts[1].high);
549
- current = g_slist_next (current);
550
- decodeSnowfall (current->data, &forecasts[0].low, &forecasts[0].high);
552
- current = g_slist_next (current);
556
- base = mktime (&tms);
557
- if (tms.tm_hour >= 12)
559
- for (i = 0; i < 7; i++)
560
- forecasts[i].date = base + 86400 * i;
562
- if (current == NULL || strlen (current->data) == 3) {
563
- /* We've got a pre-IFPS station. Realloc and return */
564
- WeatherForecast *f = g_new0 (WeatherForecast, 2);
565
- memcpy (f, forecasts, sizeof (WeatherForecast) * 2);
566
- fc = g_list_append (fc, &f[0]);
567
- fc = g_list_append (fc, &f[1]);
568
- source->done (fc, source->finished_data);
571
- /* Grab the conditions for the next 5 days */
572
- forecasts[2].conditions = decodeConditions (((gchar *)(current->data))[0]);
573
- forecasts[3].conditions = decodeConditions (((gchar *)(current->data))[1]);
574
- forecasts[4].conditions = decodeConditions (((gchar *)(current->data))[2]);
575
- forecasts[5].conditions = decodeConditions (((gchar *)(current->data))[3]);
576
- forecasts[6].conditions = decodeConditions (((gchar *)(current->data))[4]);
578
- /* Temperature forecasts */
579
- current = g_slist_next (current);
580
- if (tms.tm_hour < 12) {
581
- forecasts[2].low = ftoc (current->data);
582
- for (i = 3; i < 6; i++) {
583
- current = g_slist_next (current);
584
- forecasts[i].high = ftoc (current->data);
585
- current = g_slist_next (current);
586
- forecasts[i].low = ftoc (current->data);
588
- current = g_slist_next (current);
589
- forecasts[6].high = ftoc (current->data);
590
- forecasts[6].low = forecasts[6].high;
591
- current = g_slist_next (current);
592
- forecasts[2].pop = decodePOP (((gchar *)(current->data))[1]);
593
- forecasts[3].pop = decodePOP (((gchar *)(current->data))[3]);
594
- forecasts[4].pop = decodePOP (((gchar *)(current->data))[5]);
595
- forecasts[5].pop = decodePOP (((gchar *)(current->data))[7]);
596
- forecasts[6].pop = decodePOP (((gchar *)(current->data))[9]);
599
- for (i = 2; i < 6; i++) {
600
- forecasts[i].high = ftoc (current->data);
601
- current = g_slist_next (current);
602
- forecasts[i].low = ftoc (current->data);
603
- current = g_slist_next (current);
606
- /* hack for people who put out bad data, like Pueblo, CO. Yes, PUB, that means you */
607
- if (strlen (current->data) == 3)
608
- current = g_slist_next (current);
609
- forecasts[1].pop = decodePOP (((gchar *)(current->data))[0]);
610
- forecasts[2].pop = decodePOP (((gchar *)(current->data))[2]);
611
- forecasts[3].pop = decodePOP (((gchar *)(current->data))[4]);
612
- forecasts[4].pop = decodePOP (((gchar *)(current->data))[6]);
613
- forecasts[5].pop = decodePOP (((gchar *)(current->data))[8]);
616
- for (i = 0; i < n; i++) {
617
- fc = g_list_append (fc, &forecasts[i]);
619
- source->done (fc, source->finished_data);
621
- g_free (forecasts);
627
-parse_done (WeatherInfo *info,
630
- EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF *) data;
635
- if (!info || !weather_info_is_valid (info)) {
636
- ccfsource->done (NULL, ccfsource->finished_data);
640
- ccfsource->done (info, ccfsource->finished_data);
644
-e_weather_source_ccf_parse (EWeatherSource *source,
645
- EWeatherSourceFinished done,
648
- EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF *) source;
649
- WeatherPrefs prefs;
651
- ccfsource->finished_data = data;
652
- ccfsource->done = done;
654
- prefs.type = FORECAST_LIST;
655
- prefs.radar = FALSE;
656
- prefs.radar_custom_url = NULL;
657
- prefs.temperature_unit = TEMP_UNIT_CENTIGRADE;
658
- prefs.speed_unit = SPEED_UNIT_MS;
659
- prefs.pressure_unit = PRESSURE_UNIT_HPA;
660
- prefs.distance_unit = DISTANCE_UNIT_METERS;
662
- if (ccfsource->location && !ccfsource->info) {
663
- ccfsource->info = weather_info_new (ccfsource->location, &prefs, parse_done, source);
664
- weather_location_free (ccfsource->location);
665
- ccfsource->location = NULL;
667
- ccfsource->info = weather_info_update (ccfsource->info, &prefs, parse_done, source);
672
-e_weather_source_ccf_class_init (EWeatherSourceCCFClass *class)
674
- EWeatherSourceClass *source_class;
676
- source_class = E_WEATHER_SOURCE_CLASS (class);
677
- source_class->parse = e_weather_source_ccf_parse;
681
-e_weather_source_ccf_init (EWeatherSourceCCF *source)
683
- source->location = NULL;
684
- source->info = NULL;
688
-e_weather_source_ccf_new (const gchar *location)
690
- /* Old location is formatted as ccf/AAA[/BBB] - AAA is the 3-letter
691
- * station code for identifying the providing station (subdirectory
692
- * within the crh data repository). BBB is an optional additional
693
- * station ID for the station within the CCF file. If not present,
694
- * BBB is assumed to be the same station as AAA. But the new
695
- * location is code/name, where code is 4-letter code. So if we
696
- * got the old format, then migrate to the new one, if possible.
699
- WeatherLocation *wl;
700
- EWeatherSourceCCF *source;
702
- if (location == NULL)
705
- if (strncmp (location, "ccf/", 4) == 0)
706
- wl = find_location (location + 4, TRUE);
708
- wl = find_location (location, FALSE);
713
- source = g_object_new (E_TYPE_WEATHER_SOURCE_CCF, NULL);
714
- source->location = wl;
715
- source->info = NULL;
717
- return E_WEATHER_SOURCE (source);
719
diff --git a/calendar/backends/weather/e-weather-source-ccf.h b/calendar/backends/weather/e-weather-source-ccf.h
720
deleted file mode 100644
721
index e0ae161..0000000
722
--- a/calendar/backends/weather/e-weather-source-ccf.h
725
-/* Evolution calendar - weather backend source class for parsing
726
- * CCF (coded cities forecast) formatted NWS reports
728
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
730
- * Authors: David Trowbridge <trowbrds@cs.colorado.edu>
732
- * This program is free software; you can redistribute it and/or
733
- * modify it under the terms of version 2 of the GNU Lesser General Public
734
- * License as published by the Free Software Foundation.
736
- * This program is distributed in the hope that it will be useful,
737
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
738
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
739
- * GNU Lesser General Public License for more details.
741
- * You should have received a copy of the GNU Lesser General Public License
742
- * along with this program; if not, write to the Free Software
743
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
746
-#ifndef E_WEATHER_SOURCE_CCF_H
747
-#define E_WEATHER_SOURCE_CCF_H
749
-#include <libsoup/soup-session-async.h>
750
-#include <libsoup/soup-uri.h>
751
-#include "e-weather-source.h"
753
-#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
754
-#include <libgweather/weather.h>
755
-#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
757
-/* Standard GObject macros */
758
-#define E_TYPE_WEATHER_SOURCE_CCF \
759
- (e_weather_source_ccf_get_type ())
760
-#define E_WEATHER_SOURCE_CCF(obj) \
761
- (G_TYPE_CHECK_INSTANCE_CAST \
762
- ((obj), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
763
-#define E_WEATHER_SOURCE_CCF_CLASS(cls) \
764
- (G_TYPE_CHECK_CLASS_CAST \
765
- ((cls), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
766
-#define E_IS_WEATHER_SOURCE_CCF(obj) \
767
- (G_TYPE_CHECK_INSTANCE_TYPE \
768
- ((obj), E_TYPE_WEATHER_SOURCE_CCF))
769
-#define E_IS_WEATHER_SOURCE_CCF_CLASS(cls) \
770
- (G_TYPE_CHECK_CLASS_TYPE \
771
- ((cls), E_TYPE_WEATHER_SOURCE_CCF))
772
-#define E_WEATHER_SOURCE_CCF_GET_CLASS(obj) \
773
- (G_TYPE_INSTANCE_GET_CLASS \
774
- ((obj), E_TYPE_WEATHER_SOURCE_CCF, EWeatherSourceCCF))
778
-typedef struct _EWeatherSourceCCF EWeatherSourceCCF;
779
-typedef struct _EWeatherSourceCCFClass EWeatherSourceCCFClass;
781
-struct _EWeatherSourceCCF {
782
- EWeatherSource parent;
784
- WeatherLocation *location;
787
- EWeatherSourceFinished done;
788
- gpointer finished_data;
791
-struct _EWeatherSourceCCFClass {
792
- EWeatherSourceClass parent_class;
795
-GType e_weather_source_ccf_get_type (void);
796
-EWeatherSource *e_weather_source_ccf_new (const gchar *location);
800
-#endif /* E_WEATHER_SOURCE_CCF_H */
801
diff --git a/calendar/backends/weather/e-weather-source.c b/calendar/backends/weather/e-weather-source.c
802
index 3dd3431..2da852a 100644
803
--- a/calendar/backends/weather/e-weather-source.c
804
+++ b/calendar/backends/weather/e-weather-source.c
808
#include "e-weather-source.h"
809
-#include "e-weather-source-ccf.h"
813
G_DEFINE_TYPE (EWeatherSource, e_weather_source, G_TYPE_OBJECT)
816
+parse_done (GWeatherInfo *info,
819
+ EWeatherSource *source = (EWeatherSource *) data;
824
+ if (!info || !gweather_info_is_valid (info)) {
825
+ source->done (NULL, source->finished_data);
829
+ source->done (info, source->finished_data);
833
-e_weather_source_parse (EWeatherSource *source,
834
- EWeatherSourceFinished done,
836
+e_weather_source_parse (EWeatherSource *source,
837
+ EWeatherSourceFinished done,
840
- EWeatherSourceClass *class;
841
+ source->finished_data = data;
842
+ source->done = done;
844
+ if (!source->info) {
845
+ source->info = gweather_info_new (source->location, GWEATHER_FORECAST_LIST);
846
+ g_signal_connect (source->info, "updated", G_CALLBACK (parse_done), source);
848
+ gweather_info_update (source->info);
852
- g_return_if_fail (source != NULL);
854
+e_weather_source_finalize (GObject *object)
856
+ EWeatherSource *self = (EWeatherSource*) object;
858
- class = E_WEATHER_SOURCE_GET_CLASS (source);
859
- g_return_if_fail (class->parse != NULL);
860
+ if (self->location)
861
+ gweather_location_unref (self->location);
862
+ g_clear_object (&self->info);
864
- class->parse (source, done, data);
865
+ G_OBJECT_CLASS (e_weather_source_parent_class)->finalize (object);
869
-e_weather_source_class_init (EWeatherSourceClass *class)
870
+e_weather_source_class_init (EWeatherSourceClass *klass)
872
- /* nothing to do here */
873
+ GObjectClass *gobject_class;
875
+ gobject_class = G_OBJECT_CLASS (klass);
876
+ gobject_class->finalize = e_weather_source_finalize;
880
e_weather_source_init (EWeatherSource *source)
882
- /* nothing to do here */
886
e_weather_source_new (const gchar *location)
888
- g_return_val_if_fail (location != NULL, NULL);
889
+ GWeatherLocation *world, *glocation;
890
+ EWeatherSource *source;
893
+ /* Old location is formatted as ccf/AAA[/BBB] - AAA is the 3-letter station
894
+ * code for identifying the providing station (subdirectory within the crh data
895
+ * repository). BBB is an optional additional station ID for the station within
896
+ * the CCF file. If not present, BBB is assumed to be the same station as AAA.
897
+ * But the new location is code/name, where code is 4-letter code.
898
+ * So if got the old format, then migrate to the new one, if possible.
904
+ world = gweather_location_new_world (FALSE);
906
+ if (strncmp (location, "ccf/", 4) == 0)
909
+ tokens = g_strsplit (location, "/", 2);
911
+ glocation = gweather_location_find_by_station_code (world, tokens[0]);
913
+ gweather_location_ref (glocation);
915
+ gweather_location_unref (world);
916
+ g_strfreev (tokens);
921
+ source = E_WEATHER_SOURCE (g_object_new (e_weather_source_get_type (), NULL));
922
+ source->location = glocation;
923
+ source->info = NULL;
925
- return e_weather_source_ccf_new (location);
928
diff --git a/calendar/backends/weather/e-weather-source.h b/calendar/backends/weather/e-weather-source.h
929
index e36793e..793c2fa 100644
930
--- a/calendar/backends/weather/e-weather-source.h
931
+++ b/calendar/backends/weather/e-weather-source.h
935
#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
936
-#include <libgweather/weather.h>
937
+#include <libgweather/gweather-weather.h>
938
#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
940
/* Standard GObject macros */
947
- WEATHER_SNOW_SHOWERS,
949
- WEATHER_PARTLY_CLOUDY,
951
- WEATHER_THUNDERSTORMS,
957
- WEATHER_MOSTLY_CLOUDY,
959
- WEATHER_RAIN_SHOWERS,
961
- WEATHER_RAIN_OR_SNOW_MIXED,
963
- WEATHER_VERY_HOT_OR_HOT_HUMID,
965
- WEATHER_FREEZING_RAIN,
967
- WEATHER_BLOWING_SNOW,
968
- WEATHER_FREEZING_DRIZZLE,
969
- WEATHER_VERY_COLD_WIND_CHILL,
971
-} WeatherConditions;
973
-typedef void (*EWeatherSourceFinished)(WeatherInfo *result, gpointer data);
974
+typedef void (*EWeatherSourceFinished)(GWeatherInfo *result, gpointer data);
976
typedef struct _EWeatherSource EWeatherSource;
977
typedef struct _EWeatherSourceClass EWeatherSourceClass;
978
@@ -87,16 +59,16 @@ typedef struct _EWeatherSourceClass EWeatherSourceClass;
979
* to know how to do is parse the specific format. */
980
struct _EWeatherSource {
983
+ GWeatherLocation *location;
984
+ GWeatherInfo *info;
986
+ EWeatherSourceFinished done;
987
+ gpointer finished_data;
990
struct _EWeatherSourceClass {
991
GObjectClass parent_class;
993
- /* Returns a list of WeatherForecast objects containing the
994
- * data for the forecast. */
995
- void (*parse) (EWeatherSource *source,
996
- EWeatherSourceFinished done,
1000
GType e_weather_source_get_type (void);
1001
diff --git a/configure.ac b/configure.ac
1002
index e7e770f..2a68525 100644
1005
@@ -46,7 +46,7 @@ m4_define([libical_minimum_version], [0.43])
1007
dnl Optional Packages
1008
m4_define([goa_minimum_version], [3.2])
1009
-m4_define([gweather_minimum_version], [2.90.0])
1010
+m4_define([gweather_minimum_version], [3.5.0])
1012
AC_SUBST([BASE_VERSION],[base_version])
1013
AC_SUBST([API_VERSION],[api_version])
1014
@@ -1103,11 +1103,6 @@ AC_MSG_RESULT([$use_gweather])
1015
if test "x$use_gweather" = "xyes"; then
1016
PKG_CHECK_MODULES([LIBGWEATHER], [gweather-3.0 >= gweather_minimum_version],[],
1017
[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.])])
1019
- dnl gweather-3.5 introduces API changes we do not yet support.
1020
- if `$PKG_CONFIG --atleast-version=3.5 gweather-3.0`; then
1021
- 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.])
1024
AM_CONDITIONAL(ENABLE_WEATHER, [test $use_gweather = yes])