Add notify_events notify integration (#36049)

* Add new notify_events notification component

* Fix manifest

* Formatting fix

* Black formatting + CODEOWNERS

* Fix requirements_all.txt

* Flake8 warning fix

* Isort fixes

* Update notify-events library requirement version

* Replace Exception to more suitable and update lib version

* Reformat integration according to "0007-integration-config-yaml-structure.md"

* Update homeassistant/components/notify_events/manifest.json

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Fix manifest + remove async

* Black formatting

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Alexey Kustov
2020-06-05 23:26:56 +04:00
committed by GitHub
parent b51d81edba
commit 3076fc5f25
7 changed files with 155 additions and 0 deletions

View File

@ -538,6 +538,7 @@ omit =
homeassistant/components/notion/sensor.py
homeassistant/components/noaa_tides/sensor.py
homeassistant/components/norway_air/air_quality.py
homeassistant/components/notify_events/notify.py
homeassistant/components/nsw_fuel_station/sensor.py
homeassistant/components/nuimo_controller/*
homeassistant/components/nuki/lock.py

View File

@ -274,6 +274,7 @@ homeassistant/components/nissan_leaf/* @filcole
homeassistant/components/nmbs/* @thibmaek
homeassistant/components/no_ip/* @fabaff
homeassistant/components/notify/* @home-assistant/core
homeassistant/components/notify_events/* @matrozov @papajojo
homeassistant/components/notion/* @bachya
homeassistant/components/nsw_fuel_station/* @nickw444
homeassistant/components/nsw_rural_fire_service_feed/* @exxamalte

View File

@ -0,0 +1,20 @@
"""The notify_events component."""
import voluptuous as vol
from homeassistant.const import CONF_TOKEN
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
from .const import DOMAIN
CONFIG_SCHEMA = vol.Schema(
{DOMAIN: vol.Schema({vol.Required(CONF_TOKEN): cv.string})}, extra=vol.ALLOW_EXTRA
)
def setup(hass, config):
"""Set up the notify_events component."""
hass.data[DOMAIN] = config[DOMAIN]
discovery.load_platform(hass, "notify", DOMAIN, {}, config)
return True

View File

@ -0,0 +1,3 @@
"""Const for notify_events."""
DOMAIN = "notify_events"

View File

@ -0,0 +1,7 @@
{
"domain": "notify_events",
"name": "Notify.Events",
"documentation": "https://www.home-assistant.io/integrations/notify_events",
"codeowners": ["@matrozov", "@papajojo"],
"requirements": ["notify-events==1.0.4"]
}

View File

@ -0,0 +1,120 @@
"""Notify.Events platform for notify component."""
import logging
import os.path
from notify_events import Message
from homeassistant.components.notify import (
ATTR_DATA,
ATTR_TITLE,
BaseNotificationService,
)
from homeassistant.const import CONF_TOKEN
from .const import DOMAIN
ATTR_LEVEL = "level"
ATTR_PRIORITY = "priority"
ATTR_FILES = "files"
ATTR_IMAGES = "images"
ATTR_FILE_URL = "url"
ATTR_FILE_PATH = "path"
ATTR_FILE_CONTENT = "content"
ATTR_FILE_NAME = "name"
ATTR_FILE_MIME_TYPE = "mime_type"
ATTR_FILE_KIND_FILE = "file"
ATTR_FILE_KIND_IMAGE = "image"
_LOGGER = logging.getLogger(__name__)
def get_service(hass, config, discovery_info=None):
"""Get the Notify.Events notification service."""
return NotifyEventsNotificationService(hass.data[DOMAIN][CONF_TOKEN])
class NotifyEventsNotificationService(BaseNotificationService):
"""Implement the notification service for Notify.Events."""
def __init__(self, token):
"""Initialize the service."""
self.token = token
def file_exists(self, filename) -> bool:
"""Check if a file exists on disk and is in authorized path."""
if not self.hass.config.is_allowed_path(filename):
return False
return os.path.isfile(filename)
def attach_file(self, msg: Message, item: dict, kind: str = ATTR_FILE_KIND_FILE):
"""Append a file or image to message."""
file_name = None
mime_type = None
if ATTR_FILE_NAME in item:
file_name = item[ATTR_FILE_NAME]
if ATTR_FILE_MIME_TYPE in item:
mime_type = item[ATTR_FILE_MIME_TYPE]
if ATTR_FILE_URL in item:
if kind == ATTR_FILE_KIND_IMAGE:
msg.add_image_from_url(item[ATTR_FILE_URL], file_name, mime_type)
else:
msg.add_file_from_url(item[ATTR_FILE_URL], file_name, mime_type)
elif ATTR_FILE_CONTENT in item:
if kind == ATTR_FILE_KIND_IMAGE:
msg.add_image_from_content(
item[ATTR_FILE_CONTENT], file_name, mime_type
)
else:
msg.add_file_from_content(item[ATTR_FILE_CONTENT], file_name, mime_type)
elif ATTR_FILE_PATH in item:
file_exists = self.file_exists(item[ATTR_FILE_PATH])
if file_exists:
if kind == ATTR_FILE_KIND_IMAGE:
msg.add_image(item[ATTR_FILE_PATH], file_name, mime_type)
else:
msg.add_file(item[ATTR_FILE_PATH], file_name, mime_type)
else:
_LOGGER.error("File does not exist: %s", item[ATTR_FILE_PATH])
def prepare_message(self, message, data) -> Message:
"""Prepare a message to send."""
msg = Message(message)
if ATTR_TITLE in data:
msg.set_title(data[ATTR_TITLE])
if ATTR_LEVEL in data:
try:
msg.set_level(data[ATTR_LEVEL])
except ValueError as error:
_LOGGER.warning("Setting level error: %s", error)
if ATTR_PRIORITY in data:
try:
msg.set_priority(data[ATTR_PRIORITY])
except ValueError as error:
_LOGGER.warning("Setting priority error: %s", error)
if ATTR_IMAGES in data:
for image in data[ATTR_IMAGES]:
self.attach_file(msg, image, ATTR_FILE_KIND_IMAGE)
if ATTR_FILES in data:
for file in data[ATTR_FILES]:
self.attach_file(msg, file)
return msg
def send_message(self, message, **kwargs):
"""Send a message."""
data = kwargs.get(ATTR_DATA) or {}
msg = self.prepare_message(message, data)
msg.send(self.token)

View File

@ -963,6 +963,9 @@ niko-home-control==0.2.1
# homeassistant.components.nilu
niluclient==0.1.2
# homeassistant.components.notify_events
notify-events==1.0.4
# homeassistant.components.nederlandse_spoorwegen
nsapi==3.0.4