[Vobject] Recurring Events Examples
Jeffrey Harris
jeffrey at osafoundation.org
Sun Sep 20 01:23:00 CDT 2009
Hi Keyton,
> Do you have any example Python code showing the creation of recurring
> events? Do most developers create copies of the other event and then
> sort of keep up with them, sending, say, the next ten? Or can I send a
> recurring event to Outlook etc via a single iCal entry?
There are a few calendar clients that create a limited subset of a
recurring series of events, but that's not common these days.
The sections on recurrence in RFC2445 are long and complicated, but the
basic idea is reasonably simple. You can do this:
>>> import vobject
>>> import datetime
>>> cal = vobject.iCalendar()
>>> cal.add('vevent').add('dtstart')
<DTSTART{}>
>>> cal.vevent.dtstart.value = datetime.datetime(2009,9,19,10)
>>> cal.vevent.add('rrule').value = "FREQ=WEEKLY"
>>> print cal.serialize()
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//PYVOBJECT//NONSGML Version 1//EN
BEGIN:VEVENT
UID:20090920T060033Z-91602 at jeffrey.local
DTSTART:20090919T100000
RRULE:FREQ=WEEKLY
END:VEVENT
END:VCALENDAR
This is an indefinitely recurring event, recurring weekly on Saturday
mornings (to be legal, it should have a timezone, but almost no one
enforces that rule). vobject maps recurrence information in VEVENTs
like this to a special object that helps with recurrence, a
dateutil.rrule.rruleset.
If you want to see the first three occurrences of the rule (be careful
not to expand the entire series, it's indefinitely recurring into the
future), do this:
>>> cal.vevent.rruleset[0:3]
[datetime.datetime(2009, 9, 19, 10, 0),
datetime.datetime(2009, 9, 26, 10, 0),
datetime.datetime(2009, 10, 3, 10, 0)]
If you want to add a Sunday to this every-Saturday rule, do:
>>> cal.vevent.add('rdate').value = [datetime.datetime(2009,9,20,10)]
You can also exclude particular dates:
>>> cal.vevent.add('exdate').value = [datetime.datetime(2009,9,26,10)]
Note that RDATE and EXDATE can each take multiple dates, so when you set
value it needs to be a list of dates or datetimes, not an individual
date or datetime. Now the first three occurrences look like this:
>>> cal.vevent.rruleset[0:3]
[datetime.datetime(2009, 9, 19, 10, 0),
datetime.datetime(2009, 9, 20, 10, 0),
datetime.datetime(2009, 10, 3, 10, 0)]
--------------
If you want to change a specific occurrence (or a particular occurrence
and all later occurrences), you do that by creating a *new* VEVENT, with
an identical UID to the master VEVENT (the master has the RRULE set).
In this new VEVENT set RECURRENCE-ID to match the DTSTART for the
occurrence you're changing.
vobject doesn't help you with multiple VEVENTs, or help you parse
iCalendar with several VEVENTs representing the same recurring series.
I've thought about adding convenience functions to do this, but I've
never gotten around to it.
Hope that helps,
Jeffrey
More information about the VObject
mailing list