diff --git a/main.py b/main.py index 101ff3b..2891928 100755 --- a/main.py +++ b/main.py @@ -1,11 +1,17 @@ import datetime +from caldav.lib.error import NotFoundError +from caldav.objects import Todo from yaml import load, FullLoader +import icalendar from icalendar.parser import Contentlines, Contentline from dateutil.rrule import rrule, FREQNAMES import caldav +APP_ID = 'CaldavRecurringTask' + + class Task: def __init__(self, reference_date, name, data): self.ref_date = reference_date @@ -14,20 +20,22 @@ class Task: self.date_begin = rrule(count=1, dtstart=reference_date, **data['start'])[0] self.date_end = self.date_begin + datetime.timedelta(microseconds=-1, **data['duration']) + self.uid = f"{APP_ID}-{self.name}-{self.date_begin.strftime('%Y%m%d')}" + + self.title = data['title'] self.body = data['body'] self.priority = data['priority'] def to_ical(self): current_dtstamp = datetime.datetime.now().strftime('%Y%m%dT%H%M%SZ') - uid = f"CaldavRecurringTask-{self.name}-{self.date_end.strftime('%Y%m%d')}" c = Contentlines([ Contentline('BEGIN:VCALENDAR'), Contentline('VERSION:2.0'), Contentline('PRODID:-//DorfsvaldNet//CaldavRecuringTaskClient//FR'), Contentline('BEGIN:VTODO'), Contentline(f'DTSTAMP:{current_dtstamp}'), - Contentline(f'UID:{uid}'), + Contentline(f'UID:{self.uid}'), Contentline(f'CREATED:{current_dtstamp}'), Contentline(f'LAST-MODIFIED:{current_dtstamp}'), Contentline(f'SEQUENCE:{"4"}'), @@ -58,8 +66,16 @@ class Client: if self.calendar is None: raise LookupError('No calendar named "{}" found'.format(calendar_name)) - def add_event(self, new_task): - self.calendar.add_event(new_task.to_ical()) + def add_todo(self, new_task): + self.calendar.add_todo(new_task.to_ical()) + + def get_todo_by_uid(self, uid): + try: + todo = self.calendar.todo_by_uid(uid) + # todo.percent_complete = todo.icalendar_component['PERCENT-COMPLETE'] + return todo + except NotFoundError: + return False if __name__ == "__main__": @@ -79,7 +95,15 @@ if __name__ == "__main__": if task_list: server = conf['dav_server'] client = Client(server['url'], server['user'], server['pass'], server['calendar']) + previous_tasks = client.todos(include_completed=True) for task in task_list: - client.add_event(task) + if not client.get_todo_by_uid(task.uid): + # Removing previous completed tasks + for t in previous_tasks: + if t.icalendar_component.get('uid').startswith(f"{APP_ID}-{task.name}")\ + and t.icalendar_component.get('status') == 'COMPLETED': + t.delete() + + client.add_todo(task) print('process finished: {} tasks created'.format(len(task_list))) diff --git a/tasks.example.yml b/tasks.example.yml index f22c0c1..48c6cef 100644 --- a/tasks.example.yml +++ b/tasks.example.yml @@ -38,7 +38,7 @@ weekly_task: freq: WEEKLY byweekday: 6 duration: - days: 60 + days: 4 title: A Weekly task body: This a task that is created once a week and starts on the last day of the week priority: 1 @@ -59,6 +59,6 @@ another_yearly_task: byweekno: 4 duration: days: 60 - title: A Yearly task + title: Another Yearly task body: This a task that is created once a year, on the fourth week of the year priority: 1