1
/* Evolution calendar - weather backend
3
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
5
* Authors: David Trowbridge <trowbrds@cs.colorado.edu>
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of version 2 of the GNU Lesser General Public
9
* License as published by the Free Software Foundation.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
#include <glib/gi18n-lib.h>
25
#include "e-cal-backend-weather.h"
26
#include "e-source-weather.h"
27
#include "e-weather-source.h"
29
#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
30
#include <libgweather/weather.h>
31
#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
33
#define WEATHER_UID_EXT "-weather"
35
#define E_CAL_BACKEND_WEATHER_GET_PRIVATE(obj) \
36
(G_TYPE_INSTANCE_GET_PRIVATE \
37
((obj), E_TYPE_CAL_BACKEND_WEATHER, ECalBackendWeatherPrivate))
39
#define EDC_ERROR(_code) e_data_cal_create_error (_code, NULL)
40
#define EDC_ERROR_EX(_code, _msg) e_data_cal_create_error (_code, _msg)
42
G_DEFINE_TYPE (ECalBackendWeather, e_cal_backend_weather, E_TYPE_CAL_BACKEND_SYNC)
44
static gboolean reload_cb (ECalBackendWeather *cbw);
45
static gboolean begin_retrieval_cb (ECalBackendWeather *cbw);
46
static ECalComponent * create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_forecast);
47
static void e_cal_backend_weather_add_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzobj, GError **perror);
49
/* Private part of the ECalBackendWeather structure */
50
struct _ECalBackendWeatherPrivate {
51
/* URI to get remote weather data from */
55
ECalBackendStore *store;
60
guint reload_timeout_id;
66
/* City (for summary) */
70
EWeatherSource *source;
72
guint begin_retrival_id;
76
reload_cb (ECalBackendWeather *cbw)
78
ECalBackendWeatherPrivate *priv;
85
priv->reload_timeout_id = 0;
87
begin_retrieval_cb (cbw);
92
maybe_start_reload_timeout (ECalBackendWeather *cbw)
94
ECalBackendWeatherPrivate *priv;
96
ESourceRefresh *extension;
97
const gchar *extension_name;
98
guint interval_in_minutes = 0;
102
if (priv->reload_timeout_id)
105
source = e_backend_get_source (E_BACKEND (cbw));
107
extension_name = E_SOURCE_EXTENSION_REFRESH;
108
extension = e_source_get_extension (source, extension_name);
110
/* By default, reload every 4 hours. At least for CCF, the forecasts
111
* only come out twice a day, and chances are while the NWS and similar
112
* organizations have some serious bandwidth, they would appreciate it
113
* if we didn't hammer their servers. */
114
if (e_source_refresh_get_enabled (extension)) {
115
interval_in_minutes =
116
e_source_refresh_get_interval_minutes (extension);
117
if (interval_in_minutes == 0)
118
interval_in_minutes = 240;
121
if (interval_in_minutes > 0)
122
priv->reload_timeout_id = g_timeout_add_seconds (
123
interval_in_minutes * 60,
124
(GSourceFunc) reload_cb, cbw);
127
/* TODO Do not replicate this in every backend */
128
static icaltimezone *
129
resolve_tzid (const gchar *tzid,
134
zone = (!strcmp (tzid, "UTC"))
135
? icaltimezone_get_utc_timezone ()
136
: icaltimezone_get_builtin_timezone_from_tzid (tzid);
139
zone = e_cal_backend_internal_get_timezone (E_CAL_BACKEND (user_data), tzid);
145
put_component_to_store (ECalBackendWeather *cb,
148
time_t time_start, time_end;
149
ECalBackendWeatherPrivate *priv;
153
e_cal_util_get_component_occur_times (comp, &time_start, &time_end,
154
resolve_tzid, cb, icaltimezone_get_utc_timezone (),
155
e_cal_backend_get_kind (E_CAL_BACKEND (cb)));
157
e_cal_backend_store_put_component_with_time_range (priv->store, comp, time_start, time_end);
161
finished_retrieval_cb (WeatherInfo *info,
162
ECalBackendWeather *cbw)
164
ECalBackendWeatherPrivate *priv;
171
e_cal_backend_notify_error (E_CAL_BACKEND (cbw), _("Could not retrieve weather data"));
176
comps = e_cal_backend_store_get_components (priv->store);
178
for (l = comps; l != NULL; l = g_slist_next (l)) {
181
comp = E_CAL_COMPONENT (l->data);
182
id = e_cal_component_get_id (comp);
184
e_cal_backend_notify_component_removed (E_CAL_BACKEND (cbw), id, comp, NULL);
186
e_cal_component_free_id (id);
187
g_object_unref (comp);
189
g_slist_free (comps);
190
e_cal_backend_store_clean (priv->store);
192
comp = create_weather (cbw, info, FALSE);
196
put_component_to_store (cbw, comp);
197
e_cal_backend_notify_component_created (E_CAL_BACKEND (cbw), comp);
198
g_object_unref (comp);
200
forecasts = weather_info_get_forecast_list (info);
204
/* skip the first one, it's for today, which has been added above */
205
for (f = forecasts->next; f; f = f->next) {
206
WeatherInfo *nfo = f->data;
209
comp = create_weather (cbw, nfo, TRUE);
211
put_component_to_store (cbw, comp);
212
e_cal_backend_notify_component_created (E_CAL_BACKEND (cbw), comp);
213
g_object_unref (comp);
220
priv->is_loading = FALSE;
224
begin_retrieval_cb (ECalBackendWeather *cbw)
226
ECalBackendWeatherPrivate *priv = cbw->priv;
230
/* XXX Too much overloading of the word 'source' here! */
232
if (!e_backend_get_online (E_BACKEND (cbw)))
235
maybe_start_reload_timeout (cbw);
237
e_source = e_backend_get_source (E_BACKEND (cbw));
239
if (priv->source == NULL) {
240
ESourceWeather *extension;
241
const gchar *extension_name;
244
extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
245
extension = e_source_get_extension (e_source, extension_name);
247
location = e_source_weather_dup_location (extension);
248
priv->source = e_weather_source_new (location);
252
source = g_main_current_source ();
254
if (priv->begin_retrival_id == g_source_get_id (source))
255
priv->begin_retrival_id = 0;
257
if (priv->is_loading)
260
priv->is_loading = TRUE;
262
e_weather_source_parse (
263
priv->source, (EWeatherSourceFinished)
264
finished_retrieval_cb, cbw);
270
getCategory (WeatherInfo *report)
273
const gchar *description;
274
const gchar *icon_name;
276
{ N_("Weather: Fog"), "weather-fog" },
277
{ N_("Weather: Cloudy Night"), "weather-few-clouds-night" },
278
{ N_("Weather: Cloudy"), "weather-few-clouds" },
279
{ N_("Weather: Overcast"), "weather-overcast" },
280
{ N_("Weather: Showers"), "weather-showers" },
281
{ N_("Weather: Snow"), "weather-snow" },
282
{ N_("Weather: Clear Night"), "weather-clear-night" },
283
{ N_("Weather: Sunny"), "weather-clear" },
284
{ N_("Weather: Thunderstorms"), "weather-storm" },
289
const gchar *icon_name = weather_info_get_icon_name (report);
294
for (i = 0; categories[i].description; i++) {
295
if (!g_ascii_strncasecmp (categories[i].icon_name,
296
icon_name, strlen (icon_name)))
297
return _(categories[i].description);
303
static ECalComponent *
304
create_weather (ECalBackendWeather *cbw,
306
gboolean is_forecast)
308
ECalBackendWeatherPrivate *priv;
309
ECalComponent *cal_comp;
310
ECalComponentText comp_summary;
311
icalcomponent *ical_comp;
312
struct icaltimetype itt;
313
ECalComponentDateTime dt;
315
GSList *text_list = NULL;
316
ECalComponentText *description;
320
icaltimezone *update_zone = NULL;
321
ESourceWeather *extension;
322
const gchar *extension_name;
323
const WeatherLocation *location;
324
ESourceWeatherUnits units;
326
g_return_val_if_fail (E_IS_CAL_BACKEND_WEATHER (cbw), NULL);
328
if (!weather_info_get_value_update (report, &update_time))
333
source = e_backend_get_source (E_BACKEND (cbw));
335
extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
336
extension = e_source_get_extension (source, extension_name);
337
units = e_source_weather_get_units (extension);
339
/* Prefer metric if units is invalid. */
340
if (units == E_SOURCE_WEATHER_UNITS_IMPERIAL)
341
weather_info_to_imperial (report);
343
weather_info_to_metric (report);
345
/* create the component and event object */
346
ical_comp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
347
cal_comp = e_cal_component_new ();
348
e_cal_component_set_icalcomponent (cal_comp, ical_comp);
351
uid = e_cal_component_gen_uid ();
352
e_cal_component_set_uid (cal_comp, uid);
355
/* use timezone of the location to determine date for which this is set */
356
location = weather_info_get_location (report);
357
if (location && location->tz_hint && *location->tz_hint)
358
update_zone = icaltimezone_get_builtin_timezone (location->tz_hint);
361
update_zone = icaltimezone_get_utc_timezone ();
363
/* Set all-day event's date from forecast data - cannot set is_date,
364
* because in that case no timezone conversion is done */
365
itt = icaltime_from_timet_with_zone (update_time, 0, update_zone);
373
dt.tzid = icaltimezone_get_tzid (update_zone);
377
e_cal_component_set_dtstart (cal_comp, &dt);
379
icaltime_adjust (&itt, 1, 0, 0, 0);
380
/* We have to add 1 day to DTEND, as it is not inclusive. */
381
e_cal_component_set_dtend (cal_comp, &dt);
384
gdouble tmin = 0.0, tmax = 0.0;
386
if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) &&
387
weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &tmax) &&
389
/* because weather_info_get_temp* uses one internal buffer, thus finally
390
* the last value is shown for both, which is obviously wrong */
391
GString *str = g_string_new (priv->city);
393
g_string_append (str, " : ");
394
g_string_append (str, weather_info_get_temp_min (report));
395
g_string_append (str, "/");
396
g_string_append (str, weather_info_get_temp_max (report));
398
comp_summary.value = g_string_free (str, FALSE);
400
comp_summary.value = g_strdup_printf ("%s : %s", priv->city, weather_info_get_temp (report));
403
gdouble tmin = 0.0, tmax = 0.0;
404
/* because weather_info_get_temp* uses one internal buffer, thus finally
405
* the last value is shown for both, which is obviously wrong */
406
GString *str = g_string_new (priv->city);
408
g_string_append (str, " : ");
409
if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) &&
410
weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &tmax) &&
412
g_string_append (str, weather_info_get_temp_min (report));
413
g_string_append (str, "/");
414
g_string_append (str, weather_info_get_temp_max (report));
416
g_string_append (str, weather_info_get_temp (report));
419
comp_summary.value = g_string_free (str, FALSE);
421
comp_summary.altrep = NULL;
422
e_cal_component_set_summary (cal_comp, &comp_summary);
423
g_free ((gchar *) comp_summary.value);
425
tmp = weather_info_get_forecast (report);
426
comp_summary.value = weather_info_get_weather_summary (report);
428
description = g_new0 (ECalComponentText, 1);
429
description->value = g_strconcat (is_forecast ? "" : comp_summary.value, is_forecast ? "" : "\n", tmp ? _("Forecast") : "", tmp ? ":" : "", tmp && !is_forecast ? "\n" : "", tmp ? tmp : "", NULL);
430
description->altrep = "";
431
text_list = g_slist_append (text_list, description);
432
e_cal_component_set_description_list (cal_comp, text_list);
433
g_free ((gchar *) comp_summary.value);
435
/* Set category and visibility */
436
e_cal_component_set_categories (cal_comp, getCategory (report));
437
e_cal_component_set_classification (cal_comp, E_CAL_COMPONENT_CLASS_PUBLIC);
439
/* Weather is shown as free time */
440
e_cal_component_set_transparency (cal_comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT);
442
e_cal_component_commit_sequence (cal_comp);
448
e_cal_backend_weather_get_backend_property (ECalBackendSync *backend,
450
GCancellable *cancellable,
451
const gchar *prop_name,
455
gboolean processed = TRUE;
457
g_return_val_if_fail (prop_name != NULL, FALSE);
458
g_return_val_if_fail (prop_value != NULL, FALSE);
460
if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
461
*prop_value = g_strdup (CAL_STATIC_CAPABILITY_NO_ALARM_REPEAT ","
462
CAL_STATIC_CAPABILITY_NO_AUDIO_ALARMS ","
463
CAL_STATIC_CAPABILITY_NO_DISPLAY_ALARMS ","
464
CAL_STATIC_CAPABILITY_NO_PROCEDURE_ALARMS ","
465
CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT ","
466
CAL_STATIC_CAPABILITY_NO_THISANDFUTURE ","
467
CAL_STATIC_CAPABILITY_NO_THISANDPRIOR ","
468
CAL_STATIC_CAPABILITY_REFRESH_SUPPORTED);
469
} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS) ||
470
g_str_equal (prop_name, CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS)) {
471
/* Weather has no particular email addresses associated with it */
473
} else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_DEFAULT_OBJECT)) {
474
g_propagate_error (perror, EDC_ERROR (UnsupportedMethod));
483
e_cal_backend_weather_open (ECalBackendSync *backend,
485
GCancellable *cancellable,
486
gboolean only_if_exists,
489
ECalBackendWeather *cbw;
490
ECalBackendWeatherPrivate *priv;
492
ESourceWeather *extension;
493
const gchar *extension_name;
494
const gchar *cache_dir;
498
cbw = E_CAL_BACKEND_WEATHER (backend);
501
source = e_backend_get_source (E_BACKEND (backend));
502
cache_dir = e_cal_backend_get_cache_dir (E_CAL_BACKEND (backend));
504
extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
505
extension = e_source_get_extension (source, extension_name);
509
location = e_source_weather_dup_location (extension);
510
priv->city = g_strdup (strrchr (location, '/') + 1);
513
e_cal_backend_notify_readonly (E_CAL_BACKEND (backend), TRUE);
515
online = e_backend_get_online (E_BACKEND (backend));
516
e_cal_backend_notify_online (E_CAL_BACKEND (backend), online);
519
e_cal_backend_cache_remove (cache_dir, "cache.xml");
520
priv->store = e_cal_backend_file_store_new (cache_dir);
523
g_propagate_error (perror, EDC_ERROR_EX (OtherError, _("Could not create cache file")));
527
/* do we require to load this new store */
528
e_cal_backend_store_load (priv->store);
529
e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
531
if (!e_backend_get_online (E_BACKEND (backend)))
534
if (!priv->begin_retrival_id)
535
priv->begin_retrival_id = g_idle_add ((GSourceFunc) begin_retrieval_cb, cbw);
538
e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
542
e_cal_backend_weather_refresh (ECalBackendSync *backend,
544
GCancellable *cancellable,
547
ECalBackendWeather *cbw;
548
ECalBackendWeatherPrivate *priv;
550
cbw = E_CAL_BACKEND_WEATHER (backend);
557
if (priv->reload_timeout_id)
558
g_source_remove (priv->reload_timeout_id);
559
priv->reload_timeout_id = 0;
561
/* wait a second, then start reloading */
562
priv->reload_timeout_id = g_timeout_add (1000, (GSourceFunc) reload_cb, cbw);
566
e_cal_backend_weather_remove (ECalBackendSync *backend,
568
GCancellable *cancellable,
571
ECalBackendWeather *cbw;
572
ECalBackendWeatherPrivate *priv;
574
cbw = E_CAL_BACKEND_WEATHER (backend);
578
/* lie here a bit, but otherwise the calendar will not be removed, even it should */
579
g_print (G_STRLOC ": Doesn't have a cache?!?");
583
e_cal_backend_store_remove (priv->store);
587
e_cal_backend_weather_receive_objects (ECalBackendSync *backend,
589
GCancellable *cancellable,
593
g_propagate_error (perror, EDC_ERROR (PermissionDenied));
597
e_cal_backend_weather_get_object (ECalBackendSync *backend,
599
GCancellable *cancellable,
605
ECalBackendWeather *cbw = E_CAL_BACKEND_WEATHER (backend);
606
ECalBackendWeatherPrivate *priv = cbw->priv;
609
e_return_data_cal_error_if_fail (uid != NULL, InvalidArg);
610
e_return_data_cal_error_if_fail (priv->store != NULL, InvalidArg);
612
comp = e_cal_backend_store_get_component (priv->store, uid, rid);
614
g_propagate_error (error, EDC_ERROR (ObjectNotFound));
618
*object = e_cal_component_get_as_string (comp);
619
g_object_unref (comp);
623
e_cal_backend_weather_get_object_list (ECalBackendSync *backend,
625
GCancellable *cancellable,
626
const gchar *sexp_string,
630
ECalBackendWeather *cbw = E_CAL_BACKEND_WEATHER (backend);
631
ECalBackendWeatherPrivate *priv = cbw->priv;
632
ECalBackendSExp *sexp = e_cal_backend_sexp_new (sexp_string);
633
GSList *components, *l;
634
time_t occur_start = -1, occur_end = -1;
635
gboolean prunning_by_time;
638
g_propagate_error (perror, EDC_ERROR (InvalidQuery));
643
prunning_by_time = e_cal_backend_sexp_evaluate_occur_times (sexp,
647
components = prunning_by_time ?
648
e_cal_backend_store_get_components_occuring_in_range (priv->store, occur_start, occur_end)
649
: e_cal_backend_store_get_components (priv->store);
651
for (l = components; l != NULL; l = g_slist_next (l)) {
652
if (e_cal_backend_sexp_match_comp (sexp, E_CAL_COMPONENT (l->data), E_CAL_BACKEND (backend)))
653
*objects = g_slist_append (*objects, e_cal_component_get_as_string (l->data));
656
g_slist_foreach (components, (GFunc) g_object_unref, NULL);
657
g_slist_free (components);
658
g_object_unref (sexp);
662
e_cal_backend_weather_add_timezone (ECalBackendSync *backend,
664
GCancellable *cancellable,
668
ECalBackendWeather *cbw;
669
ECalBackendWeatherPrivate *priv;
670
icalcomponent *tz_comp;
674
cbw = (ECalBackendWeather *) backend;
676
e_return_data_cal_error_if_fail (E_IS_CAL_BACKEND_WEATHER (cbw), InvalidArg);
677
e_return_data_cal_error_if_fail (tzobj != NULL, InvalidArg);
681
tz_comp = icalparser_parse_string (tzobj);
682
e_return_data_cal_error_if_fail (tz_comp != NULL, InvalidObject);
684
if (icalcomponent_isa (tz_comp) != ICAL_VTIMEZONE_COMPONENT) {
685
g_propagate_error (error, EDC_ERROR (InvalidObject));
689
zone = icaltimezone_new ();
690
icaltimezone_set_component (zone, tz_comp);
691
tzid = icaltimezone_get_tzid (zone);
693
if (g_hash_table_lookup (priv->zones, tzid)) {
694
icaltimezone_free (zone, TRUE);
696
g_hash_table_insert (priv->zones, g_strdup (tzid), zone);
701
e_cal_backend_weather_get_free_busy (ECalBackendSync *backend,
703
GCancellable *cancellable,
710
/* Weather doesn't count as busy time */
711
icalcomponent *vfb = icalcomponent_new_vfreebusy ();
712
icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
715
icalcomponent_set_dtstart (vfb, icaltime_from_timet_with_zone (start, FALSE, utc_zone));
716
icalcomponent_set_dtend (vfb, icaltime_from_timet_with_zone (end, FALSE, utc_zone));
718
calobj = icalcomponent_as_ical_string_r (vfb);
719
*freebusy = g_slist_append (NULL, calobj);
720
icalcomponent_free (vfb);
724
e_cal_backend_weather_start_view (ECalBackend *backend,
727
ECalBackendWeather *cbw;
728
ECalBackendWeatherPrivate *priv;
729
ECalBackendSExp *sexp;
730
GSList *components, *l;
733
time_t occur_start = -1, occur_end = -1;
734
gboolean prunning_by_time;
736
cbw = E_CAL_BACKEND_WEATHER (backend);
740
error = EDC_ERROR (NoSuchCal);
741
e_data_cal_view_notify_complete (query, error);
742
g_error_free (error);
746
sexp = e_data_cal_view_get_object_sexp (query);
748
error = EDC_ERROR (InvalidQuery);
749
e_data_cal_view_notify_complete (query, error);
750
g_error_free (error);
755
prunning_by_time = e_cal_backend_sexp_evaluate_occur_times (sexp, &occur_start, &occur_end);
756
components = prunning_by_time ?
757
e_cal_backend_store_get_components_occuring_in_range (priv->store, occur_start, occur_end)
758
: e_cal_backend_store_get_components (priv->store);
760
for (l = components; l != NULL; l = g_slist_next (l)) {
761
if (e_cal_backend_sexp_match_comp (sexp, E_CAL_COMPONENT (l->data), backend))
762
objects = g_slist_prepend (objects, l->data);
766
e_data_cal_view_notify_components_added (query, objects);
768
g_slist_free_full (components, g_object_unref);
769
g_slist_free (objects);
771
e_data_cal_view_notify_complete (query, NULL /* Success */);
775
e_cal_backend_weather_notify_online_cb (ECalBackend *backend,
778
ECalBackendWeather *cbw;
779
ECalBackendWeatherPrivate *priv;
783
cbw = E_CAL_BACKEND_WEATHER (backend);
786
online = e_backend_get_online (E_BACKEND (backend));
787
loaded = e_cal_backend_is_opened (backend);
789
if (loaded && priv->reload_timeout_id) {
790
g_source_remove (priv->reload_timeout_id);
791
priv->reload_timeout_id = 0;
795
e_cal_backend_notify_online (backend, online);
796
e_cal_backend_notify_readonly (backend, TRUE);
800
static icaltimezone *
801
e_cal_backend_weather_internal_get_timezone (ECalBackend *backend,
806
g_return_val_if_fail (tzid != NULL, NULL);
808
if (!strcmp (tzid, "UTC")) {
809
zone = icaltimezone_get_utc_timezone ();
811
ECalBackendWeather *cbw = E_CAL_BACKEND_WEATHER (backend);
813
g_return_val_if_fail (E_IS_CAL_BACKEND_WEATHER (cbw), NULL);
815
zone = g_hash_table_lookup (cbw->priv->zones, tzid);
817
if (!zone && E_CAL_BACKEND_CLASS (e_cal_backend_weather_parent_class)->internal_get_timezone)
818
zone = E_CAL_BACKEND_CLASS (e_cal_backend_weather_parent_class)->internal_get_timezone (backend, tzid);
825
free_zone (gpointer data)
827
icaltimezone_free (data, TRUE);
830
/* Finalize handler for the weather backend */
832
e_cal_backend_weather_finalize (GObject *object)
834
ECalBackendWeatherPrivate *priv;
836
priv = E_CAL_BACKEND_WEATHER_GET_PRIVATE (object);
838
if (priv->reload_timeout_id)
839
g_source_remove (priv->reload_timeout_id);
841
if (priv->begin_retrival_id)
842
g_source_remove (priv->begin_retrival_id);
845
g_object_unref (priv->store);
849
g_hash_table_destroy (priv->zones);
853
/* Chain up to parent's finalize() method. */
854
G_OBJECT_CLASS (e_cal_backend_weather_parent_class)->finalize (object);
857
/* Object initialization function for the weather backend */
859
e_cal_backend_weather_init (ECalBackendWeather *cbw)
861
cbw->priv = E_CAL_BACKEND_WEATHER_GET_PRIVATE (cbw);
863
cbw->priv->zones = g_hash_table_new_full (
864
(GHashFunc) g_str_hash,
865
(GEqualFunc) g_str_equal,
866
(GDestroyNotify) g_free,
867
(GDestroyNotify) free_zone);
869
e_cal_backend_sync_set_lock (E_CAL_BACKEND_SYNC (cbw), TRUE);
872
cbw, "notify::online",
873
G_CALLBACK (e_cal_backend_weather_notify_online_cb), NULL);
876
/* Class initialization function for the weather backend */
878
e_cal_backend_weather_class_init (ECalBackendWeatherClass *class)
880
GObjectClass *object_class;
881
ECalBackendClass *backend_class;
882
ECalBackendSyncClass *sync_class;
884
g_type_class_add_private (class, sizeof (ECalBackendWeatherPrivate));
886
object_class = (GObjectClass *) class;
887
backend_class = (ECalBackendClass *) class;
888
sync_class = (ECalBackendSyncClass *) class;
890
object_class->finalize = e_cal_backend_weather_finalize;
892
sync_class->get_backend_property_sync = e_cal_backend_weather_get_backend_property;
893
sync_class->open_sync = e_cal_backend_weather_open;
894
sync_class->refresh_sync = e_cal_backend_weather_refresh;
895
sync_class->remove_sync = e_cal_backend_weather_remove;
896
sync_class->receive_objects_sync = e_cal_backend_weather_receive_objects;
897
sync_class->get_object_sync = e_cal_backend_weather_get_object;
898
sync_class->get_object_list_sync = e_cal_backend_weather_get_object_list;
899
sync_class->add_timezone_sync = e_cal_backend_weather_add_timezone;
900
sync_class->get_free_busy_sync = e_cal_backend_weather_get_free_busy;
902
backend_class->start_view = e_cal_backend_weather_start_view;
903
backend_class->internal_get_timezone = e_cal_backend_weather_internal_get_timezone;
905
/* Register our ESource extension. */
906
E_TYPE_SOURCE_WEATHER;