From 5c9a8a27c8289279316efc1f8a9f2e80833ce904 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 25 Aug 2020 14:23:21 +0200 Subject: [PATCH 1/4] Fix TTS languange characters (#39211) --- homeassistant/components/tts/__init__.py | 11 ++++++-- tests/components/tts/test_init.py | 35 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/tts/__init__.py b/homeassistant/components/tts/__init__.py index 39e4702e855..c7c0b986878 100644 --- a/homeassistant/components/tts/__init__.py +++ b/homeassistant/components/tts/__init__.py @@ -321,7 +321,9 @@ class SpeechManager: else: options_key = "-" - key = KEY_PATTERN.format(msg_hash, language, options_key, engine).lower() + key = KEY_PATTERN.format( + msg_hash, language.replace("_", "-"), options_key, engine + ).lower() # Is speech already in memory if key in self.mem_cache: @@ -352,9 +354,14 @@ class SpeechManager: # Create file infos filename = f"{key}.{extension}".lower() - data = self.write_tags(filename, data, provider, message, language, options) + # Validate filename + if not _RE_VOICE_FILE.match(filename): + raise HomeAssistantError( + f"TTS filename '{filename}' from {engine} is invalid!" + ) # Save to memory + data = self.write_tags(filename, data, provider, message, language, options) self._async_store_to_memcache(key, filename, data) if cache: diff --git a/tests/components/tts/test_init.py b/tests/components/tts/test_init.py index b4cb9c67af3..a100ef22c65 100644 --- a/tests/components/tts/test_init.py +++ b/tests/components/tts/test_init.py @@ -176,6 +176,41 @@ async def test_setup_component_and_test_service_with_config_language( ).is_file() +async def test_setup_component_and_test_service_with_config_language_special( + hass, empty_cache_dir +): + """Set up the demo platform and call service with extend language.""" + import homeassistant.components.demo.tts as demo_tts + + demo_tts.SUPPORT_LANGUAGES.append("en_US") + calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) + + config = {tts.DOMAIN: {"platform": "demo", "language": "en_US"}} + + with assert_setup_component(1, tts.DOMAIN): + assert await async_setup_component(hass, tts.DOMAIN, config) + + await hass.services.async_call( + tts.DOMAIN, + "demo_say", + { + "entity_id": "media_player.something", + tts.ATTR_MESSAGE: "There is someone at the door.", + }, + blocking=True, + ) + assert len(calls) == 1 + assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MEDIA_TYPE_MUSIC + assert ( + calls[0].data[ATTR_MEDIA_CONTENT_ID] + == "http://example.local:8123/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en-us_-_demo.mp3" + ) + await hass.async_block_till_done() + assert ( + empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en-us_-_demo.mp3" + ).is_file() + + async def test_setup_component_and_test_service_with_wrong_conf_language(hass): """Set up the demo platform and call service with wrong config.""" config = {tts.DOMAIN: {"platform": "demo", "language": "ru"}} From 9678cbdde20e9f879732836f3e9a8a2dd2a136a2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 26 Aug 2020 10:50:25 -0500 Subject: [PATCH 2/4] Fix time pattern listener firing a few microseconds early (#39281) --- homeassistant/helpers/event.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index 3f0c2db3b2f..be002a1b204 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -620,13 +620,19 @@ def async_track_utc_time_change( calculate_next(now + timedelta(seconds=1)) + # We always get time.time() first to avoid time.time() + # ticking forward after fetching hass.loop.time() + # and callback being scheduled a few microseconds early cancel_callback = hass.loop.call_at( - hass.loop.time() + next_time.timestamp() - time.time(), + -time.time() + hass.loop.time() + next_time.timestamp(), pattern_time_change_listener, ) + # We always get time.time() first to avoid time.time() + # ticking forward after fetching hass.loop.time() + # and callback being scheduled a few microseconds early cancel_callback = hass.loop.call_at( - hass.loop.time() + next_time.timestamp() - time.time(), + -time.time() + hass.loop.time() + next_time.timestamp(), pattern_time_change_listener, ) From 77107e4501d70a368ff2d333a90af6f39a42683b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 26 Aug 2020 15:52:05 +0000 Subject: [PATCH 3/4] Bumped version to 0.114.4 --- homeassistant/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 938e108d58b..9dd74f6709c 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 114 -PATCH_VERSION = "3" +PATCH_VERSION = "4" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 1) From 8fa1a1f600d6822646685058127690e8204fe8b9 Mon Sep 17 00:00:00 2001 From: Phil Bruckner Date: Sun, 9 Aug 2020 22:26:35 -0500 Subject: [PATCH 4/4] Fix async_fire_time_changed in tests/common.py (#38705) --- tests/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common.py b/tests/common.py index bcb66428f6b..16f349de800 100644 --- a/tests/common.py +++ b/tests/common.py @@ -295,8 +295,8 @@ def async_fire_time_changed(hass, datetime_, fire_all=False): if task.cancelled(): continue - future_seconds = task.when() - hass.loop.time() mock_seconds_into_future = datetime_.timestamp() - time.time() + future_seconds = task.when() - hass.loop.time() if fire_all or mock_seconds_into_future >= future_seconds: with patch(