or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

calendar-management.mdclient-auth.mdevent-operations.mdindex.mdjournal-freebusy.mdprincipal-calendar.mdtask-management.md

calendar-management.mddocs/

0

# Calendar Management

1

2

Comprehensive calendar operations including object retrieval, search functionality, synchronization, and calendar object management with full support for events, todos, and journals.

3

4

## Capabilities

5

6

### Calendar Object Retrieval

7

8

Retrieve different types of calendar objects (events, todos, journals, free/busy) from calendar collections with filtering and type-specific access methods.

9

10

```python { .api }

11

class Calendar(DAVObject):

12

def events(self):

13

"""

14

Get all events in this calendar.

15

16

Returns:

17

list[Event]: List of Event objects

18

"""

19

20

def todos(self):

21

"""

22

Get all todos/tasks in this calendar.

23

24

Returns:

25

list[Todo]: List of Todo objects

26

"""

27

28

def journals(self):

29

"""

30

Get all journal entries in this calendar.

31

32

Returns:

33

list[Journal]: List of Journal objects

34

"""

35

36

def freebusy(self):

37

"""

38

Get all free/busy objects in this calendar.

39

40

Returns:

41

list[FreeBusy]: List of FreeBusy objects

42

"""

43

44

def objects(self, load_objects=False, sort=None):

45

"""

46

Get all calendar objects of all types.

47

48

Parameters:

49

- load_objects: bool, whether to load full object data

50

- sort: str, sort order for objects

51

52

Returns:

53

list[CalendarObjectResource]: All objects in calendar

54

"""

55

56

def objects_by_sync_token(self, sync_token=None, load_objects=True):

57

"""

58

Retrieve objects using WebDAV synchronization for efficient updates.

59

60

Parameters:

61

- sync_token: str, synchronization token from previous sync

62

- load_objects: bool, whether to load full object data (default True)

63

64

Returns:

65

tuple: (objects, new_sync_token) where objects is list of

66

CalendarObjectResource and new_sync_token is str

67

"""

68

```

69

70

**Usage Examples:**

71

72

```python

73

import caldav

74

75

# Get calendar from principal

76

client = caldav.DAVClient(url="...", username="...", password="...")

77

principal = client.principal()

78

calendar = principal.calendars()[0]

79

80

# Get all events

81

all_events = calendar.events()

82

print(f"Found {len(all_events)} events")

83

84

# Get all todos

85

all_todos = calendar.todos()

86

for todo in all_todos:

87

summary = todo.icalendar_component.get('SUMMARY', 'No title')

88

print(f"Todo: {summary}")

89

90

# Note: No general objects() method available

91

# Use specific methods: calendar.events(), calendar.todos(), calendar.journals()

92

93

# Efficient synchronization

94

sync_token = None

95

while True:

96

objects, new_sync_token = calendar.objects_by_sync_token(

97

sync_token=sync_token,

98

load_objects=True

99

)

100

101

if objects:

102

print(f"Found {len(objects)} changed objects")

103

# Process changed objects

104

for obj in objects:

105

print(f"Updated: {obj.id}")

106

107

sync_token = new_sync_token

108

break # In real usage, would check for changes periodically

109

```

110

111

### Calendar Object Creation

112

113

Create and save new calendar objects with support for different object types and creation options.

114

115

```python { .api }

116

def save_event(self, ical, no_overwrite=False, no_create=False):

117

"""

118

Save an event to this calendar.

119

120

Parameters:

121

- ical: str, iCalendar data (VCALENDAR format)

122

- no_overwrite: bool, prevent overwriting existing events (default False)

123

- no_create: bool, prevent creating new events (default False)

124

125

Returns:

126

Event: Saved Event object

127

128

Raises:

129

ConsistencyError: If no_overwrite=True and event exists

130

NotFoundError: If no_create=True and event doesn't exist

131

"""

132

133

def save_todo(self, ical, no_overwrite=False, no_create=False):

134

"""

135

Save a todo/task to this calendar.

136

137

Parameters:

138

- ical: str, iCalendar data (VCALENDAR format)

139

- no_overwrite: bool, prevent overwriting existing todos

140

- no_create: bool, prevent creating new todos

141

142

Returns:

143

Todo: Saved Todo object

144

"""

145

146

def save_journal(self, ical, no_overwrite=False, no_create=False):

147

"""

148

Save a journal entry to this calendar.

149

150

Parameters:

151

- ical: str, iCalendar data (VCALENDAR format)

152

- no_overwrite: bool, prevent overwriting existing journals

153

- no_create: bool, prevent creating new journals

154

155

Returns:

156

Journal: Saved Journal object

157

"""

158

159

# Generic object creation

160

def save_object(self, objclass, ical=None, no_overwrite=False, no_create=False, **ical_data):

161

"""

162

Save calendar object of any type.

163

164

Parameters:

165

- objclass: class, calendar object class (Event, Todo, Journal, FreeBusy)

166

- ical: str, iCalendar data (alternative to **ical_data)

167

- no_overwrite: bool, prevent overwriting existing objects

168

- no_create: bool, prevent creating new objects

169

- **ical_data: additional iCalendar properties

170

171

Returns:

172

CalendarObjectResource: Saved object

173

"""

174

175

def save_with_invites(self, ical, attendees, **attendeeoptions):

176

"""

177

Save calendar object and send invitations to attendees.

178

179

Parameters:

180

- ical: str, iCalendar data

181

- attendees: list[str], attendee email addresses

182

- **attendeeoptions: additional attendee options

183

184

Returns:

185

CalendarObjectResource: Saved object with invitations sent

186

"""

187

188

# Convenient aliases

189

def add_event(self, ical, no_overwrite=False, no_create=False):

190

"""Alias for save_event."""

191

192

def add_todo(self, ical, no_overwrite=False, no_create=False):

193

"""Alias for save_todo."""

194

195

def add_journal(self, ical, no_overwrite=False, no_create=False):

196

"""Alias for save_journal."""

197

```

198

199

**Usage Examples:**

200

201

```python

202

# Create a new event

203

event_ical = """BEGIN:VCALENDAR

204

VERSION:2.0

205

PRODID:-//My App//My App//EN

206

BEGIN:VEVENT

207

UID:meeting-001@example.com

208

DTSTART:20250915T140000Z

209

DTEND:20250915T150000Z

210

SUMMARY:Team Meeting

211

DESCRIPTION:Weekly team sync meeting

212

LOCATION:Conference Room A

213

END:VEVENT

214

END:VCALENDAR"""

215

216

# Save the event

217

event = calendar.save_event(event_ical)

218

print(f"Created event with UID: {event.id}")

219

220

# Create a todo

221

todo_ical = """BEGIN:VCALENDAR

222

VERSION:2.0

223

PRODID:-//My App//My App//EN

224

BEGIN:VTODO

225

UID:task-001@example.com

226

SUMMARY:Complete project documentation

227

DESCRIPTION:Finish writing the API documentation

228

DUE:20250920T170000Z

229

PRIORITY:1

230

STATUS:NEEDS-ACTION

231

END:VTODO

232

END:VCALENDAR"""

233

234

# Save with no overwrite to prevent accidents

235

todo = calendar.save_todo(todo_ical, no_overwrite=True)

236

237

# Create journal entry

238

journal_ical = """BEGIN:VCALENDAR

239

VERSION:2.0

240

PRODID:-//My App//My App//EN

241

BEGIN:VJOURNAL

242

UID:journal-001@example.com

243

DTSTART:20250915T090000Z

244

SUMMARY:Daily standup notes

245

DESCRIPTION:Discussed sprint progress and blockers

246

END:VJOURNAL

247

END:VCALENDAR"""

248

249

journal = calendar.add_journal(journal_ical)

250

```

251

252

### Object Lookup

253

254

Find specific calendar objects by URL or UID for direct access and manipulation.

255

256

```python { .api }

257

def event_by_url(self, href):

258

"""

259

Get event by its URL/href.

260

261

Parameters:

262

- href: str, event URL or href

263

264

Returns:

265

Event: Event object or None if not found

266

"""

267

268

def event_by_uid(self, uid):

269

"""

270

Get event by its UID.

271

272

Parameters:

273

- uid: str, event UID

274

275

Returns:

276

Event: Event object or None if not found

277

"""

278

279

def todo_by_uid(self, uid):

280

"""

281

Get todo by its UID.

282

283

Parameters:

284

- uid: str, todo UID

285

286

Returns:

287

Todo: Todo object or None if not found

288

"""

289

290

def journal_by_uid(self, uid):

291

"""

292

Get journal entry by its UID.

293

294

Parameters:

295

- uid: str, journal UID

296

297

Returns:

298

Journal: Journal object or None if not found

299

"""

300

301

def object_by_uid(self, uid):

302

"""

303

Get any calendar object by its UID.

304

305

Parameters:

306

- uid: str, object UID

307

308

Returns:

309

CalendarObjectResource: Object or None if not found

310

"""

311

```

312

313

### Advanced Search

314

315

Comprehensive search functionality with support for XML queries, component filters, property filters, and date range searches.

316

317

```python { .api }

318

def search(self, xml_query=None, comp_filter=None, prop_filter=None,

319

text_match=None, start=None, end=None, expand=False, verify_expand=True):

320

"""

321

Advanced search for calendar objects with multiple filter options.

322

323

Parameters:

324

- xml_query: str, raw CalDAV XML query

325

- comp_filter: str, component filter (e.g., "VEVENT", "VTODO")

326

- prop_filter: dict, property filters {property: value}

327

- text_match: str, text search in summaries and descriptions

328

- start: datetime, start of date range

329

- end: datetime, end of date range

330

- expand: bool, expand recurring events within date range

331

- verify_expand: bool, verify expanded events (default True)

332

333

Returns:

334

list[CalendarObjectResource]: Matching calendar objects

335

"""

336

337

def date_search(self, start, end=None, compfilter=None, expand=False, verify_expand=True):

338

"""

339

Search for calendar objects within a date range.

340

341

Parameters:

342

- start: datetime, start of search range

343

- end: datetime, end of search range (if None, searches from start forward)

344

- compfilter: str, component type filter ("VEVENT", "VTODO", "VJOURNAL")

345

- expand: bool, expand recurring events within range

346

- verify_expand: bool, verify expanded recurring events

347

348

Returns:

349

list[CalendarObjectResource]: Objects within date range

350

"""

351

```

352

353

**Usage Examples:**

354

355

```python

356

from datetime import datetime, timedelta

357

358

# Find events in the next week

359

start_date = datetime.now()

360

end_date = start_date + timedelta(days=7)

361

362

upcoming_events = calendar.date_search(

363

start=start_date,

364

end=end_date,

365

compfilter="VEVENT",

366

expand=True # Expand recurring events

367

)

368

369

print(f"Found {len(upcoming_events)} upcoming events")

370

for event in upcoming_events:

371

summary = event.icalendar_component.get('SUMMARY', 'No title')

372

dtstart = event.icalendar_component.get('DTSTART').dt

373

print(f" {dtstart}: {summary}")

374

375

# Search for todos with text matching

376

urgent_todos = calendar.search(

377

comp_filter="VTODO",

378

text_match="urgent",

379

prop_filter={"STATUS": "NEEDS-ACTION"}

380

)

381

382

# Complex search with XML query

383

xml_query = """

384

<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">

385

<D:prop xmlns:D="DAV:">

386

<D:getetag/>

387

<C:calendar-data/>

388

</D:prop>

389

<C:filter>

390

<C:comp-filter name="VCALENDAR">

391

<C:comp-filter name="VEVENT">

392

<C:prop-filter name="SUMMARY">

393

<C:text-match collation="i;ascii-casemap">meeting</C:text-match>

394

</C:prop-filter>

395

</C:comp-filter>

396

</C:comp-filter>

397

</C:filter>

398

</C:calendar-query>"""

399

400

meetings = calendar.search(xml_query=xml_query)

401

402

# Look up specific objects

403

specific_event = calendar.event_by_uid("meeting-001@example.com")

404

if specific_event:

405

print(f"Found event: {specific_event.icalendar_component['SUMMARY']}")

406

407

# Find any object type by UID

408

any_object = calendar.object_by_uid("some-uid@example.com")

409

if any_object:

410

print(f"Object type: {any_object.__class__.__name__}")

411

```

412

413

### Free/Busy Operations

414

415

Request and manage free/busy information for scheduling and availability coordination.

416

417

```python { .api }

418

def freebusy_request(self, start, end, attendees=None):

419

"""

420

Request free/busy information for a time range.

421

422

Parameters:

423

- start: datetime, start of time range

424

- end: datetime, end of time range

425

- attendees: list[str], attendee email addresses (optional)

426

427

Returns:

428

FreeBusy: Free/busy information object

429

"""

430

```

431

432

### Calendar Properties

433

434

Access and manage calendar-specific properties and capabilities.

435

436

```python { .api }

437

@property

438

def supported_calendar_component_set(self):

439

"""Get supported calendar component types for this calendar."""

440

441

def get_supported_components(self):

442

"""

443

Get the set of supported component types.

444

445

Returns:

446

set[str]: Set of supported component types (VEVENT, VTODO, etc.)

447

"""

448

```

449

450

**Usage Examples:**

451

452

```python

453

# Check what components this calendar supports

454

supported = calendar.get_supported_components()

455

print(f"Calendar supports: {', '.join(supported)}")

456

457

# Only create todos if supported

458

if 'VTODO' in supported:

459

todo = calendar.save_todo(todo_ical)

460

else:

461

print("This calendar doesn't support todos")

462

463

# Request free/busy for scheduling

464

from datetime import datetime, timedelta

465

466

meeting_start = datetime(2025, 9, 20, 14, 0) # 2 PM

467

meeting_end = meeting_start + timedelta(hours=1)

468

469

freebusy_info = calendar.freebusy_request(

470

start=meeting_start,

471

end=meeting_end,

472

attendees=["attendee1@example.com", "attendee2@example.com"]

473

)

474

475

# Check availability (implementation depends on server response format)

476

if freebusy_info:

477

print("Free/busy information retrieved successfully")

478

```

479

480

## Search Filter Examples

481

482

```python { .api }

483

# Common component filters

484

COMPONENT_FILTERS = {

485

"events": "VEVENT",

486

"todos": "VTODO",

487

"tasks": "VTODO", # alias

488

"journals": "VJOURNAL",

489

"freebusy": "VFREEBUSY"

490

}

491

492

# Common property filters

493

PROPERTY_FILTERS = {

494

# Todo status filters

495

"pending_todos": {"STATUS": "NEEDS-ACTION"},

496

"completed_todos": {"STATUS": "COMPLETED"},

497

"in_progress_todos": {"STATUS": "IN-PROCESS"},

498

499

# Event status filters

500

"confirmed_events": {"STATUS": "CONFIRMED"},

501

"tentative_events": {"STATUS": "TENTATIVE"},

502

"cancelled_events": {"STATUS": "CANCELLED"},

503

504

# Priority filters

505

"high_priority": {"PRIORITY": "1"},

506

"medium_priority": {"PRIORITY": "5"},

507

"low_priority": {"PRIORITY": "9"}

508

}

509

```