From eaa55951a2f694492bba1f47041b7ac528d93a1c Mon Sep 17 00:00:00 2001 From: Christopher Viel Date: Wed, 3 Jan 2018 13:46:30 -0500 Subject: [PATCH] Copy push subscriptions before passing them to pywebpush PyWebPush updates the subscription reference held by home assistant with a byte encoded value. This causes errors the next time we try to save html5_push_registrations.conf. As a workaround, I do a deepcopy of the registration dictionary before giving it to PyWebPush. --- homeassistant/components/notify/html5.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/notify/html5.py b/homeassistant/components/notify/html5.py index a979ab5fb2f5dd..f97a4ebb864cc9 100644 --- a/homeassistant/components/notify/html5.py +++ b/homeassistant/components/notify/html5.py @@ -5,6 +5,7 @@ https://home-assistant.io/components/notify.html5/ """ import asyncio +from copy import deepcopy import datetime import json import logging @@ -133,17 +134,6 @@ def _load_config(filename): return {} -class JSONBytesDecoder(json.JSONEncoder): - """JSONEncoder to decode bytes objects to unicode.""" - - # pylint: disable=method-hidden - def default(self, obj): - """Decode object if it's a bytes object, else defer to base class.""" - if isinstance(obj, bytes): - return obj.decode() - return json.JSONEncoder.default(self, obj) - - class HTML5PushRegistrationView(HomeAssistantView): """Accepts push registrations from a browser.""" @@ -408,8 +398,12 @@ def send_message(self, message="", **kwargs): jwt_token = jwt.encode(jwt_claims, jwt_secret).decode('utf-8') payload[ATTR_DATA][ATTR_JWT] = jwt_token - response = WebPusher(info[ATTR_SUBSCRIPTION]).send( - json.dumps(payload), gcm_key=self._gcm_key, ttl='86400') + # Deepcopy here because WebPusher alters our reference with byte() + # Remove deepcopy when pywebpush releases a new version (>1.4.0) + # See https://github.com/home-assistant/home-assistant/pull/11437 + subscription = deepcopy(info[ATTR_SUBSCRIPTION]) + response = WebPusher(subscription).send( + json.dumps(payload), gcm_key=self._gcm_key, ttl=86400) # pylint: disable=no-member if response.status_code == 410: