On Tue, 2011-11-01 at 13:43 +0100, Patrick Ohly wrote: > > But I guess this won't resolve the "new CalDAV item does not have > right > > RECURRENCE-ID" fatal error. Hmm... > > Indeed, that is a different problem. I'm working on a patch.
I got carried away a bit ;-) After writing tests for this particular problem I was convinced enough that the code works that I already merged it into the master branch. See the attached patches. -- Best Regards, Patrick Ohly The content of this message is my personal opinion only and although I am an employee of Intel, the statements I make here in no way represent Intel's position on the issue, nor am I authorized to speak on behalf of Intel on this matter.
>From bee26ca9f9464c7b83dc9729ae57f1c38aa4235f Mon Sep 17 00:00:00 2001 From: Patrick Ohly <[email protected]> Date: Wed, 2 Nov 2011 11:57:22 +0100 Subject: [PATCH 1/3] Smart Pointer: added eptr support for icalproperty and icalparameter Needed for code which creates icalproperty or icalparameter and does not immediately add it to a parent. --- src/syncevo/SmartPtr.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/src/syncevo/SmartPtr.h b/src/syncevo/SmartPtr.h index c1594b2..59baa83 100644 --- a/src/syncevo/SmartPtr.h +++ b/src/syncevo/SmartPtr.h @@ -73,6 +73,8 @@ class Unref { #endif // HAVE_GLIB #ifdef ENABLE_ICAL static void unref(icalcomponent *pointer) { icalcomponent_free(pointer); } + static void unref(icalproperty *pointer) { icalproperty_free(pointer); } + static void unref(icalparameter *pointer) { icalparameter_free(pointer); } static void unref(icaltimezone *pointer) { icaltimezone_free(pointer, 1); } #endif // ENABLE_ICAL }; -- 1.7.2.5
>From a2add05a345b80280b86c44e33ebc3542bcf3efe Mon Sep 17 00:00:00 2001 From: Patrick Ohly <[email protected]> Date: Wed, 2 Nov 2011 14:02:11 +0100 Subject: [PATCH 2/3] EDS compatibility: added icalparameter_new_clone + icalproperty_new_recurrenceid Needed for re-adding RECURRENCE-ID when missing. --- src/syncevo/eds_abi_wrapper.cpp | 2 ++ src/syncevo/eds_abi_wrapper.h | 4 ++++ 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/src/syncevo/eds_abi_wrapper.cpp b/src/syncevo/eds_abi_wrapper.cpp index 9d06130..ac1ca33 100644 --- a/src/syncevo/eds_abi_wrapper.cpp +++ b/src/syncevo/eds_abi_wrapper.cpp @@ -282,6 +282,7 @@ extern "C" void EDSAbiWrapperInit() &EDSAbiWrapperSingleton.icalparameter_get_tzid, "icalparameter_get_tzid", &EDSAbiWrapperSingleton.icalparameter_set_tzid, "icalparameter_set_tzid", &EDSAbiWrapperSingleton.icalparameter_new_from_value_string, "icalparameter_new_from_value_string", + &EDSAbiWrapperSingleton.icalparameter_new_clone, "icalparameter_new_clone", &EDSAbiWrapperSingleton.icalproperty_new_clone, "icalproperty_new_clone", &EDSAbiWrapperSingleton.icalproperty_free, "icalproperty_free", &EDSAbiWrapperSingleton.icalproperty_get_description, "icalproperty_get_description", @@ -299,6 +300,7 @@ extern "C" void EDSAbiWrapperInit() &EDSAbiWrapperSingleton.icalproperty_new_summary, "icalproperty_new_summary", &EDSAbiWrapperSingleton.icalproperty_new_uid, "icalproperty_new_uid", &EDSAbiWrapperSingleton.icalproperty_new_sequence, "icalproperty_new_sequence", + &EDSAbiWrapperSingleton.icalproperty_new_recurrenceid, "icalproperty_new_recurrenceid", &EDSAbiWrapperSingleton.icalproperty_set_value_from_string, "icalproperty_set_value_from_string", &EDSAbiWrapperSingleton.icalproperty_set_dtstamp, "icalproperty_set_dtstamp", &EDSAbiWrapperSingleton.icalproperty_set_lastmodified, "icalproperty_set_lastmodified", diff --git a/src/syncevo/eds_abi_wrapper.h b/src/syncevo/eds_abi_wrapper.h index de534e2..abb98f3 100644 --- a/src/syncevo/eds_abi_wrapper.h +++ b/src/syncevo/eds_abi_wrapper.h @@ -180,6 +180,7 @@ struct EDSAbiWrapper { const char* (*icalparameter_get_tzid) (const icalparameter* value); void (*icalparameter_set_tzid) (icalparameter* value, const char* v); icalparameter *(*icalparameter_new_from_value_string)(icalparameter_kind kind, const char *value); + icalparameter *(*icalparameter_new_clone)(icalparameter *param); icalproperty *(*icalproperty_new_clone)(icalproperty *prop); void (*icalproperty_free)(icalproperty *prop); const char* (*icalproperty_get_description) (const icalproperty* prop); @@ -197,6 +198,7 @@ struct EDSAbiWrapper { icalproperty* (*icalproperty_new_summary) (const char* v); icalproperty* (*icalproperty_new_sequence) (int v); icalproperty* (*icalproperty_new_uid) (const char* v); + icalproperty* (*icalproperty_new_recurrenceid) (icaltimetype v); void (*icalproperty_set_value_from_string) (icalproperty* prop,const char* value, const char* kind); void (*icalproperty_set_dtstamp) (icalproperty* prop, struct icaltimetype v); void (*icalproperty_set_lastmodified) (icalproperty* prop, struct icaltimetype v); @@ -347,6 +349,7 @@ extern struct EDSAbiWrapper EDSAbiWrapperSingleton; # define icalparameter_get_tzid EDSAbiWrapperSingleton.icalparameter_get_tzid # define icalparameter_set_tzid EDSAbiWrapperSingleton.icalparameter_set_tzid # define icalparameter_new_from_value_string EDSAbiWrapperSingleton.icalparameter_new_from_value_string +# define icalparameter_new_clone EDSAbiWrapperSingleton.icalparameter_new_clone # define icalproperty_new_clone EDSAbiWrapperSingleton.icalproperty_new_clone # define icalproperty_free EDSAbiWrapperSingleton.icalproperty_free # define icalproperty_get_description EDSAbiWrapperSingleton.icalproperty_get_description @@ -364,6 +367,7 @@ extern struct EDSAbiWrapper EDSAbiWrapperSingleton; # define icalproperty_new_summary EDSAbiWrapperSingleton.icalproperty_new_summary # define icalproperty_new_uid EDSAbiWrapperSingleton.icalproperty_new_uid # define icalproperty_new_sequence EDSAbiWrapperSingleton.icalproperty_new_sequence +# define icalproperty_new_recurrenceid EDSAbiWrapperSingleton.icalproperty_new_recurrenceid # define icalproperty_set_value_from_string EDSAbiWrapperSingleton.icalproperty_set_value_from_string # define icalproperty_set_dtstamp EDSAbiWrapperSingleton.icalproperty_set_dtstamp # define icalproperty_set_lastmodified EDSAbiWrapperSingleton.icalproperty_set_lastmodified -- 1.7.2.5
>From 03d3c720bab43323addb1c7c70ad033b8204833e Mon Sep 17 00:00:00 2001 From: Patrick Ohly <[email protected]> Date: Wed, 2 Nov 2011 12:02:04 +0100 Subject: [PATCH 3/3] CalDAV: add RECURRENCE-ID in update When storing an updated detached recurrence, the VEVENT was expected to contain a RECURRENCE-ID. This might not be the case when the peer in a local sync (typically the local storage) was unable to store that property. Support such a local storage by re-adding the RECURRENCE-ID based on the available information: - RECURRENCE-ID value from sub ID - TZID from parent event's DTSTART (if parent exists) or current event's DTSTART (otherwise) Tests for different scenarios (all-day event with date-only RECURRENCE-ID, with TZID, without TZID) will be committed separately. --- src/backends/webdav/CalDAVSource.cpp | 49 ++++++++++++++++++++++++++++++++- 1 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/backends/webdav/CalDAVSource.cpp b/src/backends/webdav/CalDAVSource.cpp index cfb25c5..aab2a82 100644 --- a/src/backends/webdav/CalDAVSource.cpp +++ b/src/backends/webdav/CalDAVSource.cpp @@ -498,10 +498,55 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid } } } else { - if (subid != knownSubID) { - SE_THROW("new CalDAV item does not have right RECURRENCE-ID"); + if (!subid.empty() && subid != knownSubID) { + SE_THROW(StringPrintf("new CalDAV item does not have right RECURRENCE-ID: item %s != expected %s", + subid.c_str(), knownSubID.c_str())); } Event &event = loadItem(davLUID); + + if (subid.empty() && subid != knownSubID) { + // fix incomplete iCalendar 2.0 item: should have had a RECURRENCE-ID + icalcomponent *newcomp = + icalcomponent_get_first_component(newEvent->m_calendar, ICAL_VEVENT_COMPONENT); + icalproperty *prop = icalcomponent_get_first_property(newcomp, ICAL_RECURRENCEID_PROPERTY); + if (prop) { + icalcomponent_remove_property(newcomp, prop); + icalproperty_free(prop); + } + + // reconstruct RECURRENCE-ID with known value and TZID from start time of + // the parent event or (if not found) the current event + eptr<icalproperty> rid(icalproperty_new_recurrenceid(icaltime_from_string(knownSubID.c_str())), + "new rid"); + icalproperty *dtstart = NULL; + icalcomponent *comp; + // look for parent first + for (comp = icalcomponent_get_first_component(event.m_calendar, ICAL_VEVENT_COMPONENT); + comp && !dtstart; + comp = icalcomponent_get_next_component(event.m_calendar, ICAL_VEVENT_COMPONENT)) { + if (!icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY)) { + dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY); + } + } + // fall back to current event + if (!dtstart) { + dtstart = icalcomponent_get_first_property(newcomp, ICAL_DTSTART_PROPERTY); + } + // ignore missing TZID + if (dtstart) { + icalparameter *tzid = icalproperty_get_first_parameter(dtstart, ICAL_TZID_PARAMETER); + if (tzid) { + icalproperty_set_parameter(rid, icalparameter_new_clone(tzid)); + } + } + + // finally add RECURRENCE-ID and fix newEvent's meta information + icalcomponent_add_property(newcomp, rid.release()); + subid = knownSubID; + newEvent->m_subids.erase(""); + newEvent->m_subids.insert(subid); + } + // no changes expected yet, copy previous attributes subres.m_mainid = davLUID; subres.m_uid = event.m_UID; -- 1.7.2.5
_______________________________________________ SyncEvolution mailing list [email protected] http://lists.syncevolution.org/listinfo/syncevolution
