@@ -268,16 +268,25 @@ def list_tasks_sync(calendar_name: Optional[str] = None):
268268 for cal in calendars_to_check :
269269 todos = cal .todos ()
270270 for todo in todos :
271- task_data = {
272- 'calendar' : cal .name ,
273- 'summary' : todo .instance .vtodo .summary .value if hasattr (todo .instance .vtodo , 'summary' ) else '' ,
274- 'uid' : todo .instance .vtodo .uid .value if hasattr (todo .instance .vtodo , 'uid' ) else '' ,
275- 'status' : todo .instance .vtodo .status .value if hasattr (todo .instance .vtodo , 'status' ) else 'NEEDS-ACTION' ,
276- 'due' : str (todo .instance .vtodo .due .value ) if hasattr (todo .instance .vtodo , 'due' ) else None ,
277- 'priority' : todo .instance .vtodo .priority .value if hasattr (todo .instance .vtodo , 'priority' ) else None ,
278- 'description' : todo .instance .vtodo .description .value if hasattr (todo .instance .vtodo , 'description' ) else '' ,
279- }
280- tasks .append (task_data )
271+ # Parse the todo data using ics library
272+ try :
273+ ical_data = todo .data
274+ parsed_cal = Calendar (ical_data )
275+
276+ for ics_todo in parsed_cal .todos :
277+ task_data = {
278+ 'calendar' : cal .name ,
279+ 'summary' : ics_todo .name or '' ,
280+ 'uid' : ics_todo .uid or '' ,
281+ 'status' : ics_todo .status or 'NEEDS-ACTION' ,
282+ 'due' : str (ics_todo .due ) if ics_todo .due else None ,
283+ 'priority' : ics_todo .priority ,
284+ 'description' : ics_todo .description or '' ,
285+ }
286+ tasks .append (task_data )
287+ except :
288+ # Fallback if parsing fails
289+ continue
281290
282291 return tasks
283292
@@ -304,12 +313,23 @@ def complete_task_sync(calendar_name: str, task_uid: str):
304313
305314 todos = calendar .todos ()
306315 for todo in todos :
307- if hasattr (todo .instance .vtodo , 'uid' ) and todo .instance .vtodo .uid .value == task_uid :
308- todo .instance .vtodo .status .value = 'COMPLETED'
309- todo .instance .vtodo .add ('completed' )
310- todo .instance .vtodo .completed .value = datetime .now (timezone .utc )
311- todo .save ()
312- return True
316+ # Parse the todo data using ics library
317+ try :
318+ ical_data = todo .data
319+ parsed_cal = Calendar (ical_data )
320+
321+ for ics_todo in parsed_cal .todos :
322+ if ics_todo .uid == task_uid :
323+ # Mark as completed
324+ ics_todo .status = 'COMPLETED'
325+ ics_todo .completed = datetime .now (timezone .utc )
326+
327+ # Serialize and save
328+ todo .data = str (parsed_cal )
329+ todo .save ()
330+ return True
331+ except :
332+ continue
313333
314334 return False
315335
@@ -331,33 +351,40 @@ def update_task_sync(calendar_name: str, task_uid: str, title: Optional[str] = N
331351
332352 todos = calendar .todos ()
333353 for todo in todos :
334- if hasattr (todo .instance .vtodo , 'uid' ) and todo .instance .vtodo .uid .value == task_uid :
335- if title :
336- todo .instance .vtodo .summary .value = title
337- if description :
338- todo .instance .vtodo .description .value = description
339- if priority is not None :
340- if not hasattr (todo .instance .vtodo , 'priority' ):
341- todo .instance .vtodo .add ('priority' )
342- todo .instance .vtodo .priority .value = priority
343- if due_date :
344- parsed_date = datetime .strptime (due_date , "%Y-%m-%d" )
345- if due_time :
346- parsed_time = datetime .strptime (due_time , "%I:%M %p" ).time ()
347- due_datetime = datetime .combine (parsed_date , parsed_time )
348- else :
349- due_datetime = parsed_date
350-
351- if timezone_str :
352- tz = pytz .timezone (timezone_str )
353- due_datetime = tz .localize (due_datetime )
354-
355- if not hasattr (todo .instance .vtodo , 'due' ):
356- todo .instance .vtodo .add ('due' )
357- todo .instance .vtodo .due .value = due_datetime
358-
359- todo .save ()
360- return True
354+ # Parse the todo data using ics library
355+ try :
356+ ical_data = todo .data
357+ parsed_cal = Calendar (ical_data )
358+
359+ for ics_todo in parsed_cal .todos :
360+ if ics_todo .uid == task_uid :
361+ # Update fields if provided
362+ if title :
363+ ics_todo .name = title
364+ if description :
365+ ics_todo .description = description
366+ if priority is not None :
367+ ics_todo .priority = priority
368+ if due_date :
369+ parsed_date = datetime .strptime (due_date , "%Y-%m-%d" )
370+ if due_time :
371+ parsed_time = datetime .strptime (due_time , "%I:%M %p" ).time ()
372+ due_datetime = datetime .combine (parsed_date , parsed_time )
373+ else :
374+ due_datetime = parsed_date
375+
376+ if timezone_str :
377+ tz = pytz .timezone (timezone_str )
378+ due_datetime = tz .localize (due_datetime )
379+
380+ ics_todo .due = due_datetime
381+
382+ # Serialize and save
383+ todo .data = str (parsed_cal )
384+ todo .save ()
385+ return True
386+ except :
387+ continue
361388
362389 return False
363390
@@ -385,9 +412,18 @@ def delete_task_sync(calendar_name: str, task_uid: str):
385412
386413 todos = calendar .todos ()
387414 for todo in todos :
388- if hasattr (todo .instance .vtodo , 'uid' ) and todo .instance .vtodo .uid .value == task_uid :
389- todo .delete ()
390- return True
415+ # Parse the todo data using ics library to find the right one
416+ try :
417+ ical_data = todo .data
418+ parsed_cal = Calendar (ical_data )
419+
420+ for ics_todo in parsed_cal .todos :
421+ if ics_todo .uid == task_uid :
422+ # Delete the todo
423+ todo .delete ()
424+ return True
425+ except :
426+ continue
391427
392428 return False
393429
0 commit comments