Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion homeassistant/components/pushover/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"domain": "pushover",
"name": "Pushover",
"documentation": "https://www.home-assistant.io/integrations/pushover",
"requirements": ["python-pushover==0.4"],
"requirements": ["pushover_complete==1.1.1"],
"dependencies": [],
"codeowners": []
}
114 changes: 58 additions & 56 deletions homeassistant/components/pushover/notify.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""Pushover platform for notify component."""
import logging

from pushover import Client, InitError, RequestError
import requests
from pushover_complete import PushoverAPI
import voluptuous as vol

from homeassistant.components.notify import (
Expand All @@ -19,6 +18,15 @@
_LOGGER = logging.getLogger(__name__)

ATTR_ATTACHMENT = "attachment"
ATTR_URL = "url"
ATTR_URL_TITLE = "url_title"
ATTR_PRIORITY = "priority"
ATTR_RETRY = "retry"
ATTR_SOUND = "sound"
ATTR_HTML = "html"
ATTR_CALLBACK_URL = "callback_url"
ATTR_EXPIRE = "expire"
ATTR_TIMESTAMP = "timestamp"

CONF_USER_KEY = "user_key"

Expand All @@ -29,13 +37,9 @@

def get_service(hass, config, discovery_info=None):
"""Get the Pushover notification service."""
try:
return PushoverNotificationService(
hass, config[CONF_USER_KEY], config[CONF_API_KEY]
)
except InitError:
_LOGGER.error("Wrong API key supplied")
return None
return PushoverNotificationService(
hass, config[CONF_USER_KEY], config[CONF_API_KEY]
)


class PushoverNotificationService(BaseNotificationService):
Expand All @@ -46,67 +50,65 @@ def __init__(self, hass, user_key, api_token):
self._hass = hass
self._user_key = user_key
self._api_token = api_token
self.pushover = Client(self._user_key, api_token=self._api_token)
self.pushover = PushoverAPI(self._api_token)

def send_message(self, message="", **kwargs):
"""Send a message to a user."""
# Make a copy and use empty dict if necessary
data = dict(kwargs.get(ATTR_DATA) or {})

data["title"] = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT)

# Check for attachment.
if ATTR_ATTACHMENT in data:
# If attachment is a URL, use requests to open it as a stream.
if data[ATTR_ATTACHMENT].startswith("http"):
# Extract params from data dict
title = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT)
data = dict(kwargs.get(ATTR_DATA) or {})
url = data.get(ATTR_URL, None)
url_title = data.get(ATTR_URL_TITLE, None)
priority = data.get(ATTR_PRIORITY, None)
retry = data.get(ATTR_PRIORITY, None)
expire = data.get(ATTR_EXPIRE, None)
callback_url = data.get(ATTR_CALLBACK_URL, None)
timestamp = data.get(ATTR_TIMESTAMP, None)
sound = data.get(ATTR_SOUND, None)
html = 1 if data.get(ATTR_HTML, False) else 0

image = data.get(ATTR_ATTACHMENT, None)
# Check for attachment
if image is not None:
# Only allow attachments from whitelisted paths, check valid path
if self._hass.config.is_allowed_path(data[ATTR_ATTACHMENT]):
# try to open it as a normal file.
try:
response = requests.get(
data[ATTR_ATTACHMENT], stream=True, timeout=5
)
if response.status_code == 200:
# Replace the attachment identifier with file object.
data[ATTR_ATTACHMENT] = response.content
else:
_LOGGER.error(
"Failed to download image %s, response code: %d",
data[ATTR_ATTACHMENT],
response.status_code,
)
# Remove attachment key to send without attachment.
del data[ATTR_ATTACHMENT]
except requests.exceptions.RequestException as ex_val:
file_handle = open(data[ATTR_ATTACHMENT], "rb")
# Replace the attachment identifier with file object.
image = file_handle
except OSError as ex_val:
_LOGGER.error(ex_val)
# Remove attachment key to try sending without attachment
del data[ATTR_ATTACHMENT]
else:
# Not a URL, check valid path first
if self._hass.config.is_allowed_path(data[ATTR_ATTACHMENT]):
# try to open it as a normal file.
try:
file_handle = open(data[ATTR_ATTACHMENT], "rb")
# Replace the attachment identifier with file object.
data[ATTR_ATTACHMENT] = file_handle
except OSError as ex_val:
_LOGGER.error(ex_val)
# Remove attachment key to send without attachment.
del data[ATTR_ATTACHMENT]
else:
_LOGGER.error("Path is not whitelisted")
# Remove attachment key to send without attachment.
del data[ATTR_ATTACHMENT]
image = None
else:
_LOGGER.error("Path is not whitelisted")
# Remove attachment key to send without attachment.
image = None

targets = kwargs.get(ATTR_TARGET)

if not isinstance(targets, list):
targets = [targets]

for target in targets:
if target is not None:
data["device"] = target

try:
self.pushover.send_message(message, **data)
self.pushover.send_message(
self._user_key,
message,
target,
title,
url,
url_title,
image,
priority,
retry,
expire,
callback_url,
timestamp,
sound,
html,
)
except ValueError as val_err:
_LOGGER.error(val_err)
except RequestError:
_LOGGER.exception("Could not send pushover notification")
6 changes: 3 additions & 3 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,9 @@ pushbullet.py==0.11.0
# homeassistant.components.pushetta
pushetta==1.0.15

# homeassistant.components.pushover
pushover_complete==1.1.1

# homeassistant.components.rpi_gpio_pwm
pwmled==1.4.1

Expand Down Expand Up @@ -1605,9 +1608,6 @@ python-nest==4.1.0
# homeassistant.components.nmap_tracker
python-nmap==0.6.1

# homeassistant.components.pushover
python-pushover==0.4

# homeassistant.components.qbittorrent
python-qbittorrent==0.4.1

Expand Down