From fbfc674ca56a9edee60883b9202fef418a194179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isabella=20Gross=20Alstr=C3=B6m?= Date: Sun, 2 Jun 2019 22:58:27 +0200 Subject: [PATCH] Add service for adding event to google component (#22473) * Add service for adding event to google component * Add service examples for google.add_event * add refactoring based on reviews * Fix too long lines * Order import * Move to move line * Remove parenthesis * Add service for adding event to google component * Add service examples for google.add_event * add refactoring based on reviews * Add check for correct scopes, otherwise re-authenticate * fix build failure * fix build failure --- homeassistant/components/google/__init__.py | 113 +++++++++++++++++- homeassistant/components/google/services.yaml | 27 +++++ 2 files changed, 135 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/google/__init__.py b/homeassistant/components/google/__init__.py index e9bbf3f96cd..027a6b2f568 100644 --- a/homeassistant/components/google/__init__.py +++ b/homeassistant/components/google/__init__.py @@ -1,4 +1,5 @@ """Support for Google - Calendar Event Devices.""" +from datetime import timedelta, datetime import logging import os import yaml @@ -35,17 +36,32 @@ CONF_MAX_RESULTS = 'max_results' DEFAULT_CONF_TRACK_NEW = True DEFAULT_CONF_OFFSET = '!!' +EVENT_CALENDAR_ID = 'calendar_id' +EVENT_DESCRIPTION = 'description' +EVENT_END_CONF = 'end' +EVENT_END_DATE = 'end_date' +EVENT_END_DATETIME = 'end_date_time' +EVENT_IN = 'in' +EVENT_IN_DAYS = 'days' +EVENT_IN_WEEKS = 'weeks' +EVENT_START_CONF = 'start' +EVENT_START_DATE = 'start_date' +EVENT_START_DATETIME = 'start_date_time' +EVENT_SUMMARY = 'summary' +EVENT_TYPES_CONF = 'event_types' + NOTIFICATION_ID = 'google_calendar_notification' -NOTIFICATION_TITLE = 'Google Calendar Setup' +NOTIFICATION_TITLE = "Google Calendar Setup" GROUP_NAME_ALL_CALENDARS = "Google Calendar Sensors" SERVICE_SCAN_CALENDARS = 'scan_for_calendars' SERVICE_FOUND_CALENDARS = 'found_calendar' +SERVICE_ADD_EVENT = 'add_event' DATA_INDEX = 'google_calendars' YAML_DEVICES = '{}_calendars.yaml'.format(DOMAIN) -SCOPES = 'https://www.googleapis.com/auth/calendar.readonly' +SCOPES = 'https://www.googleapis.com/auth/calendar' TOKEN_FILE = '.{}.token'.format(DOMAIN) @@ -73,6 +89,27 @@ DEVICE_SCHEMA = vol.Schema({ vol.All(cv.ensure_list, [_SINGLE_CALSEARCH_CONFIG]), }, extra=vol.ALLOW_EXTRA) +_EVENT_IN_TYPES = vol.Schema( + { + vol.Exclusive(EVENT_IN_DAYS, EVENT_TYPES_CONF): cv.positive_int, + vol.Exclusive(EVENT_IN_WEEKS, EVENT_TYPES_CONF): cv.positive_int, + } +) + +ADD_EVENT_SERVICE_SCHEMA = vol.Schema( + { + vol.Required(EVENT_CALENDAR_ID): cv.string, + vol.Required(EVENT_SUMMARY): cv.string, + vol.Optional(EVENT_DESCRIPTION, default=""): cv.string, + vol.Exclusive(EVENT_START_DATE, EVENT_START_CONF): cv.date, + vol.Exclusive(EVENT_END_DATE, EVENT_END_CONF): cv.date, + vol.Exclusive(EVENT_START_DATETIME, EVENT_START_CONF): cv.datetime, + vol.Exclusive(EVENT_END_DATETIME, EVENT_END_CONF): cv.datetime, + vol.Exclusive(EVENT_IN, EVENT_START_CONF, EVENT_END_CONF): + _EVENT_IN_TYPES + } +) + def do_authentication(hass, hass_config, config): """Notify user of actions and authenticate. @@ -87,10 +124,9 @@ def do_authentication(hass, hass_config, config): oauth = OAuth2WebServerFlow( client_id=config[CONF_CLIENT_ID], client_secret=config[CONF_CLIENT_SECRET], - scope='https://www.googleapis.com/auth/calendar.readonly', + scope='https://www.googleapis.com/auth/calendar', redirect_uri='Home-Assistant.io', ) - try: dev_flow = oauth.step1_get_device_and_user_codes() except OAuth2DeviceCodeError as err: @@ -155,11 +191,23 @@ def setup(hass, config): if not os.path.isfile(token_file): do_authentication(hass, config, conf) else: - do_setup(hass, config, conf) + if not check_correct_scopes(token_file): + do_authentication(hass, config, conf) + else: + do_setup(hass, config, conf) return True +def check_correct_scopes(token_file): + """Check for the correct scopes in file.""" + tokenfile = open(token_file, "r").read() + if "readonly" in tokenfile: + _LOGGER.warning("Please re-authenticate with Google.") + return False + return True + + def setup_services(hass, hass_config, track_new_found_calendars, calendar_service): """Set up the service listeners.""" @@ -195,6 +243,61 @@ def setup_services(hass, hass_config, track_new_found_calendars, hass.services.register( DOMAIN, SERVICE_SCAN_CALENDARS, _scan_for_calendars) + + def _add_event(call): + """Add a new event to calendar.""" + service = calendar_service.get() + start = {} + end = {} + + if EVENT_IN in call.data: + if EVENT_IN_DAYS in call.data[EVENT_IN]: + now = datetime.now() + + start_in = now + timedelta( + days=call.data[EVENT_IN][EVENT_IN_DAYS]) + end_in = start_in + timedelta(days=1) + + start = {'date': start_in.strftime('%Y-%m-%d')} + end = {'date': end_in.strftime('%Y-%m-%d')} + + elif EVENT_IN_WEEKS in call.data[EVENT_IN]: + now = datetime.now() + + start_in = now + timedelta( + weeks=call.data[EVENT_IN][EVENT_IN_WEEKS]) + end_in = start_in + timedelta(days=1) + + start = {'date': start_in.strftime('%Y-%m-%d')} + end = {'date': end_in.strftime('%Y-%m-%d')} + + elif EVENT_START_DATE in call.data: + start = {'date': str(call.data[EVENT_START_DATE])} + end = {'date': str(call.data[EVENT_END_DATE])} + + elif EVENT_START_DATETIME in call.data: + start_dt = str(call.data[EVENT_START_DATETIME] + .strftime('%Y-%m-%dT%H:%M:%S')) + end_dt = str(call.data[EVENT_END_DATETIME] + .strftime('%Y-%m-%dT%H:%M:%S')) + start = {'dateTime': start_dt, + 'timeZone': str(hass.config.time_zone)} + end = {'dateTime': end_dt, + 'timeZone': str(hass.config.time_zone)} + + event = { + 'summary': call.data[EVENT_SUMMARY], + 'description': call.data[EVENT_DESCRIPTION], + 'start': start, + 'end': end, + } + service_data = {'calendarId': call.data[EVENT_CALENDAR_ID], + 'body': event} + event = service.events().insert(**service_data).execute() + + hass.services.register( + DOMAIN, SERVICE_ADD_EVENT, _add_event, schema=ADD_EVENT_SERVICE_SCHEMA + ) return True diff --git a/homeassistant/components/google/services.yaml b/homeassistant/components/google/services.yaml index 34eecb33fd5..048e886dc4e 100644 --- a/homeassistant/components/google/services.yaml +++ b/homeassistant/components/google/services.yaml @@ -2,3 +2,30 @@ found_calendar: description: Add calendar if it has not been already discovered. scan_for_calendars: description: Scan for new calendars. +add_event: + description: Add a new calendar event. + fields: + calendar_id: + description: The id of the calendar you want. + example: 'Your email' + summary: + description: Acts as the title of the event. + example: 'Bowling' + description: + description: The description of the event. Optional. + example: 'Birthday bowling' + start_date_time: + description: The date and time the event should start. + example: '2019-03-22 20:00:00' + end_date_time: + description: The date and time the event should end. + example: '2019-03-22 22:00:00' + start_date: + description: The date the whole day event should start. + example: '2019-03-10' + end_date: + description: The date the whole day event should end. + example: '2019-03-11' + in: + description: Days or weeks that you want to create the event in. + example: '"days": 2 or "weeks": 2' \ No newline at end of file