Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Support for Microsoft Busystatus #1220

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions khal/icalendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
29 changes: 29 additions & 0 deletions khal/khalendar/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'}
Comment on lines +304 to +308
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to define this dictionary inside a function, just make it a global dictionary. Otherwise it gets recreated each time the function is called, which is kinda pointless.


@property
def start_local(self) -> dt.datetime:
"""self.start() localized to local timezone"""
Expand Down Expand Up @@ -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'
Comment on lines +356 to +357
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this property is not set, I don't think we should fall back to BUSY, we should return None instead. Especially since this property is non-standard.

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]
Comment on lines +362 to +367
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non blocking hint: You can use self._vevents[self.ref].get('X-MICROSOFT-CDO-BUSYSTATUS', None), which returns the value (if present) or None (if absent).

Suggested change
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]
busystatus = self._vevents[self.ref].get('X-MICROSOFT-CDO-BUSYSTATUS', None)
if busystatus not in self.allowed_busystatus.keys():
return ''
return self.allowed_busystatus[busystatus]

Which can be further simplified into:

Suggested change
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]
busystatus = self._vevents[self.ref].get('X-MICROSOFT-CDO-BUSYSTATUS', None)
return self.allowed_busystatus.get(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]:
Expand Down
3 changes: 3 additions & 0 deletions khal/ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(', '):
Expand Down
11 changes: 11 additions & 0 deletions khal/ui/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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'
)
Expand Down Expand Up @@ -402,6 +409,7 @@ def decorate_choice(c):
self.attendees,
divider,
self.startendeditor,
urwid.Columns([(24, self.busystatus_choose)]),
self.recurrenceeditor,
divider,
self.alarms,
Expand Down Expand Up @@ -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:
Expand All @@ -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(
Expand Down