0
# Event Operations
1
2
Comprehensive event management functionality including creation, modification, deletion, recurring event handling, and attendee management with full iCalendar support and CalDAV scheduling extensions.
3
4
## Capabilities
5
6
### Event Class
7
8
Represents CalDAV events (VEVENT components) with specialized methods for event-specific operations and date/time handling.
9
10
```python { .api }
11
class Event(CalendarObjectResource):
12
"""
13
Event class inherits all functionality from CalendarObjectResource.
14
15
Additional methods available for Event objects:
16
"""
17
18
# Event-specific alias
19
set_dtend = CalendarObjectResource.set_end # Alias for setting event end time
20
21
# Inherited methods from CalendarObjectResource for date/time handling:
22
def get_duration(self):
23
"""Get event duration (inherited from CalendarObjectResource)."""
24
25
def set_duration(self, duration, movable_attr="DTSTART"):
26
"""Set event duration (inherited from CalendarObjectResource)."""
27
28
def set_end(self, end, move_dtstart=False):
29
"""Set event end time (inherited from CalendarObjectResource)."""
30
31
# Access to event properties through icalendar_component property:
32
# event.icalendar_component['DTSTART'] - start time
33
# event.icalendar_component['DTEND'] - end time
34
# event.icalendar_component['SUMMARY'] - event title
35
# event.icalendar_component['DESCRIPTION'] - event description
36
```
37
38
**Usage Examples:**
39
40
```python
41
import caldav
42
from datetime import datetime, timedelta
43
44
# Get an existing event
45
calendar = principal.calendars()[0]
46
events = calendar.events()
47
if events:
48
event = events[0]
49
50
# Get event timing information through icalendar component
51
component = event.icalendar_component
52
start_time = component.get('DTSTART')
53
end_time = component.get('DTEND')
54
duration = event.get_duration() # Available method
55
56
print(f"Event: {component.get('SUMMARY', 'No title')}")
57
print(f"Start: {start_time}")
58
print(f"End: {end_time}")
59
print(f"Duration: {duration}")
60
61
# Modify event timing
62
new_start = datetime(2025, 9, 20, 15, 0) # 3 PM
63
component['DTSTART'] = new_start
64
event.set_duration(timedelta(hours=2)) # 2 hour meeting
65
66
# Save changes
67
event.save()
68
print("Event updated successfully")
69
```
70
71
### Event Creation
72
73
Create new events with comprehensive iCalendar support including all standard properties and extensions.
74
75
```python { .api }
76
# Event creation through calendar.save_event() - see calendar-management.md
77
# Additional event-specific creation patterns:
78
79
def create_simple_event(summary, start, end, description=None, location=None):
80
"""
81
Helper function to create simple event iCalendar data.
82
83
Parameters:
84
- summary: str, event title
85
- start: datetime, event start time
86
- end: datetime, event end time
87
- description: str, optional event description
88
- location: str, optional event location
89
90
Returns:
91
str: iCalendar data for the event
92
"""
93
```
94
95
**Usage Examples:**
96
97
```python
98
from datetime import datetime, timezone
99
import uuid
100
101
# Create a simple event manually
102
def create_meeting_event(title, start_time, duration_hours, description=None, location=None):
103
end_time = start_time + timedelta(hours=duration_hours)
104
event_uid = f"{uuid.uuid4()}@example.com"
105
106
ical_data = f"""BEGIN:VCALENDAR
107
VERSION:2.0
108
PRODID:-//My Calendar App//My Calendar App//EN
109
BEGIN:VEVENT
110
UID:{event_uid}
111
DTSTART:{start_time.strftime('%Y%m%dT%H%M%SZ')}
112
DTEND:{end_time.strftime('%Y%m%dT%H%M%SZ')}
113
SUMMARY:{title}
114
"""
115
116
if description:
117
ical_data += f"DESCRIPTION:{description}\n"
118
if location:
119
ical_data += f"LOCATION:{location}\n"
120
121
ical_data += """DTSTAMP:{}Z
122
STATUS:CONFIRMED
123
END:VEVENT
124
END:VCALENDAR""".format(datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S'))
125
126
return ical_data
127
128
# Create and save an event
129
meeting_start = datetime(2025, 9, 25, 10, 0, tzinfo=timezone.utc)
130
meeting_ical = create_meeting_event(
131
title="Project Review Meeting",
132
start_time=meeting_start,
133
duration_hours=1.5,
134
description="Review project progress and discuss next steps",
135
location="Conference Room B"
136
)
137
138
event = calendar.save_event(meeting_ical)
139
print(f"Created event: {event.id}")
140
141
# Create all-day event
142
allday_ical = """BEGIN:VCALENDAR
143
VERSION:2.0
144
PRODID:-//My App//My App//EN
145
BEGIN:VEVENT
146
UID:holiday-001@example.com
147
DTSTART;VALUE=DATE:20250925
148
DTEND;VALUE=DATE:20250926
149
SUMMARY:Team Building Day
150
DESCRIPTION:Annual team building activities
151
END:VEVENT
152
END:VCALENDAR"""
153
154
allday_event = calendar.save_event(allday_ical)
155
```
156
157
### Recurring Events
158
159
Handle recurring events with support for RRULE patterns, exception dates, and recurrence expansion.
160
161
```python { .api }
162
def expand(self, start, end):
163
"""
164
Expand recurring event within date range.
165
166
Parameters:
167
- start: datetime, start of expansion range
168
- end: datetime, end of expansion range
169
170
Returns:
171
list[Event]: List of Event instances for each occurrence
172
"""
173
```
174
175
**Usage Examples:**
176
177
```python
178
# Create a recurring event
179
recurring_ical = """BEGIN:VCALENDAR
180
VERSION:2.0
181
PRODID:-//My App//My App//EN
182
BEGIN:VEVENT
183
UID:weekly-standup@example.com
184
DTSTART:20250915T090000Z
185
DTEND:20250915T093000Z
186
SUMMARY:Weekly Team Standup
187
DESCRIPTION:Weekly team synchronization meeting
188
RRULE:FREQ=WEEKLY;BYDAY=MO;COUNT=10
189
END:VEVENT
190
END:VCALENDAR"""
191
192
recurring_event = calendar.save_event(recurring_ical)
193
194
# Expand recurring event for next month
195
from datetime import datetime, timedelta
196
start_date = datetime.now()
197
end_date = start_date + timedelta(days=30)
198
199
occurrences = recurring_event.expand(start_date, end_date)
200
print(f"Found {len(occurrences)} occurrences in the next month")
201
202
for occurrence in occurrences:
203
start_time = occurrence.get_dtstart()
204
print(f"Standup on: {start_time}")
205
206
# Create recurring event with exceptions
207
recurring_with_exception = """BEGIN:VCALENDAR
208
VERSION:2.0
209
PRODID:-//My App//My App//EN
210
BEGIN:VEVENT
211
UID:daily-checkin@example.com
212
DTSTART:20251001T150000Z
213
DTEND:20251001T151500Z
214
SUMMARY:Daily Check-in
215
RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;COUNT=20
216
EXDATE:20251015T150000Z,20251030T150000Z
217
END:VEVENT
218
END:VCALENDAR"""
219
220
daily_event = calendar.save_event(recurring_with_exception)
221
```
222
223
### Attendee Management
224
225
Manage event attendees with support for CalDAV scheduling extensions including RSVP tracking and role management.
226
227
```python { .api }
228
def add_attendee(self, attendee, rsvp=None, role=None, partstat=None, cutype=None):
229
"""
230
Add attendee to event.
231
232
Parameters:
233
- attendee: str, attendee email address or calendar user address
234
- rsvp: bool, whether RSVP is requested
235
- role: str, attendee role ('REQ-PARTICIPANT', 'OPT-PARTICIPANT', 'CHAIR')
236
- partstat: str, participation status ('NEEDS-ACTION', 'ACCEPTED', 'DECLINED', 'TENTATIVE')
237
- cutype: str, calendar user type ('INDIVIDUAL', 'GROUP', 'RESOURCE', 'ROOM')
238
"""
239
240
def remove_attendee(self, attendee):
241
"""
242
Remove attendee from event.
243
244
Parameters:
245
- attendee: str, attendee email address to remove
246
"""
247
248
def add_organizer(self):
249
"""Add organizer property to event based on current user."""
250
251
def remove_organizer(self):
252
"""Remove organizer property from event."""
253
```
254
255
**Usage Examples:**
256
257
```python
258
# Get an event and manage attendees
259
event = calendar.event_by_uid("meeting-001@example.com")
260
if event:
261
# Add required participant
262
event.add_attendee(
263
attendee="alice@example.com",
264
rsvp=True,
265
role="REQ-PARTICIPANT",
266
partstat="NEEDS-ACTION"
267
)
268
269
# Add optional participant
270
event.add_attendee(
271
attendee="bob@example.com",
272
rsvp=True,
273
role="OPT-PARTICIPANT",
274
partstat="NEEDS-ACTION"
275
)
276
277
# Add meeting room resource
278
event.add_attendee(
279
attendee="room-a@example.com",
280
cutype="ROOM",
281
role="NON-PARTICIPANT"
282
)
283
284
# Set organizer
285
event.add_organizer()
286
287
# Save the updated event
288
event.save()
289
print("Attendees added to event")
290
291
# Later, remove an attendee
292
event.remove_attendee("bob@example.com")
293
event.save()
294
```
295
296
### Event Modification
297
298
Modify existing events with proper change tracking and conflict resolution.
299
300
```python { .api }
301
# Inherited from CalendarObjectResource
302
def save(self):
303
"""Save event changes to the server."""
304
305
def delete(self):
306
"""Delete event from the server."""
307
308
def copy(self, new_parent):
309
"""Copy event to different calendar."""
310
311
def move(self, new_parent):
312
"""Move event to different calendar."""
313
314
def change_uid(self, new_uid=None):
315
"""Change event UID (generates new UID if not provided)."""
316
317
def load(self):
318
"""Load/reload event data from the server."""
319
320
def get_relatives(self):
321
"""
322
Get related calendar objects.
323
324
Returns:
325
list[CalendarObjectResource]: Related objects
326
"""
327
328
def add_relation(self, related_object, reltype="PARENT"):
329
"""
330
Add relation to another calendar object.
331
332
Parameters:
333
- related_object: CalendarObjectResource, target object
334
- reltype: str, relation type ('PARENT', 'CHILD', 'SIBLING')
335
"""
336
337
def split_expanded(self):
338
"""
339
Split expanded recurrence into individual objects.
340
341
Returns:
342
list[Event]: Individual event instances
343
"""
344
```
345
346
**Usage Examples:**
347
348
```python
349
# Modify an existing event
350
event = calendar.event_by_uid("meeting-001@example.com")
351
if event:
352
# Access the iCalendar component for detailed modifications
353
component = event.icalendar_component
354
355
# Update basic properties
356
component['SUMMARY'] = 'Updated Meeting Title'
357
component['DESCRIPTION'] = 'Updated meeting description with new agenda'
358
component['LOCATION'] = 'New Conference Room'
359
360
# Update timing
361
event.set_dtstart(datetime(2025, 9, 25, 14, 30, tzinfo=timezone.utc))
362
event.set_duration(timedelta(hours=2))
363
364
# Add alarm/reminder
365
from icalendar import Alarm
366
alarm = Alarm()
367
alarm.add('TRIGGER', timedelta(minutes=-15)) # 15 minutes before
368
alarm.add('ACTION', 'DISPLAY')
369
alarm.add('DESCRIPTION', 'Meeting reminder')
370
component.add_component(alarm)
371
372
# Save changes
373
event.save()
374
print("Event updated successfully")
375
376
# Copy event to another calendar
377
other_calendar = principal.calendars()[1]
378
copied_event = event.copy(other_calendar)
379
print(f"Copied event to {other_calendar.name}: {copied_event.id}")
380
381
# Move event between calendars
382
moved_event = event.move(other_calendar)
383
print(f"Moved event to {other_calendar.name}")
384
```
385
386
### Event Queries and Filtering
387
388
Advanced event querying with date ranges, text search, and property filtering.
389
390
```python { .api }
391
# These methods are available on Calendar objects for event-specific searches
392
# See calendar-management.md for full details
393
394
# Common event search patterns:
395
def find_events_by_summary(calendar, summary_text):
396
"""Find events matching summary text."""
397
return calendar.search(
398
comp_filter="VEVENT",
399
text_match=summary_text
400
)
401
402
def find_events_by_location(calendar, location):
403
"""Find events at specific location."""
404
return calendar.search(
405
comp_filter="VEVENT",
406
prop_filter={"LOCATION": location}
407
)
408
409
def find_upcoming_events(calendar, days=7):
410
"""Find events in the next N days."""
411
from datetime import datetime, timedelta
412
start = datetime.now()
413
end = start + timedelta(days=days)
414
return calendar.date_search(start=start, end=end, compfilter="VEVENT")
415
```
416
417
## Event Properties
418
419
```python { .api }
420
# Common event properties that can be accessed via icalendar_component
421
EVENT_PROPERTIES = {
422
"SUMMARY": "str", # Event title/summary
423
"DESCRIPTION": "str", # Event description
424
"DTSTART": "datetime", # Start date/time
425
"DTEND": "datetime", # End date/time
426
"DURATION": "timedelta", # Duration (alternative to DTEND)
427
"LOCATION": "str", # Event location
428
"STATUS": "str", # CONFIRMED, TENTATIVE, CANCELLED
429
"PRIORITY": "int", # Priority (0-9, 0=undefined, 1=highest, 9=lowest)
430
"CLASS": "str", # PUBLIC, PRIVATE, CONFIDENTIAL
431
"CATEGORIES": "list[str]", # Event categories/tags
432
"ORGANIZER": "vCalAddress", # Event organizer
433
"ATTENDEE": "list[vCalAddress]", # Event attendees
434
"RRULE": "str", # Recurrence rule
435
"EXDATE": "list[datetime]", # Exception dates
436
"RDATE": "list[datetime]", # Additional recurrence dates
437
}
438
439
# Event status values
440
EVENT_STATUS = {
441
"CONFIRMED": "Confirmed event",
442
"TENTATIVE": "Tentative/provisional event",
443
"CANCELLED": "Cancelled event"
444
}
445
446
# Event classification values
447
EVENT_CLASS = {
448
"PUBLIC": "Public event (default)",
449
"PRIVATE": "Private to organizer",
450
"CONFIDENTIAL": "Confidential access required"
451
}
452
```