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

task-management.mddocs/

0

# Task Management

1

2

Comprehensive todo/task management functionality with support for due dates, completion tracking, priority management, and task hierarchies using CalDAV VTODO components.

3

4

## Capabilities

5

6

### Todo Class

7

8

Represents CalDAV todos/tasks (VTODO components) with specialized methods for task-specific operations including completion tracking and due date management.

9

10

```python { .api }

11

class Todo(CalendarObjectResource):

12

def get_due(self):

13

"""

14

Get todo due date/time.

15

16

Returns:

17

datetime or date: Todo due date/time, or None if not set

18

"""

19

20

def get_dtstart(self):

21

"""

22

Get todo start date/time.

23

24

Returns:

25

datetime or date: Todo start date/time, or None if not set

26

"""

27

28

def get_duration(self):

29

"""

30

Get todo duration.

31

32

Returns:

33

timedelta: Todo duration, or None if not set

34

"""

35

36

def set_due(self, due):

37

"""

38

Set todo due date/time.

39

40

Parameters:

41

- due: datetime or date, new due date/time

42

"""

43

44

def set_dtstart(self, dtstart):

45

"""

46

Set todo start date/time.

47

48

Parameters:

49

- dtstart: datetime or date, new start date/time

50

"""

51

52

def set_duration(self, duration):

53

"""

54

Set todo duration.

55

56

Parameters:

57

- duration: timedelta, task duration

58

"""

59

60

def complete(self, completion_timestamp=None, handle_rrule=True):

61

"""

62

Mark todo as completed.

63

64

Parameters:

65

- completion_timestamp: datetime, completion time (default: now)

66

- handle_rrule: bool, handle recurring todos by creating next occurrence

67

68

Returns:

69

Todo: Next occurrence if recurring, or None

70

"""

71

```

72

73

**Usage Examples:**

74

75

```python

76

import caldav

77

from datetime import datetime, timedelta, timezone

78

79

# Get existing todos

80

calendar = principal.calendars()[0]

81

todos = calendar.todos()

82

83

if todos:

84

todo = todos[0]

85

86

# Get todo information

87

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

88

due_date = todo.get_due()

89

start_date = todo.get_dtstart()

90

status = todo.icalendar_component.get('STATUS', 'No status')

91

92

print(f"Todo: {summary}")

93

print(f"Due: {due_date}")

94

print(f"Status: {status}")

95

96

# Modify todo timing

97

new_due = datetime(2025, 9, 30, 17, 0, tzinfo=timezone.utc)

98

todo.set_due(new_due)

99

todo.set_dtstart(datetime.now(timezone.utc))

100

101

# Mark as completed

102

if status != 'COMPLETED':

103

next_occurrence = todo.complete()

104

if next_occurrence:

105

print(f"Created next occurrence: {next_occurrence.id}")

106

else:

107

print("Todo marked as completed")

108

```

109

110

### Todo Creation

111

112

Create new todos with comprehensive VTODO support including all standard properties and task-specific features.

113

114

```python { .api }

115

# Todo creation through calendar.save_todo() - see calendar-management.md

116

# Additional todo-specific creation patterns:

117

118

def create_simple_todo(summary, due_date=None, priority=None, description=None):

119

"""

120

Helper function to create simple todo iCalendar data.

121

122

Parameters:

123

- summary: str, todo title/summary

124

- due_date: datetime, optional due date

125

- priority: int, priority level (1-9, 1=highest, 9=lowest)

126

- description: str, optional todo description

127

128

Returns:

129

str: iCalendar data for the todo

130

"""

131

```

132

133

**Usage Examples:**

134

135

```python

136

from datetime import datetime, timezone

137

import uuid

138

139

# Create a simple todo

140

def create_task(title, due_date=None, priority=5, description=None):

141

task_uid = f"{uuid.uuid4()}@example.com"

142

143

ical_data = f"""BEGIN:VCALENDAR

144

VERSION:2.0

145

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

146

BEGIN:VTODO

147

UID:{task_uid}

148

SUMMARY:{title}

149

STATUS:NEEDS-ACTION

150

PRIORITY:{priority}

151

"""

152

153

if due_date:

154

ical_data += f"DUE:{due_date.strftime('%Y%m%dT%H%M%SZ')}\n"

155

if description:

156

ical_data += f"DESCRIPTION:{description}\n"

157

158

ical_data += f"""DTSTAMP:{datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%SZ')}

159

END:VTODO

160

END:VCALENDAR"""

161

162

return ical_data

163

164

# Create and save a todo

165

task_due = datetime(2025, 10, 1, 17, 0, tzinfo=timezone.utc)

166

task_ical = create_task(

167

title="Complete project documentation",

168

due_date=task_due,

169

priority=2, # High priority

170

description="Finish writing user guide and API documentation"

171

)

172

173

todo = calendar.save_todo(task_ical)

174

print(f"Created todo: {todo.id}")

175

176

# Create recurring todo

177

recurring_todo_ical = """BEGIN:VCALENDAR

178

VERSION:2.0

179

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

180

BEGIN:VTODO

181

UID:weekly-report@example.com

182

SUMMARY:Submit weekly status report

183

DESCRIPTION:Prepare and submit weekly project status report

184

DUE:20250919T170000Z

185

STATUS:NEEDS-ACTION

186

PRIORITY:3

187

RRULE:FREQ=WEEKLY;BYDAY=FR;COUNT=12

188

END:VTODO

189

END:VCALENDAR"""

190

191

recurring_todo = calendar.save_todo(recurring_todo_ical)

192

193

# Create todo with subtasks (using RELATED-TO property)

194

parent_todo_ical = """BEGIN:VCALENDAR

195

VERSION:2.0

196

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

197

BEGIN:VTODO

198

UID:project-launch@example.com

199

SUMMARY:Launch new product

200

DESCRIPTION:Complete all tasks required for product launch

201

DUE:20251215T170000Z

202

STATUS:NEEDS-ACTION

203

PRIORITY:1

204

END:VTODO

205

END:VCALENDAR"""

206

207

parent_todo = calendar.save_todo(parent_todo_ical)

208

209

# Create subtask

210

subtask_ical = f"""BEGIN:VCALENDAR

211

VERSION:2.0

212

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

213

BEGIN:VTODO

214

UID:marketing-materials@example.com

215

SUMMARY:Create marketing materials

216

DESCRIPTION:Design and create marketing collateral

217

DUE:20251201T170000Z

218

STATUS:NEEDS-ACTION

219

PRIORITY:2

220

RELATED-TO;RELTYPE=PARENT:{parent_todo.id}

221

END:VTODO

222

END:VCALENDAR"""

223

224

subtask = calendar.save_todo(subtask_ical)

225

```

226

227

### Todo Status Management

228

229

Comprehensive status tracking and workflow management for todos with support for different completion states.

230

231

```python { .api }

232

# Todo status values (accessed via icalendar_component['STATUS'])

233

TODO_STATUS = {

234

"NEEDS-ACTION": "Task needs to be completed",

235

"COMPLETED": "Task has been completed",

236

"IN-PROCESS": "Task is currently being worked on",

237

"CANCELLED": "Task has been cancelled"

238

}

239

240

# Todo priority levels (accessed via icalendar_component['PRIORITY'])

241

TODO_PRIORITY = {

242

0: "Undefined priority",

243

1: "Highest priority",

244

2: "High priority",

245

3: "High priority",

246

4: "Medium-high priority",

247

5: "Medium priority (default)",

248

6: "Medium-low priority",

249

7: "Low priority",

250

8: "Low priority",

251

9: "Lowest priority"

252

}

253

```

254

255

**Usage Examples:**

256

257

```python

258

# Manage todo status

259

todo = calendar.todo_by_uid("project-task@example.com")

260

if todo:

261

component = todo.icalendar_component

262

263

# Check current status

264

current_status = component.get('STATUS', 'NEEDS-ACTION')

265

print(f"Current status: {current_status}")

266

267

# Start working on the task

268

component['STATUS'] = 'IN-PROCESS'

269

component['PERCENT-COMPLETE'] = 25 # 25% complete

270

todo.save()

271

272

# Update progress

273

component['PERCENT-COMPLETE'] = 75

274

todo.save()

275

276

# Complete the task

277

todo.complete() # This sets STATUS=COMPLETED and COMPLETED timestamp

278

279

# Filter todos by status

280

pending_todos = calendar.search(

281

comp_filter="VTODO",

282

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

283

)

284

285

in_progress_todos = calendar.search(

286

comp_filter="VTODO",

287

prop_filter={"STATUS": "IN-PROCESS"}

288

)

289

290

completed_todos = calendar.search(

291

comp_filter="VTODO",

292

prop_filter={"STATUS": "COMPLETED"}

293

)

294

295

print(f"Pending: {len(pending_todos)}, In Progress: {len(in_progress_todos)}, Completed: {len(completed_todos)}")

296

```

297

298

### Todo Hierarchy and Dependencies

299

300

Manage task hierarchies and dependencies using RELATED-TO properties for project organization and workflow management.

301

302

```python { .api }

303

def get_relatives(self, field_filter=None, include_self=False):

304

"""

305

Get related todos (parent/child relationships).

306

307

Parameters:

308

- field_filter: str, filter by relation type ('PARENT', 'CHILD', 'SIBLING')

309

- include_self: bool, include this todo in results

310

311

Returns:

312

list[CalendarObjectResource]: Related todos

313

"""

314

```

315

316

**Usage Examples:**

317

318

```python

319

# Create project with subtasks

320

project_ical = """BEGIN:VCALENDAR

321

VERSION:2.0

322

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

323

BEGIN:VTODO

324

UID:website-redesign@example.com

325

SUMMARY:Website Redesign Project

326

DESCRIPTION:Complete website redesign and launch

327

DUE:20251231T170000Z

328

STATUS:NEEDS-ACTION

329

PRIORITY:1

330

END:VTODO

331

END:VCALENDAR"""

332

333

project = calendar.save_todo(project_ical)

334

335

# Create subtasks with parent relationship

336

subtasks = [

337

("Design mockups", "Create visual designs and mockups", "20251115T170000Z"),

338

("Frontend development", "Implement frontend based on designs", "20251201T170000Z"),

339

("Backend integration", "Connect frontend to existing backend", "20251215T170000Z"),

340

("Testing and QA", "Test all functionality and fix bugs", "20251220T170000Z")

341

]

342

343

created_subtasks = []

344

for i, (summary, description, due) in enumerate(subtasks):

345

subtask_uid = f"website-subtask-{i+1}@example.com"

346

347

subtask_ical = f"""BEGIN:VCALENDAR

348

VERSION:2.0

349

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

350

BEGIN:VTODO

351

UID:{subtask_uid}

352

SUMMARY:{summary}

353

DESCRIPTION:{description}

354

DUE:{due}

355

STATUS:NEEDS-ACTION

356

PRIORITY:2

357

RELATED-TO;RELTYPE=PARENT:{project.id}

358

END:VTODO

359

END:VCALENDAR"""

360

361

subtask = calendar.save_todo(subtask_ical)

362

created_subtasks.append(subtask)

363

364

# Find all subtasks of the project

365

project_subtasks = project.get_relatives(field_filter="CHILD")

366

print(f"Project has {len(project_subtasks)} subtasks")

367

368

# Create dependency between subtasks (frontend depends on design)

369

design_task = created_subtasks[0]

370

frontend_task = created_subtasks[1]

371

372

# Add dependency relationship

373

frontend_component = frontend_task.icalendar_component

374

frontend_component.add('RELATED-TO', design_task.id)

375

frontend_component['RELATED-TO'].params['RELTYPE'] = 'DEPENDS-ON'

376

frontend_task.save()

377

378

print(f"Frontend task now depends on: {design_task.id}")

379

```

380

381

### Todo Queries and Filtering

382

383

Advanced todo querying with status filters, due date ranges, and priority-based searches.

384

385

```python { .api }

386

# Common todo search patterns using calendar.search() - see calendar-management.md

387

388

def find_overdue_todos(calendar):

389

"""Find todos past their due date."""

390

from datetime import datetime

391

now = datetime.now()

392

393

todos = calendar.search(comp_filter="VTODO")

394

overdue = []

395

396

for todo in todos:

397

due_date = todo.get_due()

398

status = todo.icalendar_component.get('STATUS', 'NEEDS-ACTION')

399

400

if due_date and due_date < now and status != 'COMPLETED':

401

overdue.append(todo)

402

403

return overdue

404

405

def find_high_priority_todos(calendar):

406

"""Find high priority todos."""

407

return calendar.search(

408

comp_filter="VTODO",

409

prop_filter={"PRIORITY": "1"}

410

) + calendar.search(

411

comp_filter="VTODO",

412

prop_filter={"PRIORITY": "2"}

413

)

414

415

def find_todos_due_this_week(calendar):

416

"""Find todos due in the next 7 days."""

417

from datetime import datetime, timedelta

418

419

start = datetime.now()

420

end = start + timedelta(days=7)

421

422

todos = calendar.search(comp_filter="VTODO")

423

due_this_week = []

424

425

for todo in todos:

426

due_date = todo.get_due()

427

status = todo.icalendar_component.get('STATUS', 'NEEDS-ACTION')

428

429

if due_date and start <= due_date <= end and status != 'COMPLETED':

430

due_this_week.append(todo)

431

432

return due_this_week

433

```

434

435

**Usage Examples:**

436

437

```python

438

# Find todos by various criteria

439

overdue = find_overdue_todos(calendar)

440

print(f"Overdue todos: {len(overdue)}")

441

442

high_priority = find_high_priority_todos(calendar)

443

print(f"High priority todos: {len(high_priority)}")

444

445

due_soon = find_todos_due_this_week(calendar)

446

print(f"Due this week: {len(due_soon)}")

447

448

# Search by text in summary or description

449

project_todos = calendar.search(

450

comp_filter="VTODO",

451

text_match="website"

452

)

453

454

# Find todos by specific status

455

active_todos = calendar.search(

456

comp_filter="VTODO",

457

prop_filter={"STATUS": "IN-PROCESS"}

458

)

459

460

# Complex status filtering

461

incomplete_todos = []

462

for status in ["NEEDS-ACTION", "IN-PROCESS"]:

463

todos = calendar.search(

464

comp_filter="VTODO",

465

prop_filter={"STATUS": status}

466

)

467

incomplete_todos.extend(todos)

468

469

print(f"Total incomplete todos: {len(incomplete_todos)}")

470

```

471

472

### Recurring Todos

473

474

Handle recurring todos with automatic creation of next occurrences upon completion.

475

476

```python { .api }

477

# Recurring todos use the same RRULE syntax as events

478

# When completed with handle_rrule=True, a new occurrence is automatically created

479

480

RECURRING_TODO_PATTERNS = {

481

"daily": "FREQ=DAILY",

482

"weekdays": "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR",

483

"weekly": "FREQ=WEEKLY",

484

"monthly": "FREQ=MONTHLY",

485

"yearly": "FREQ=YEARLY"

486

}

487

```

488

489

**Usage Examples:**

490

491

```python

492

# Create daily recurring todo

493

daily_standup_ical = """BEGIN:VCALENDAR

494

VERSION:2.0

495

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

496

BEGIN:VTODO

497

UID:daily-standup-prep@example.com

498

SUMMARY:Prepare for daily standup

499

DESCRIPTION:Review progress and prepare standup updates

500

DUE:20250915T090000Z

501

STATUS:NEEDS-ACTION

502

PRIORITY:3

503

RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;COUNT=50

504

END:VTODO

505

END:VCALENDAR"""

506

507

recurring_todo = calendar.save_todo(daily_standup_ical)

508

509

# Complete the recurring todo - this creates the next occurrence

510

next_occurrence = recurring_todo.complete(handle_rrule=True)

511

if next_occurrence:

512

print(f"Completed today's standup prep, created tomorrow's: {next_occurrence.id}")

513

514

# Create monthly recurring todo

515

monthly_report_ical = """BEGIN:VCALENDAR

516

VERSION:2.0

517

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

518

BEGIN:VTODO

519

UID:monthly-report@example.com

520

SUMMARY:Submit monthly progress report

521

DESCRIPTION:Compile and submit monthly team progress report

522

DUE:20250930T170000Z

523

STATUS:NEEDS-ACTION

524

PRIORITY:2

525

RRULE:FREQ=MONTHLY;BYMONTHDAY=-1

526

END:VTODO

527

END:VCALENDAR"""

528

529

monthly_todo = calendar.save_todo(monthly_report_ical)

530

```

531

532

## Todo Properties

533

534

```python { .api }

535

# Common todo properties that can be accessed via icalendar_component

536

TODO_PROPERTIES = {

537

"SUMMARY": "str", # Todo title/summary

538

"DESCRIPTION": "str", # Todo description

539

"DUE": "datetime", # Due date/time

540

"DTSTART": "datetime", # Start date/time

541

"DURATION": "timedelta", # Duration

542

"STATUS": "str", # NEEDS-ACTION, COMPLETED, IN-PROCESS, CANCELLED

543

"PRIORITY": "int", # Priority (0-9, 0=undefined, 1=highest, 9=lowest)

544

"PERCENT-COMPLETE": "int", # Completion percentage (0-100)

545

"COMPLETED": "datetime", # Completion timestamp (set by complete())

546

"CLASS": "str", # PUBLIC, PRIVATE, CONFIDENTIAL

547

"CATEGORIES": "list[str]", # Todo categories/tags

548

"RELATED-TO": "str", # Related todo UID

549

"RRULE": "str", # Recurrence rule

550

}

551

```