From 85dac3f08c75de6167fd4c4ad3fb416a1edb54c7 Mon Sep 17 00:00:00 2001 From: sebu06 Date: Thu, 26 Jan 2023 13:45:44 +0100 Subject: [PATCH] Added Support for Microsoft Busystatus --- khal/icalendar.py | 1 + khal/khalendar/event.py | 29 +++++++++++++++++++++++++++++ khal/ui/__init__.py | 3 +++ khal/ui/editor.py | 11 +++++++++++ 4 files changed, 44 insertions(+) diff --git a/khal/icalendar.py b/khal/icalendar.py index b9d6334aa..8fe84e160 100644 --- a/khal/icalendar.py +++ b/khal/icalendar.py @@ -111,6 +111,7 @@ def new_vevent(locale, event = icalendar.Event() event.add('dtstart', dtstart) + event.add('X-MICROSOFT-CDO-BUSYSTATUS', "BUSY") event.add('dtend', dtend) event.add('dtstamp', dt.datetime.now()) event.add('summary', summary) diff --git a/khal/khalendar/event.py b/khal/khalendar/event.py index 8f3a88fc0..4feaecab1 100644 --- a/khal/khalendar/event.py +++ b/khal/khalendar/event.py @@ -299,6 +299,14 @@ def symbol_strings(self) -> Dict[str, str]: 'right_arrow': '->' } + @property + def allowed_busystatus(self) -> Dict[str, str]: + return {'BUSY': 'Busy', + 'FREE': 'Free', + 'TENTATIVE': 'Tentative', + 'WORKINGELSEWHERE': 'Work elsewhere', + 'OOF': 'Out of office'} + @property def start_local(self) -> dt.datetime: """self.start() localized to local timezone""" @@ -343,6 +351,27 @@ def organizer(self) -> str: else: return email + @property + def busystatus(self) -> str: + if 'X-MICROSOFT-CDO-BUSYSTATUS' not in self._vevents[self.ref]: + return 'BUSY' + return self._vevents[self.ref]['X-MICROSOFT-CDO-BUSYSTATUS'] + + @property + def busystatus_formatted(self) -> str: + if 'X-MICROSOFT-CDO-BUSYSTATUS' not in self._vevents[self.ref]: + return '' + busystatus = self._vevents[self.ref]['X-MICROSOFT-CDO-BUSYSTATUS'] + if busystatus not in self.allowed_busystatus.keys(): + return '' + return self.allowed_busystatus[busystatus] + + def update_busystatus(self, busystatus: str) -> None: + if busystatus and busystatus in self.allowed_busystatus.keys(): + self._vevents[self.ref]['X-MICROSOFT-CDO-BUSYSTATUS'] = busystatus + else: + self._vevents[self.ref].pop('X-MICROSOFT-CDO-BUSYSTATUS') + @property def url(self) -> str: if 'URL' not in self._vevents[self.ref]: diff --git a/khal/ui/__init__.py b/khal/ui/__init__.py index 41b2ca9fe..457bc7121 100644 --- a/khal/ui/__init__.py +++ b/khal/ui/__init__.py @@ -965,6 +965,9 @@ def __init__(self, conf, event, collection=None): if event.url != '': lines.append(urwid.Text('URL: ' + event.url)) + if event.busystatus: + lines.append(urwid.Text('Busy: ' + event.busystatus_formatted)) + if event.attendees != '': lines.append(urwid.Text('Attendees:')) for attendee in event.attendees.split(', '): diff --git a/khal/ui/editor.py b/khal/ui/editor.py index 3edf3b0ce..dbbcbf7d0 100644 --- a/khal/ui/editor.py +++ b/khal/ui/editor.py @@ -340,6 +340,7 @@ def __init__(self, pane, event, save_callback=None, always_save=False): self.location = event.location self.attendees = event.attendees self.categories = event.categories + self.busystatus = event.busystatus self.url = event.url self.startendeditor = StartEndEditor( event.start_local, event.end_local, self._conf, @@ -372,6 +373,12 @@ def decorate_choice(c): ), 'edit' ) + + allowed_status = self.event.allowed_busystatus + self.busystatus_choose = Choice( + allowed_status.keys(), active=self.busystatus, + decorate_func=(lambda x: allowed_status[x]), overlay_width=24) + self.location = urwid.AttrMap(ExtendedEdit( caption=('', 'Location: '), edit_text=self.location), 'edit' ) @@ -402,6 +409,7 @@ def decorate_choice(c): self.attendees, divider, self.startendeditor, + urwid.Columns([(24, self.busystatus_choose)]), self.recurrenceeditor, divider, self.alarms, @@ -443,6 +451,8 @@ def changed(self): return True if self.startendeditor.changed or self.calendar_chooser.changed: return True + if self.busystatus_choose.changed: + return True if self.recurrenceeditor.changed: return True if self.alarms.changed: @@ -456,6 +466,7 @@ def update_vevent(self): self.event.update_attendees(get_wrapped_text(self.attendees).split(',')) self.event.update_categories(get_wrapped_text(self.categories).split(',')) self.event.update_url(get_wrapped_text(self.url)) + self.event.update_busystatus(self.busystatus_choose.active) if self.startendeditor.changed: self.event.update_start_end(