[evolution-data-server/libgdata-port] Tidy up recurrence support, adding support for addition of recurrent events
- From: Philip Withnall <pwithnall src gnome org>
- To: svn-commits-list gnome org
- Subject: [evolution-data-server/libgdata-port] Tidy up recurrence support, adding support for addition of recurrent events
- Date: Tue, 30 Jun 2009 18:36:28 +0000 (UTC)
commit 32c7b902866527e8dd64c36b94f18563edec84fb
Author: Philip Withnall <philip tecnocode co uk>
Date: Sun May 31 21:26:07 2009 +0100
Tidy up recurrence support, adding support for addition of recurrent events
.../backends/google/e-cal-backend-google-utils.c | 251 +++++++++++++++++---
calendar/backends/google/e-cal-backend-google.c | 13 +-
calendar/backends/google/e-cal-backend-google.h | 1 -
3 files changed, 222 insertions(+), 43 deletions(-)
---
diff --git a/calendar/backends/google/e-cal-backend-google-utils.c b/calendar/backends/google/e-cal-backend-google-utils.c
index 54a0fc1..d049ed6 100644
--- a/calendar/backends/google/e-cal-backend-google-utils.c
+++ b/calendar/backends/google/e-cal-backend-google-utils.c
@@ -60,8 +60,7 @@
/****************************************************** Google Connection Helper Functions ***********************************************/
-static gboolean gd_timeval_to_ical (GDataCalendarEvent *event, GTimeVal *timeval, struct icaltimetype *itt, ECalComponentDateTime *dt,
- icaltimezone *default_zone);
+static gboolean gd_timeval_to_ical (GTimeVal *timeval, struct icaltimetype *itt, ECalComponentDateTime *dt, icaltimezone *default_zone);
static void get_timeval (ECalComponentDateTime dt, GTimeVal *timeval);
static gint utils_compare_ids (gconstpointer cache_id, gconstpointer modified_cache_id);
static gchar * utils_form_query (const gchar *query);
@@ -221,14 +220,14 @@ e_cal_backend_google_utils_update (gpointer handle)
/* Find the Removed Item */
iter_list = NULL;
for (iter_list = ids_list; iter_list != NULL; iter_list = iter_list->next) {
- GSList *remove = g_slist_find_custom (cache_keys, iter_list->data, (GCompareFunc) utils_compare_ids);
+ GSList *remove_list = g_slist_find_custom (cache_keys, iter_list->data, (GCompareFunc) utils_compare_ids);
- if (!remove) {
+ if (!remove_list) {
uid_list = g_slist_prepend (uid_list, g_strdup ((gchar *)iter_list->data));
needs_to_insert = TRUE;
} else {
- cache_keys = g_slist_remove_link (cache_keys, remove);
- g_slist_free (remove);
+ cache_keys = g_slist_remove_link (cache_keys, remove_list);
+ g_slist_free (remove_list);
}
}
@@ -400,29 +399,29 @@ e_gdata_event_to_cal_component (GDataCalendarEvent *event, ECalBackendGoogle *cb
/* Description*/
description = gdata_entry_get_content (GDATA_ENTRY (event));
if (description) {
- GSList l;
+ GSList li;
text.value = description;
text.altrep = NULL;
- l.data = &text;
- l.next = NULL;
- e_cal_component_set_description_list (comp, &l);
+ li.data = &text;
+ li.next = NULL;
+ e_cal_component_set_description_list (comp, &li);
}
/* Creation/Last update */
gdata_entry_get_published (GDATA_ENTRY (event), &timeval);
- if (gd_timeval_to_ical (event, &timeval, &itt, &dt, default_zone))
+ if (gd_timeval_to_ical (&timeval, &itt, &dt, default_zone))
e_cal_component_set_created (comp, &itt);
gdata_entry_get_updated (GDATA_ENTRY (event), &timeval);
- if (gd_timeval_to_ical (event, &timeval, &itt, &dt, default_zone))
+ if (gd_timeval_to_ical (&timeval, &itt, &dt, default_zone))
e_cal_component_set_dtstamp (comp, &itt);
/* Start/End times */
/* TODO: deal with multiple time periods */
gdata_calendar_event_get_primary_time (event, &timeval, &timeval2, NULL);
- if (gd_timeval_to_ical (event, &timeval, &itt, &dt_start, default_zone))
+ if (gd_timeval_to_ical (&timeval, &itt, &dt_start, default_zone))
e_cal_component_set_dtstart (comp, &dt_start);
- if (gd_timeval_to_ical (event, &timeval2, &itt, &dt, default_zone))
+ if (gd_timeval_to_ical (&timeval2, &itt, &dt, default_zone))
e_cal_component_set_dtend (comp, &dt);
/* Summary of the event */
@@ -529,6 +528,7 @@ e_gdata_event_to_cal_component (GDataCalendarEvent *event, ECalBackendGoogle *cb
guint recurrence_length = strlen (recurrence);
do {
+ icalproperty *prop;
const gchar *f = NULL;
if (i == NULL || *i == '\0' || i - recurrence >= recurrence_length)
@@ -550,19 +550,68 @@ e_gdata_event_to_cal_component (GDataCalendarEvent *event, ECalBackendGoogle *cb
goto next_property;
/* Parse the recurrence properties */
- if (strncmp (i, "RRULE:", 6) == 0) {
- struct icalrecurrencetype recur;
+ if (strncmp (i, "DTSTART", 7) == 0) {
+ struct icaltimetype recur;
+ gchar *recur_string;
+
+ /* Parse the dtstart property; this takes priority over that retrieved from gdata_calendar_event_get_primary_time */
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
+ g_free (recur_string);
+
+ if (icalproperty_isa (prop) != ICAL_DTSTART_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_dtstart (prop);
+ icalproperty_free (prop);
+ itt = icaltime_convert_to_zone (recur, default_zone);
+ dt.value = &itt;
+ dt.tzid = NULL;
+ e_cal_component_set_dtstart (comp, &dt);
+ } else if (strncmp (i, "DTEND", 5) == 0) {
+ struct icaltimetype recur;
+ gchar *recur_string;
+
+ /* Parse the dtend property; this takes priority over that retrieved from gdata_calendar_event_get_primary_time */
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
+ g_free (recur_string);
+
+ if (icalproperty_isa (prop) != ICAL_DTEND_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_dtstart (prop);
+ icalproperty_free (prop);
+ itt = icaltime_convert_to_zone (recur, default_zone);
+ dt.value = &itt;
+ dt.tzid = NULL;
+ e_cal_component_set_dtend (comp, &dt);
+ } else if (strncmp (i, "RRULE", 5) == 0) {
+ struct icalrecurrencetype recur, *recur2;
gchar *recur_string;
/* Parse the rrule property */
- recur_string = g_strndup (i + 6, f - i);
- recur = icalrecurrencetype_from_string (recur_string);
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
g_free (recur_string);
- rrule_list = g_slist_prepend (rrule_list, &recur);
- } else if (strncmp (i, "RDATE:", 6) == 0) {
+ if (icalproperty_isa (prop) != ICAL_RRULE_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_rrule (prop);
+ icalproperty_free (prop);
+ recur2 = g_memdup (&recur, sizeof (recur));
+ rrule_list = g_slist_prepend (rrule_list, recur2);
+ } else if (strncmp (i, "RDATE", 5) == 0) {
struct icaldatetimeperiodtype recur;
- icalproperty *prop;
+ ECalComponentPeriod *period;
+ icalvalue *value;
gchar *recur_string;
/* Parse the rdate property */
@@ -570,30 +619,68 @@ e_gdata_event_to_cal_component (GDataCalendarEvent *event, ECalBackendGoogle *cb
prop = icalproperty_new_from_string (recur_string);
g_free (recur_string);
+ if (icalproperty_isa (prop) != ICAL_RDATE_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
recur = icalproperty_get_rdate (prop);
+ value = icalproperty_get_value (prop);
+
+ period = g_new0 (ECalComponentPeriod, 1);
+ period->start = recur.period.start;
+ if (icalvalue_isa (value) == ICAL_VALUE_DATE || icalvalue_isa (value) == ICAL_VALUE_DATETIME) {
+ period->type = E_CAL_COMPONENT_PERIOD_DATETIME;
+ period->u.end = recur.period.end;
+ } else if (icalvalue_isa (value) == ICAL_VALUE_DURATION) {
+ period->type = E_CAL_COMPONENT_PERIOD_DURATION;
+ period->u.duration = recur.period.duration;
+ } else {
+ g_assert_not_reached ();
+ }
icalproperty_free (prop);
- rdate_list = g_slist_prepend (rdate_list, &recur);
- } else if (strncmp (i, "EXRULE:", 7) == 0) {
- struct icalrecurrencetype recur;
+ rdate_list = g_slist_prepend (rdate_list, period);
+ } else if (strncmp (i, "EXRULE", 6) == 0) {
+ struct icalrecurrencetype recur, *recur2;
gchar *recur_string;
/* Parse the exrule property */
- recur_string = g_strndup (i + 7, f - i);
- recur = icalrecurrencetype_from_string (recur_string);
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
g_free (recur_string);
- exrule_list = g_slist_prepend (exrule_list, &recur);
- } else if (strncmp (i, "EXDATE:", 7) == 0) {
+ if (icalproperty_isa (prop) != ICAL_EXRULE_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_rrule (prop);
+ icalproperty_free (prop);
+ recur2 = g_memdup (&recur, sizeof (recur));
+ exrule_list = g_slist_prepend (exrule_list, recur2);
+ } else if (strncmp (i, "EXDATE", 6) == 0) {
struct icaltimetype recur;
+ ECalComponentDateTime *date_time;
gchar *recur_string;
/* Parse the exdate property */
- recur_string = g_strndup (i + 7, f - i);
+ recur_string = g_strndup (i, f - i);
+ prop = icalproperty_new_from_string (recur_string);
recur = icaltime_from_string (recur_string);
g_free (recur_string);
- exdate_list = g_slist_prepend (exdate_list, &recur);
+ if (icalproperty_isa (prop) != ICAL_EXDATE_PROPERTY) {
+ icalproperty_free (prop);
+ goto next_property;
+ }
+
+ recur = icalproperty_get_exdate (prop);
+ icalproperty_free (prop);
+ itt = icaltime_convert_to_zone (recur, default_zone);
+ date_time = g_new0 (ECalComponentDateTime, 1);
+ date_time->value = g_memdup (&itt, sizeof (itt));
+ exdate_list = g_slist_prepend (exdate_list, date_time);
}
next_property:
@@ -603,18 +690,23 @@ next_property:
rrule_list = g_slist_reverse (rrule_list);
e_cal_component_set_rrule_list (comp, rrule_list);
+ g_slist_foreach (rrule_list, (GFunc) g_free, NULL);
g_slist_free (rrule_list);
rdate_list = g_slist_reverse (rdate_list);
e_cal_component_set_rdate_list (comp, rdate_list);
+ g_slist_foreach (rdate_list, (GFunc) g_free, NULL);
g_slist_free (rdate_list);
exrule_list = g_slist_reverse (exrule_list);
e_cal_component_set_exrule_list (comp, exrule_list);
+ g_slist_foreach (exrule_list, (GFunc) g_free, NULL);
g_slist_free (exrule_list);
exdate_list = g_slist_reverse (exdate_list);
e_cal_component_set_exdate_list (comp, exdate_list);
+ g_slist_foreach (exdate_list, (GFunc) e_cal_component_free_datetime, NULL);
+ g_slist_foreach (exdate_list, (GFunc) g_free, NULL);
g_slist_free (exdate_list);
}
@@ -668,15 +760,32 @@ e_gdata_event_from_cal_component (ECalBackendGoogle *cbgo, ECalComponent *comp)
return event;
}
+static char *
+comp_date_time_as_ical_string (ECalComponentDateTime *dt, icaltimezone *default_zone)
+{
+ icaltimetype itt;
+ icalproperty *prop;
+ char *buf;
+
+ itt = icaltime_convert_to_zone (*(dt->value), default_zone);
+ dt->value = &itt;
+ prop = icalproperty_new_dtend (*(dt->value));
+ buf = icalproperty_get_value_as_string_r (prop);
+ icalproperty_free (prop);
+
+ return buf;
+}
+
void
e_gdata_event_update_from_cal_component (ECalBackendGoogle *cbgo, GDataCalendarEvent *event, ECalComponent *comp)
{
ECalBackendGooglePrivate *priv;
ECalComponentText text;
ECalComponentDateTime dt;
- gchar *term = NULL;
+ const gchar *term = NULL;
icaltimezone *default_zone;
icaltimetype itt;
+ icalproperty *prop;
GTimeVal timeval, timeval2;
const char *location;
GSList *list = NULL;
@@ -684,6 +793,8 @@ e_gdata_event_update_from_cal_component (ECalBackendGoogle *cbgo, GDataCalendarE
GDataGDWhen *when;
ECalComponentText *t;
GSList *attendee_list = NULL, *l = NULL;
+ GString *recur_string;
+ char *buf;
priv = cbgo->priv;
@@ -764,10 +875,81 @@ e_gdata_event_update_from_cal_component (ECalBackendGoogle *cbgo, GDataCalendarE
gdata_calendar_event_add_person (event, who);
}
+ /* Recurrence support */
+ recur_string = g_string_new (NULL);
+
+ e_cal_component_get_dtstart (comp, &dt);
+ buf = comp_date_time_as_ical_string (&dt, default_zone);
+ g_string_append_printf (recur_string, "DTSTART:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+
+ e_cal_component_get_dtend (comp, &dt);
+ buf = comp_date_time_as_ical_string (&dt, default_zone);
+ g_string_append_printf (recur_string, "DTEND:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+
+ e_cal_component_get_rrule_list (comp, &list);
+ for (l = list; l != NULL; l = l->next) {
+ /* Append each rrule to recur_string */
+ buf = icalrecurrencetype_as_string_r ((struct icalrecurrencetype*) l->data);
+ g_string_append_printf (recur_string, "RRULE:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+ }
+ e_cal_component_free_recur_list (list);
+
+ e_cal_component_get_rdate_list (comp, &list);
+ for (l = list; l != NULL; l = l->next) {
+ /* Append each rdate to recur_string */
+ struct icaldatetimeperiodtype date_time_period = { { 0, }, };
+ ECalComponentPeriod *period = l->data;
+
+ /* Build a struct icaldatetimeperiodtypeâ?¦ */
+ date_time_period.time = period->start;
+ date_time_period.period.start = period->start;
+ if (period->type == E_CAL_COMPONENT_PERIOD_DATETIME)
+ date_time_period.period.end = period->u.end;
+ else if (period->type == E_CAL_COMPONENT_PERIOD_DURATION)
+ date_time_period.period.duration = period->u.duration;
+ else
+ g_assert_not_reached ();
+
+ /* â?¦allowing us to build an icalproperty and get it in string form */
+ prop = icalproperty_new_rdate (date_time_period);
+
+ buf = icalproperty_get_value_as_string_r (prop);
+ g_string_append_printf (recur_string, "RDATE:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+ icalproperty_free (prop);
+ }
+ e_cal_component_free_period_list (list);
+
+ e_cal_component_get_exrule_list (comp, &list);
+ for (l = list; l != NULL; l = l->next) {
+ /* Append each exrule to recur_string */
+ buf = icalrecurrencetype_as_string_r ((struct icalrecurrencetype*) l->data);
+ g_string_append_printf (recur_string, "EXRULE:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+ }
+ e_cal_component_free_recur_list (list);
+
+ e_cal_component_get_exdate_list (comp, &list);
+ for (l = list; l != NULL; l = l->next) {
+ /* Append each exdate to recur_string */
+ ECalComponentDateTime *date_time = l->data;
+
+ /* Build an icalproperty and get the exdate in string form */
+ buf = comp_date_time_as_ical_string (date_time, default_zone);
+ g_string_append_printf (recur_string, "EXDATE:%s\r\n", buf);
+ icalmemory_free_buffer (buf);
+ }
+ e_cal_component_free_exdate_list (list);
+
+ /* Set the recurrence data on the event */
+ gdata_calendar_event_set_recurrence (event, g_string_free (recur_string, FALSE));
+
/* FIXME For transparency and status */
}
-
/***************************************************************** Utility Functions *********************************************/
static gint
@@ -811,9 +993,6 @@ utils_update_insertion (ECalBackendGoogle *cbgo, ECalBackendCache *cache, GDataF
g_object_unref (comp);
}
}
-
- if (list)
- g_slist_free (list);
}
@@ -892,7 +1071,7 @@ get_deltas_timeout (gpointer cbgo)
* @note Do not free itt or dt values, those come from buildin structures held by libical
**/
static gboolean
-gd_timeval_to_ical (GDataCalendarEvent *event, GTimeVal *timeval, struct icaltimetype *itt, ECalComponentDateTime *dt, icaltimezone *default_zone)
+gd_timeval_to_ical (GTimeVal *timeval, struct icaltimetype *itt, ECalComponentDateTime *dt, icaltimezone *default_zone)
{
/* TODO: Event's timezone? */
g_return_val_if_fail (itt != NULL, FALSE);
diff --git a/calendar/backends/google/e-cal-backend-google.c b/calendar/backends/google/e-cal-backend-google.c
index 7202ce1..6019b1b 100644
--- a/calendar/backends/google/e-cal-backend-google.c
+++ b/calendar/backends/google/e-cal-backend-google.c
@@ -1035,7 +1035,7 @@ e_cal_backend_google_create_object (ECalBackendSync *backend, EDataCal *cal, cha
cbgo = E_CAL_BACKEND_GOOGLE (backend);
g_return_val_if_fail (E_IS_CAL_BACKEND_GOOGLE(cbgo), GNOME_Evolution_Calendar_InvalidObject);
- g_return_val_if_fail (calobj != NULL && *calobj!=NULL,GNOME_Evolution_Calendar_InvalidObject);
+ g_return_val_if_fail (calobj != NULL && *calobj!=NULL, GNOME_Evolution_Calendar_InvalidObject);
priv = cbgo->priv;
if (priv->mode == CAL_MODE_LOCAL) {
/*FIXME call offline method */
@@ -1043,9 +1043,8 @@ e_cal_backend_google_create_object (ECalBackendSync *backend, EDataCal *cal, cha
}
icalcomp = icalparser_parse_string (*calobj);
- if (!icalcomp) {
+ if (!icalcomp)
return GNOME_Evolution_Calendar_InvalidObject;
- }
if (e_cal_backend_get_kind(E_CAL_BACKEND(backend)) != icalcomponent_isa (icalcomp)) {
icalcomponent_free (icalcomp);
@@ -1063,14 +1062,16 @@ e_cal_backend_google_create_object (ECalBackendSync *backend, EDataCal *cal, cha
/* Create an appointment */
GDataEntry *updated_entry;
const gchar *id;
+ GError *error = NULL;
entry = GDATA_ENTRY (e_gdata_event_from_cal_component (cbgo, comp));
- updated_entry = gdata_service_insert_entry (GDATA_SERVICE (priv->service), priv->uri, entry, NULL, NULL);
+ updated_entry = gdata_service_insert_entry (GDATA_SERVICE (priv->service), priv->uri, entry, NULL, &error);
g_object_unref (entry);
if (!updated_entry) {
- g_message ("\n Entry Insertion Failed %s \n", G_STRLOC);
- break;
+ g_message ("\n Entry Insertion Failed %s: %s \n", G_STRLOC, error->message);
+ g_error_free (error);
+ return GNOME_Evolution_Calendar_InvalidObject;
}
id = gdata_entry_get_id (updated_entry);
diff --git a/calendar/backends/google/e-cal-backend-google.h b/calendar/backends/google/e-cal-backend-google.h
index baa1b34..46ac54e 100644
--- a/calendar/backends/google/e-cal-backend-google.h
+++ b/calendar/backends/google/e-cal-backend-google.h
@@ -71,7 +71,6 @@ void e_cal_backend_google_set_cache (ECalBackendGoogle *cbgo, ECalBackendCache *
void e_cal_backend_google_set_feed (ECalBackendGoogle *cbgo, GDataFeed *feed);
void e_cal_backend_google_set_service (ECalBackendGoogle *cbgo, GDataCalendarService *service);
void e_cal_backend_google_set_uri (ECalBackendGoogle *cbgo, gchar *uri);
-void e_cal_backend_google_set_feed (ECalBackendGoogle *cbgo, GDataFeed *feed);
void e_cal_backend_google_set_mode_changed (ECalBackendGoogle *cbgo, gboolean mode_changed);
void e_cal_backend_google_set_username (ECalBackendGoogle *cbgo, gchar *username);
void e_cal_backend_google_set_password (ECalBackendGoogle *cbgo, gchar *password);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]