Using the Microsoft Graph API to retrieve Calendar and convert to Orgmode compatible plain text.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.6 KiB

  1. import pyperclip
  2. import mimetypes
  3. import os
  4. import urllib
  5. from adal import AuthenticationContext
  6. import requests
  7. import config
  8. from datetime import datetime
  9. from datetime import date
  10. from datetime import timedelta
  11. import pytz
  12. import oauth2ms
  13. def api_endpoint(url):
  14. """Convert a relative path such as /me/photo/$value to a full URI based
  15. on the current RESOURCE and API_VERSION settings in config.py.
  16. """
  17. if urllib.parse.urlparse(url).scheme in ['http', 'https']:
  18. return url # url is already complete
  19. return urllib.parse.urljoin(f'{config.RESOURCE}/v{config.API_VERSION}/',
  20. url.lstrip('/'))
  21. def parse_cal_date(dateStr):
  22. d = datetime.strptime(dateStr, "%Y-%m-%dT%H:%M:%S.0000000")
  23. exchangeTz = pytz.utc
  24. localTz = pytz.timezone('US/Central')
  25. return exchangeTz.localize(d).astimezone(localTz);
  26. def format_orgmode_date(dateObj):
  27. return dateObj.strftime("%Y-%m-%d %H:%M")
  28. def format_orgmode_time(dateObj):
  29. return dateObj.strftime("%H:%M")
  30. def get_calendar(token):
  31. """Get Calendar from O365
  32. """
  33. start = date.today() - timedelta(days=config.daysHistory)
  34. end = date.today() + timedelta(days=config.daysFuture)
  35. # print(api_endpoint("/"))
  36. cal = requests.get(
  37. api_endpoint(f'me/calendarview?startdatetime={start}T00:00:00.000Z&enddatetime={end}T23:59:59.999Z&$top={config.maxEntries}&$orderby=start/dateTime'),
  38. headers={'Authorization':f'Bearer {token}'}
  39. )
  40. calentries = cal.json()
  41. for appt in calentries['value']:
  42. apptstart = parse_cal_date(appt['start']['dateTime'])
  43. apptend = parse_cal_date(appt['end']['dateTime'])
  44. tags = ""
  45. if appt['categories']:
  46. tags = ":" + ":".join(appt['categories']) + ":"
  47. else:
  48. tags = ":WORK:"
  49. if apptstart.date() == apptend.date():
  50. dateStr = "<" + format_orgmode_date(apptstart) + "-" + format_orgmode_time(apptend) + ">"
  51. else:
  52. dateStr = "<" + format_orgmode_date(apptstart) + ">--<" + format_orgmode_date(apptend) + ">"
  53. body = appt['bodyPreview'].translate({ord('\r'): None})
  54. print(f'* {dateStr} {appt["subject"]} {tags}')
  55. print(":PROPERTIES:")
  56. if appt['location']['displayName'] is not None:
  57. print(":LOCATION: %s" % (appt['location']['displayName']))
  58. if appt['onlineMeeting'] is not None:
  59. print(f":JOINURL: {appt['onlineMeeting']['joinUrl']}")
  60. print(f":RESPONSE: {appt['responseStatus']['response']}")
  61. print(":END:")
  62. print(f"{body}")
  63. print("")
  64. if __name__ == '__main__':
  65. get_calendar(oauth2ms.token)