Re: [Evolution-hackers] cleaning up the timezone handling mess



On Fri, 2008-04-11 at 00:55 -0600, P Chenthill wrote:
[Exchange calendar backend patch]
> In cases of exchange the old VTIMEZONE and the new VTIMEZONE would have
> the same tzid, only the rules would be different. All events old and new
> will just use the latest timezone from the backend since they would have
> the same tzid in their start/end dates.

And that would be wrong for the old events which are truly in the past.
Consider the 2006 example that I sent: when viewing the year 2006 in the
calendar, the system timezone definition is used and thus Evolution
correctly uses the summer saving rules from 2006. Using the updated
VTIMEZONE for events in that year would lead to a one hour shift during
those weeks where old and new rules differ.

It's arguably the lesser evil for recurring events because the current,
still relevant recurrences would be displayed correctly, so there is
some value in it. But for old events which are archived for reference
purposes it would be just wrong. What I am suggesting would solve this
problem by preserving both the old and the new VTIMEZONE.

For recurring events the mapping to the more complex system timezone
definitions helps.

[VTIMEZONE and VEVENT are added separately]
> I don't think it works like that. iirc the whole VCALENDAR (used as
> top-level component in itip-formatter) which has events and timezone
> gets passed to the backend, the backend adds the timezone and events to
> the cache, notifies the UI.

After looking at the Evolution source code I already came to the same
conclusion. However, clients like SyncEvolution do add VTIMEZONE and
VEVENT separately. That is necessary because the UID of each new VEVENT
is required immediately, which is not possible (or at least very
awkward) via ecal_receive_objects().

This makes the new function a bit more complex, but I still think it is
doable to come up with a solution which can be used by backends and
clients. Attached is a proposal. In SyncEvolution I would lookup
existing VTIMEZONE in the calendar via the e_cal_tzlookup_ecal() utility
function, which then uses e_cal_get_timezone(). 
                              
I checked the code of the file backend. The e_cal_check_timezone() call
would fit right before the icalcomponent_merge_component() call and
would use the other tzlookup function which checks against local
VTIMEZONE components.

All the other backends would have to be adapted in a similar way. I
considered modifying the general e_cal_backend_file_receive_objects(),
but decided against it because individual backends might have better
ways of dealing with the problem. I also don't want to touch code which
I cannot test.

I will be out of town for three days. If there are no objections, then
I'll try to get working code together when I come back, hopefully before
I go on a business trip for two weeks the week after. Time, anyone got
some time?

-- 
Bye, Patrick Ohly
--  
Patrick Ohly gmx de
http://www.estamos.de/
/**
 * This function cleans up VEVENT, VJOURNAL, VTODO and VTIMEZONE
 * items which are to be imported into Evolution.
 *
 * It deals with VTIMEZONE conflicts which occur when the calendar
 * already contains an old VTIMEZONE definition with the same TZID,
 * but different summer saving rules.  Replacing the VTIMEZONE
 * potentially breaks displaying of old events, whereas not replacing
 * it breaks the new events (the behavior in Evolution <= 2.22.1).
 *
 * The way this problem is resolved is by renaming the new VTIMEZONE
 * definition until the TZID is unique. A running count is appended to
 * the TZID. All items referencing the renamed TZID are adapted
 * accordingly.
 *
 * Using VTIMEZONE definitions is problematic because they cannot be
 * updated properly when timezone definitions change and are
 * incomplete (for compatibility reason only one set of rules for
 * summer saving changes can be included, even if different rules
 * apply to different years). This function also looks for matches
 * of the used TZIDs against system timezones and replaces such TZIDs
 * with the corresponding system timezone. This works for TZIDs
 * following the Olson naming scheme by comparing the <country>/<city>
 * part and for Outlook TZIDs (via a hard-coded lookup table).
 *
 * @param comp      either a VCALENDAR containing a list of
 *                  VTIMEZONE/VEVENT/VTODO/VJOURNAL items (in
 *                  arbitrary order) or such a list directly;
 *                  these are the items which are modified
 * @param tzlookup  a callback function which is called to retrieve
 *                  a calendar's VTIMEZONE definition; the returned
 *                  string is freed by e_cal_check_timezones();
 *                  NULL indicates that no such timezone exists
 *                  or an error occurred
 * @param custom    an arbitrary pointer which is passed through to
 *                  the tzlookup function
 * @retval error    an error description in case of a failure
 * @return TRUE if successful, FALSE otherwise.
 */
gboolean e_cal_check_timezones(icalcomponent *comp,
                               char *(*tzlookup)(const char *tzid,
                                                 const void *custom,
                                                 GError **error),
                               const void *custom,
                               GError **error);

/**
 * An implementation of the tzlookup callback which clients
 * can use. Calls e_cal_get_timezone().
 *
 * @param custom     must be a valid ECal pointer
 */
char *e_cal_tzlookup_ecal(const char *tzid,
                          const void *custom,
                          GError **error);

/**
 * An implementation of the tzlookup callback which backends
 * like the file backend can use. Searches for the timezone
 * in the component list.
 *
 * @param custom     must be a icalcomponent pointer which contains
 *                   either a VCALENDAR with VTIMEZONEs or VTIMEZONES
 *                   directly
 */
char *e_cal_tzlookup_icomp(const char *tzid,
                           const void *custom,
                           GError **error);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]