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.

128 lines
4.6KB

  1. #!/usr/bin/env python3
  2. from O365 import Account, MSOffice365Protocol, FileSystemTokenBackend, Connection
  3. import configparser
  4. from datetime import datetime, timedelta
  5. import argparse
  6. parser = argparse.ArgumentParser(prog='seatingplan', description="Script to generate a seating plan via Office365 Calendars")
  7. parser.add_argument("-c", "--client-id", type=str, required=True, dest='client_id',
  8. help='Client ID for registered azure application')
  9. parser.add_argument("-s", "--client-secret", type=str, required=True, dest='client_secret',
  10. help='Client secret for registered azure application')
  11. parser.add_argument("-t", "--tenant-id", type=str, required=True, dest='tenant_id',
  12. help='Tenant ID for registered azure application')
  13. def read_config():
  14. """
  15. Reads config file and sets up variables foo
  16. :return: credentials: ('client_id', 'client_secret') and tenant: str
  17. """
  18. # TODO: Deprecate this file so we use an arg version instead
  19. config = configparser.ConfigParser()
  20. config.read("./config")
  21. credentials = (config["client"]["id"], config["client"]["secret"])
  22. tenant = config["client"]["tenant"]
  23. email = config["client"]["out_of_office_email"]
  24. return credentials, tenant, email
  25. def create_session():
  26. """
  27. Create a session with the API and save the token for later use.
  28. :return: Account class and email: str
  29. """
  30. config = parser.parse_args()
  31. credentials = (config.client_id, config.client_secret)
  32. tenant = config.tenant_id
  33. my_protocol = MSOffice365Protocol(api_version='v2.0')
  34. token_backend = FileSystemTokenBackend(token_filename='access_token.txt')
  35. return Account(
  36. credentials,
  37. protocol=my_protocol,
  38. tenant_id=tenant,
  39. token_backend=token_backend
  40. )
  41. def authenticate_session(session: Account):
  42. """
  43. Authenticates account session object with oauth. Uses the default auth flow that comes with the library
  44. It could be merged with oauth wrapper but this works too.
  45. :param session: Account object
  46. :return:
  47. """
  48. try:
  49. session.con.oauth_request("https://outlook.office.com/api/v2.0/me/calendar", "get")
  50. except RuntimeError: # Not authenticated. Need to ask user for url
  51. session.authenticate(scopes=['basic', 'address_book', 'users', 'calendar_shared'])
  52. session.con.oauth_request("https://outlook.office.com/api/v2.0/me/calendar", "get")
  53. def oauth_request(connection: Connection, url: str):
  54. """
  55. Wrapper for Connection.oauth_request to provide some error handling
  56. :param connection:
  57. :param url:
  58. :return:
  59. """
  60. request = connection.oauth_request(url, "get")
  61. if request.status_code != 200:
  62. print(f"Request failed: GET request to {url} failed with {request.status_code} error")
  63. else:
  64. return request
  65. def get_week_datetime():
  66. """
  67. Gets the current week's Monday and Friday to be used to filter a calendar.
  68. If this script is ran during the work week (Monday-Friday), it will be the current week. If it is ran on the weekend, it will generate for next week.
  69. :return: Monday and Friday: Datetime object
  70. """
  71. today = datetime.now()
  72. weekday = today.weekday()
  73. # If this script is run during the week
  74. if weekday <= 4: # 0 = Monday, 6 = Sunday
  75. monday = today - timedelta(days=weekday) # Monday = 0-0, Friday = 4-4
  76. friday = today + timedelta(days=4 - weekday) # Fri to Fri 4 + (4 - 4), Tues to Fri = 2 + (4 - 2)
  77. return monday, friday
  78. else:
  79. monday = today - timedelta(days=weekday) + timedelta(days=7) # Monday = 0-0, Friday = 4-4
  80. friday = today + timedelta(days=4 - weekday) + timedelta(
  81. days=7) # Fri to Fri 4 + (4 - 4), Tues to Fri = 2 + (4 - 2)
  82. return monday, friday
  83. def main():
  84. """
  85. Main function that is ran on start up. Script is ran from here.
  86. """
  87. session = create_session()
  88. authenticate_session(session)
  89. r = session.con.oauth_request("https://outlook.office.com/api/v2.0/users/{email}/calendar/events", "get")
  90. # request = account.con.oauth_request("https://outlook.office.com/api/v2.0/users/EMAIL/calendar/events?$filter=Start/DateTime ge '2019-09-04T08:00' AND End/Datetime le '2019-09-05T08:00'&$top=50", "get")
  91. print(r.text)
  92. # setup csv
  93. # API request events from out of office email
  94. # loop over events
  95. # find out who the event is talking about
  96. # insert into csv
  97. # output csv
  98. monday, friday = get_week_datetime()
  99. print(f"Monday is {monday}, Friday is {friday}")
  100. if __name__ == "__main__":
  101. main()