Mobile App: Support rendering multiple templates at once (#21851)
* Support rendering multiple templates at once * Only catch TemplateError and dont log the errorpull/22216/head
parent
b336322e9e
commit
c67113ad55
|
@ -43,7 +43,6 @@ ATTR_WEBHOOK_TYPE = 'type'
|
|||
|
||||
ERR_ENCRYPTION_REQUIRED = 'encryption_required'
|
||||
ERR_INVALID_COMPONENT = 'invalid_component'
|
||||
ERR_RENDER_FAILURE = 'render_failure'
|
||||
ERR_SAVE_FAILURE = 'save_failure'
|
||||
|
||||
WEBHOOK_TYPE_CALL_SERVICE = 'call_service'
|
||||
|
@ -99,8 +98,10 @@ FIRE_EVENT_SCHEMA = vol.Schema({
|
|||
})
|
||||
|
||||
RENDER_TEMPLATE_SCHEMA = vol.Schema({
|
||||
vol.Required(ATTR_TEMPLATE): cv.string,
|
||||
vol.Optional(ATTR_TEMPLATE_VARIABLES, default={}): dict,
|
||||
str: {
|
||||
vol.Required(ATTR_TEMPLATE): cv.template,
|
||||
vol.Optional(ATTR_TEMPLATE_VARIABLES, default={}): dict,
|
||||
}
|
||||
})
|
||||
|
||||
WEBHOOK_SCHEMAS = {
|
||||
|
|
|
@ -15,7 +15,7 @@ from homeassistant.const import (ATTR_DOMAIN, ATTR_SERVICE, ATTR_SERVICE_DATA,
|
|||
from homeassistant.core import EventOrigin
|
||||
from homeassistant.exceptions import (HomeAssistantError, ServiceNotFound,
|
||||
TemplateError)
|
||||
from homeassistant.helpers import template
|
||||
from homeassistant.helpers.template import attach
|
||||
from homeassistant.helpers.discovery import load_platform
|
||||
from homeassistant.helpers.storage import Store
|
||||
from homeassistant.helpers.typing import HomeAssistantType
|
||||
|
@ -26,10 +26,9 @@ from .const import (ATTR_APP_COMPONENT, ATTR_DEVICE_NAME, ATTR_EVENT_DATA,
|
|||
ATTR_WEBHOOK_ENCRYPTED, ATTR_WEBHOOK_ENCRYPTED_DATA,
|
||||
ATTR_WEBHOOK_TYPE, CONF_SECRET, DATA_DELETED_IDS,
|
||||
DATA_REGISTRATIONS, DOMAIN, ERR_ENCRYPTION_REQUIRED,
|
||||
ERR_RENDER_FAILURE, WEBHOOK_PAYLOAD_SCHEMA,
|
||||
WEBHOOK_SCHEMAS, WEBHOOK_TYPE_CALL_SERVICE,
|
||||
WEBHOOK_TYPE_FIRE_EVENT, WEBHOOK_TYPE_RENDER_TEMPLATE,
|
||||
WEBHOOK_TYPE_UPDATE_LOCATION,
|
||||
WEBHOOK_PAYLOAD_SCHEMA, WEBHOOK_SCHEMAS,
|
||||
WEBHOOK_TYPE_CALL_SERVICE, WEBHOOK_TYPE_FIRE_EVENT,
|
||||
WEBHOOK_TYPE_RENDER_TEMPLATE, WEBHOOK_TYPE_UPDATE_LOCATION,
|
||||
WEBHOOK_TYPE_UPDATE_REGISTRATION)
|
||||
|
||||
from .helpers import (_decrypt_payload, empty_okay_response, error_response,
|
||||
|
@ -132,17 +131,18 @@ async def handle_webhook(store: Store, hass: HomeAssistantType,
|
|||
return empty_okay_response(headers=headers)
|
||||
|
||||
if webhook_type == WEBHOOK_TYPE_RENDER_TEMPLATE:
|
||||
try:
|
||||
tpl = template.Template(data[ATTR_TEMPLATE], hass)
|
||||
rendered = tpl.async_render(data.get(ATTR_TEMPLATE_VARIABLES))
|
||||
return webhook_response({"rendered": rendered},
|
||||
registration=registration, headers=headers)
|
||||
# noqa: E722 pylint: disable=broad-except
|
||||
except (ValueError, TemplateError, Exception) as ex:
|
||||
_LOGGER.error("Error when rendering template during mobile_app "
|
||||
"webhook (device name: %s): %s",
|
||||
registration[ATTR_DEVICE_NAME], ex)
|
||||
return error_response(ERR_RENDER_FAILURE, str(ex), headers=headers)
|
||||
resp = {}
|
||||
for key, item in data.items():
|
||||
try:
|
||||
tpl = item[ATTR_TEMPLATE]
|
||||
attach(hass, tpl)
|
||||
resp[key] = tpl.async_render(item.get(ATTR_TEMPLATE_VARIABLES))
|
||||
# noqa: E722 pylint: disable=broad-except
|
||||
except TemplateError as ex:
|
||||
resp[key] = {"error": str(ex)}
|
||||
|
||||
return webhook_response(resp, registration=registration,
|
||||
headers=headers)
|
||||
|
||||
if webhook_type == WEBHOOK_TYPE_UPDATE_LOCATION:
|
||||
try:
|
||||
|
|
|
@ -49,7 +49,9 @@ REGISTER_CLEARTEXT = {
|
|||
RENDER_TEMPLATE = {
|
||||
'type': 'render_template',
|
||||
'data': {
|
||||
'template': 'Hello world'
|
||||
'one': {
|
||||
'template': 'Hello world'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import pytest
|
|||
from homeassistant.components.mobile_app.const import CONF_SECRET
|
||||
from homeassistant.const import CONF_WEBHOOK_ID
|
||||
|
||||
from .const import REGISTER
|
||||
from .const import REGISTER, RENDER_TEMPLATE
|
||||
from . import authed_api_client # noqa: F401
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ async def test_registration(hass_client, authed_api_client): # noqa: F811
|
|||
key = key[:keylen]
|
||||
key = key.ljust(keylen, b'\0')
|
||||
|
||||
payload = json.dumps({'template': 'Hello world'}).encode("utf-8")
|
||||
payload = json.dumps(RENDER_TEMPLATE['data']).encode("utf-8")
|
||||
|
||||
data = SecretBox(key).encrypt(payload,
|
||||
encoder=Base64Encoder).decode("utf-8")
|
||||
|
@ -62,7 +62,7 @@ async def test_registration(hass_client, authed_api_client): # noqa: F811
|
|||
encoder=Base64Encoder)
|
||||
decrypted_data = decrypted_data.decode("utf-8")
|
||||
|
||||
assert json.loads(decrypted_data) == {'rendered': 'Hello world'}
|
||||
assert json.loads(decrypted_data) == {'one': 'Hello world'}
|
||||
|
||||
|
||||
async def test_register_invalid_component(authed_api_client): # noqa: F811
|
||||
|
|
|
@ -24,7 +24,7 @@ async def test_webhook_handle_render_template(webhook_client): # noqa: F811
|
|||
assert resp.status == 200
|
||||
|
||||
json = await resp.json()
|
||||
assert json == {'rendered': 'Hello world'}
|
||||
assert json == {'one': 'Hello world'}
|
||||
|
||||
|
||||
async def test_webhook_handle_call_services(hass, webhook_client): # noqa: E501 F811
|
||||
|
@ -123,7 +123,7 @@ async def test_webhook_handle_decryption(webhook_client): # noqa: F811
|
|||
key = key[:keylen]
|
||||
key = key.ljust(keylen, b'\0')
|
||||
|
||||
payload = json.dumps({'template': 'Hello world'}).encode("utf-8")
|
||||
payload = json.dumps(RENDER_TEMPLATE['data']).encode("utf-8")
|
||||
|
||||
data = SecretBox(key).encrypt(payload,
|
||||
encoder=Base64Encoder).decode("utf-8")
|
||||
|
@ -148,7 +148,7 @@ async def test_webhook_handle_decryption(webhook_client): # noqa: F811
|
|||
encoder=Base64Encoder)
|
||||
decrypted_data = decrypted_data.decode("utf-8")
|
||||
|
||||
assert json.loads(decrypted_data) == {'rendered': 'Hello world'}
|
||||
assert json.loads(decrypted_data) == {'one': 'Hello world'}
|
||||
|
||||
|
||||
async def test_webhook_requires_encryption(webhook_client): # noqa: F811
|
||||
|
|
Loading…
Reference in New Issue