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
This commit is contained in:
Isabella Gross Alström 2019-06-02 22:58:27 +02:00 committed by Paulus Schoutsen
parent ca20b0cf17
commit fbfc674ca5
2 changed files with 135 additions and 5 deletions

View file

@ -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

View file

@ -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'