Calendar Recurrence
This document will track open issues and solutions surrounding the implementation of recurring calendar items.
Libraries
Recurrence logic
How do we handle the logic of recurring events as expressed in vCalendar?
JeffreyHarris? has suggested dateutil.rrule, and everyone seems fine with that. Details are at the
DateUtil homepage.
Date/Time Representation
Right now we use mx.DateTime.
JeffreyHarris? has suggested we switch to ICU. This seems like a good idea in general, but we currently are bound up in mx.DateTime. We need to evaluate what ICU will give us over mx.DateTime. Should we switch over entirely, or is some sort of hybrid model more appropriate? Brian Kirsh says ICU is essential for a reasonable i18n story. It sounds like ICU might not be ready for a while though.
Recurrence model
The basic problem we have is that the Repository represents "concrete" items. iCalendar recurrence is represented as single events with rules about how the event recurs. This wouldn't be a problem in a standard calendar application since the application could display the "child" events to the user any way they want. Chandler allows many different "views" into the repository though. While the Calendar View can easily represent these recurrences as actual events in the UI, there are other views that the calendar has no control over. (such as the Summary Table and sharing) These other views may need the data to be transformed in some useful way to present these multiple "child" events to the user.
Another piece of this is that recurrence is more or less unbounded - there isn't necessarily an obvious end time for a repeating event. The repository doesn't exactly have infinite storage, or representation for an infinite set of items. We probably don't want to deal with them even if it could to avoid infinite loops by other consumers of the repository.
Working under that assumption, one solution wouild be to create a "recurrence event" Kind, and link "concrete" calendar events back to that kind. That kind isn't necessarily a
CalendarEvent? or anything, but a distinctly new type that represents the recurrence (perhaps just as a vCalendar recurrence string?) and links to the dependent
CalendarEvents?. Lisa mentions the idea of a "master" event - this is something like that. She also suggested keeping track of exceptions on a case-by-case basis. This could included making notes in an individual event, or stamping a specific event. I think of the exceptions idea as sort of a copy-on-write model. As soon as the user makes a specific type of change to a visual event, it gets thrown into the repository as an actual event.
Having these concrete events would allow these events to be visible in other views besides the Calendar View, such as the Summary View, or part of some query. If in fact we want to generate some concrete events, we need to understand how and when do we generate the concrete events. We also need to figure out how the calendar code is aware of both concrete and not-yet-generated events.
Some random thoughts on concrete events
- generating n events, such as 10 events, is probably not quite what the user is expecting because I think the user thinks in date ranges, not event counts. i.e. if we're generating 10 events at a time and a user has something recurring on M/W/F, they're going to see 3 weeks of Mon/Wed/Fri events generated, plus a Monday. Perhaps what we really want is to keep generating events "n weeks in advance" or something? The "n weeks in advance" limit could be a system wide default, but could also be stored on the recurrence object I described above..
- we'll need a way to keep generating events as time moves forward. I think a wakeupcaller that fires at startup and then every hour/day/etc could ensure that the minimum number/range of concrete dates has been generated in advance. That shouldn't be too hard
- ideally the user should never have to think about the whole notion of concrete and not-concrete events.. so we need to do our best to make it appear like the concrete events really do exist.
On dynamically generated views of calendar data
These are views that we have control over because they are calendar specific, and we'll have control over the iteration of calendar events.
- free/busy stuff could automatically work around recurrence events, even if the concrete events haven't been generated yet. i.e. if I'm looking ahead 2 months for free time in my calendar, we don't have to generate the concrete events to find times that don't conflict with recurring times (whew, that's a mouthful!)
- The calendar view itself could act as though some of the concrete dates have actually been generated... i.e. if I'm looking at a week 2 months from now, the calendar view could display events even though they haven't actually been generated yet.
- For performance we could have a cache as Lisa suggests. This has more value when we're just displaying the current day/week/month in the Calendar View, as the cached concrete items would be an arbitrary set of items based on the user's interaction with the calendar. We don't know how heavy a hit this really is in our case, so the cache might be something good for another iteration of the calendar.
- Lisa mentions exceptions, and Bear mentioned the idea of annotating specific events in the future. Whether or not we automatically generate concrete events, we'd need to guarantee a concrete event exists for a certain events. This would include annotation as well as stamping. Are there other actions that would require exceptions? If that's the case, how do we hook into the stamping mechanism? How to do we handle import/export of these items?
Import/export issues
- Obviously CalDAV is a big issue here.. as I understand it, CalDAV stores repeating events as a single object.. so if anything we have to be careful that we don't try to send our concrete events off to CalDAV
- Similar to CalDAV issues, importing/exporting iCalendar stuff would have to be aware of the differences between recurrence events, and concrete events.