hass-core/homeassistant/components/ios/notify.py
Tsvi Mostovicz 80136f3591 Change datetime.now() to dt_util.now() (#26582)
* Change datetime.now() to dt_util.now() in cases where the functionality should stay the same

These changes should not affect the functionality, rather cleanup our codebase.

In general we would like integrations to not to use datetime.now() unless there's a very good
reason for it, rather use our own dt_util.now() which makes the code aware of our current time
zone.

* Use datetime.utcnow() for season sensor to get offset-naive utc time

* Revert "Use datetime.utcnow() for season sensor to get offset-naive utc time"

This reverts commit 5f36463d9c7d52f8e11ffcec7e57dfbc7b21bdd1.

* BOM sensor last_updated should be UTC as well

* Run black

* Remove unused last_partition_update variable
2019-09-19 08:39:09 +02:00

111 lines
3.5 KiB
Python

"""Support for iOS push notifications."""
import logging
import requests
from homeassistant.components import ios
from homeassistant.components.notify import (
ATTR_DATA,
ATTR_MESSAGE,
ATTR_TARGET,
ATTR_TITLE,
ATTR_TITLE_DEFAULT,
BaseNotificationService,
)
import homeassistant.util.dt as dt_util
_LOGGER = logging.getLogger(__name__)
PUSH_URL = "https://ios-push.home-assistant.io/push"
# pylint: disable=invalid-name
def log_rate_limits(hass, target, resp, level=20):
"""Output rate limit log line at given level."""
rate_limits = resp["rateLimits"]
resetsAt = dt_util.parse_datetime(rate_limits["resetsAt"])
resetsAtTime = resetsAt - dt_util.utcnow()
rate_limit_msg = (
"iOS push notification rate limits for %s: "
"%d sent, %d allowed, %d errors, "
"resets in %s"
)
_LOGGER.log(
level,
rate_limit_msg,
ios.device_name_for_push_id(hass, target),
rate_limits["successful"],
rate_limits["maximum"],
rate_limits["errors"],
str(resetsAtTime).split(".")[0],
)
def get_service(hass, config, discovery_info=None):
"""Get the iOS notification service."""
if "notify.ios" not in hass.config.components:
# Need this to enable requirements checking in the app.
hass.config.components.add("notify.ios")
if not ios.devices_with_push(hass):
_LOGGER.error(
"The notify.ios platform was loaded but no "
"devices exist! Please check the documentation at "
"https://home-assistant.io/ecosystem/ios/notifications"
"/ for more information"
)
return None
return iOSNotificationService()
class iOSNotificationService(BaseNotificationService):
"""Implement the notification service for iOS."""
def __init__(self):
"""Initialize the service."""
@property
def targets(self):
"""Return a dictionary of registered targets."""
return ios.devices_with_push(self.hass)
def send_message(self, message="", **kwargs):
"""Send a message to the Lambda APNS gateway."""
data = {ATTR_MESSAGE: message}
if kwargs.get(ATTR_TITLE) is not None:
# Remove default title from notifications.
if kwargs.get(ATTR_TITLE) != ATTR_TITLE_DEFAULT:
data[ATTR_TITLE] = kwargs.get(ATTR_TITLE)
targets = kwargs.get(ATTR_TARGET)
if not targets:
targets = ios.enabled_push_ids(self.hass)
if kwargs.get(ATTR_DATA) is not None:
data[ATTR_DATA] = kwargs.get(ATTR_DATA)
for target in targets:
if target not in ios.enabled_push_ids(self.hass):
_LOGGER.error("The target (%s) does not exist in .ios.conf", targets)
return
data[ATTR_TARGET] = target
req = requests.post(PUSH_URL, json=data, timeout=10)
if req.status_code != 201:
fallback_error = req.json().get("errorMessage", "Unknown error")
fallback_message = (
"Internal server error, " "please try again later: " "{}"
).format(fallback_error)
message = req.json().get("message", fallback_message)
if req.status_code == 429:
_LOGGER.warning(message)
log_rate_limits(self.hass, target, req.json(), 30)
else:
_LOGGER.error(message)
else:
log_rate_limits(self.hass, target, req.json())