From b254218dd6e4380f3ac80caa177cfccc0ae9291d Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 21 Jun 2023 11:20:33 +0200 Subject: [PATCH] Remove `base_url` configuration option from `tts` (#94905) --- homeassistant/components/cast/media_player.py | 10 ----- homeassistant/components/tts/__init__.py | 22 +--------- homeassistant/components/tts/const.py | 1 - homeassistant/components/tts/legacy.py | 14 ------- homeassistant/components/tts/media_source.py | 4 -- tests/components/cast/test_media_player.py | 31 +------------- tests/components/tts/test_init.py | 41 ------------------- tests/components/tts/test_legacy.py | 33 +-------------- 8 files changed, 5 insertions(+), 151 deletions(-) diff --git a/homeassistant/components/cast/media_player.py b/homeassistant/components/cast/media_player.py index ee3834e4edd..d32ff07c261 100644 --- a/homeassistant/components/cast/media_player.py +++ b/homeassistant/components/cast/media_player.py @@ -362,15 +362,7 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity): ): external_url = None internal_url = None - tts_base_url = None url_description = "" - if "tts" in self.hass.config.components: - # pylint: disable-next=[import-outside-toplevel] - from homeassistant.components import tts - - with suppress(KeyError): # base_url not configured - tts_base_url = tts.get_base_url(self.hass) - with suppress(NoURLAvailableError): # external_url not configured external_url = get_url(self.hass, allow_internal=False) @@ -378,8 +370,6 @@ class CastMediaPlayerEntity(CastDevice, MediaPlayerEntity): internal_url = get_url(self.hass, allow_external=False) if media_status.content_id: - if tts_base_url and media_status.content_id.startswith(tts_base_url): - url_description = f" from tts.base_url ({tts_base_url})" if external_url and media_status.content_id.startswith(external_url): url_description = f" from external_url ({external_url})" if internal_url and media_status.content_id.startswith(internal_url): diff --git a/homeassistant/components/tts/__init__.py b/homeassistant/components/tts/__init__.py index 8ee1b67020a..4402722e37f 100644 --- a/homeassistant/components/tts/__init__.py +++ b/homeassistant/components/tts/__init__.py @@ -52,7 +52,6 @@ from .const import ( ATTR_LANGUAGE, ATTR_MESSAGE, ATTR_OPTIONS, - CONF_BASE_URL, CONF_CACHE, CONF_CACHE_DIR, CONF_TIME_MEMORY, @@ -76,7 +75,6 @@ __all__ = [ "CONF_LANG", "DEFAULT_CACHE_DIR", "generate_media_source_id", - "get_base_url", "PLATFORM_SCHEMA_BASE", "PLATFORM_SCHEMA", "Provider", @@ -93,8 +91,6 @@ ATTR_VOICE = "voice" CONF_LANG = "language" -BASE_URL_KEY = "tts_base_url" - SERVICE_CLEAR_CACHE = "clear_cache" _RE_LEGACY_VOICE_FILE = re.compile( @@ -214,15 +210,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: use_cache: bool = conf.get(CONF_CACHE, DEFAULT_CACHE) cache_dir: str = conf.get(CONF_CACHE_DIR, DEFAULT_CACHE_DIR) time_memory: int = conf.get(CONF_TIME_MEMORY, DEFAULT_TIME_MEMORY) - base_url: str | None = conf.get(CONF_BASE_URL) - if base_url is not None: - _LOGGER.warning( - "TTS base_url option is deprecated. Configure internal/external URL" - " instead" - ) - hass.data[BASE_URL_KEY] = base_url - tts = SpeechManager(hass, use_cache, cache_dir, time_memory, base_url) + tts = SpeechManager(hass, use_cache, cache_dir, time_memory) try: await tts.async_init_cache() @@ -413,7 +402,6 @@ class SpeechManager: use_cache: bool, cache_dir: str, time_memory: int, - base_url: str | None, ) -> None: """Initialize a speech store.""" self.hass = hass @@ -422,7 +410,6 @@ class SpeechManager: self.use_cache = use_cache self.cache_dir = cache_dir self.time_memory = time_memory - self.base_url = base_url self.file_cache: dict[str, str] = {} self.mem_cache: dict[str, TTSCache] = {} @@ -886,7 +873,7 @@ class TextToSpeechUrlView(HomeAssistantView): _LOGGER.error("Error on init tts: %s", err) return self.json({"error": err}, HTTPStatus.BAD_REQUEST) - base = self.tts.base_url or get_url(self.tts.hass) + base = get_url(self.tts.hass) url = base + path return self.json({"url": url, "path": path}) @@ -914,11 +901,6 @@ class TextToSpeechView(HomeAssistantView): return web.Response(body=data, content_type=content) -def get_base_url(hass: HomeAssistant) -> str: - """Get base URL.""" - return hass.data[BASE_URL_KEY] or get_url(hass) - - @websocket_api.websocket_command( { "type": "tts/engine/list", diff --git a/homeassistant/components/tts/const.py b/homeassistant/components/tts/const.py index 3427b761fa6..f721731330c 100644 --- a/homeassistant/components/tts/const.py +++ b/homeassistant/components/tts/const.py @@ -4,7 +4,6 @@ ATTR_LANGUAGE = "language" ATTR_MESSAGE = "message" ATTR_OPTIONS = "options" -CONF_BASE_URL = "base_url" CONF_CACHE = "cache" CONF_CACHE_DIR = "cache_dir" CONF_FIELDS = "fields" diff --git a/homeassistant/components/tts/legacy.py b/homeassistant/components/tts/legacy.py index 619c9374622..4734c3f22d1 100644 --- a/homeassistant/components/tts/legacy.py +++ b/homeassistant/components/tts/legacy.py @@ -9,7 +9,6 @@ from pathlib import Path from typing import TYPE_CHECKING, Any, cast import voluptuous as vol -import yarl from homeassistant.components.media_player import ( ATTR_MEDIA_ANNOUNCE, @@ -31,7 +30,6 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.service import async_set_service_schema from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.setup import async_prepare_setup_platform -from homeassistant.util.network import normalize_url from homeassistant.util.yaml import load_yaml from .const import ( @@ -39,7 +37,6 @@ from .const import ( ATTR_LANGUAGE, ATTR_MESSAGE, ATTR_OPTIONS, - CONF_BASE_URL, CONF_CACHE, CONF_CACHE_DIR, CONF_FIELDS, @@ -72,16 +69,6 @@ def _deprecated_platform(value: str) -> str: return value -def _valid_base_url(value: str) -> str: - """Validate base url, return value.""" - url = yarl.URL(cv.url(value)) - - if url.path != "/": - raise vol.Invalid("Path should be empty") - - return normalize_url(value) - - PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend( { vol.Required(CONF_PLATFORM): vol.All(cv.string, _deprecated_platform), @@ -90,7 +77,6 @@ PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend( vol.Optional(CONF_TIME_MEMORY, default=DEFAULT_TIME_MEMORY): vol.All( vol.Coerce(int), vol.Range(min=60, max=57600) ), - vol.Optional(CONF_BASE_URL): _valid_base_url, vol.Optional(CONF_SERVICE_NAME): cv.string, } ) diff --git a/homeassistant/components/tts/media_source.py b/homeassistant/components/tts/media_source.py index d371d457dde..837a15a4f88 100644 --- a/homeassistant/components/tts/media_source.py +++ b/homeassistant/components/tts/media_source.py @@ -18,7 +18,6 @@ from homeassistant.components.media_source import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_component import EntityComponent -from homeassistant.helpers.network import get_url from .const import DATA_TTS_MANAGER, DOMAIN from .helper import get_engine_instance @@ -124,9 +123,6 @@ class TTSMediaSource(MediaSource): mime_type = mimetypes.guess_type(url)[0] or "audio/mpeg" - if manager.base_url and manager.base_url != get_url(self.hass): - url = f"{manager.base_url}{url}" - return PlayMedia(url, mime_type) async def async_browse_media( diff --git a/tests/components/cast/test_media_player.py b/tests/components/cast/test_media_player.py index f290754d6fa..6f7a13b47af 100644 --- a/tests/components/cast/test_media_player.py +++ b/tests/components/cast/test_media_player.py @@ -1894,7 +1894,7 @@ async def test_failed_cast_other_url( assert await async_setup_component( hass, tts.DOMAIN, - {tts.DOMAIN: {"platform": "demo", "base_url": "http://example.local:8123"}}, + {tts.DOMAIN: {"platform": "demo"}}, ) info = get_fake_chromecast_info() @@ -1951,7 +1951,7 @@ async def test_failed_cast_external_url( assert await async_setup_component( hass, tts.DOMAIN, - {tts.DOMAIN: {"platform": "demo", "base_url": "http://example.com:8123"}}, + {tts.DOMAIN: {"platform": "demo"}}, ) info = get_fake_chromecast_info() @@ -1969,33 +1969,6 @@ async def test_failed_cast_external_url( ) -async def test_failed_cast_tts_base_url( - hass: HomeAssistant, caplog: pytest.LogCaptureFixture -) -> None: - """Test warning when casting from tts.base_url fails.""" - await async_setup_component(hass, "homeassistant", {}) - with assert_setup_component(1, tts.DOMAIN): - assert await async_setup_component( - hass, - tts.DOMAIN, - {tts.DOMAIN: {"platform": "demo", "base_url": "http://example.local:8123"}}, - ) - - info = get_fake_chromecast_info() - chromecast, _ = await async_setup_media_player_cast(hass, info) - _, _, media_status_cb = get_status_callbacks(chromecast) - - media_status = MagicMock(images=None) - media_status.player_is_idle = True - media_status.idle_reason = "ERROR" - media_status.content_id = "http://example.local:8123/tts.mp3" - media_status_cb(media_status) - assert ( - "Failed to cast media http://example.local:8123/tts.mp3 from tts.base_url" - in caplog.text - ) - - async def test_disconnect_on_stop(hass: HomeAssistant) -> None: """Test cast device disconnects socket on stop.""" info = get_fake_chromecast_info() diff --git a/tests/components/tts/test_init.py b/tests/components/tts/test_init.py index cedc4c7cae9..2656beba236 100644 --- a/tests/components/tts/test_init.py +++ b/tests/components/tts/test_init.py @@ -5,7 +5,6 @@ from typing import Any from unittest.mock import MagicMock, patch import pytest -import voluptuous as vol from homeassistant.components import tts from homeassistant.components.media_player import ( @@ -17,7 +16,6 @@ from homeassistant.components.media_player import ( MediaType, ) from homeassistant.components.media_source import Unresolvable -from homeassistant.components.tts.legacy import _valid_base_url from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN from homeassistant.core import HomeAssistant, State @@ -25,7 +23,6 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.typing import UNDEFINED from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util -from homeassistant.util.network import normalize_url from .common import ( DEFAULT_LANG, @@ -1315,44 +1312,6 @@ async def test_tags_with_wave() -> None: assert tagged_data != tts_data -@pytest.mark.parametrize( - "value", - ( - "http://example.local:8123", - "http://example.local", - "http://example.local:80", - "https://example.com", - "https://example.com:443", - "https://example.com:8123", - ), -) -def test_valid_base_url(value) -> None: - """Test we validate base urls.""" - assert _valid_base_url(value) == normalize_url(value) - # Test we strip trailing `/` - assert _valid_base_url(value + "/") == normalize_url(value) - - -@pytest.mark.parametrize( - "value", - ( - "http://example.local:8123/sub-path", - "http://example.local/sub-path", - "https://example.com/sub-path", - "https://example.com:8123/sub-path", - "mailto:some@email", - "http:example.com", - "http:/example.com", - "http//example.com", - "example.com", - ), -) -def test_invalid_base_url(value) -> None: - """Test we catch bad base urls.""" - with pytest.raises(vol.Invalid): - _valid_base_url(value) - - @pytest.mark.parametrize( ("setup", "result_engine"), [ diff --git a/tests/components/tts/test_legacy.py b/tests/components/tts/test_legacy.py index 26b7c2397b4..5a8321e2ae4 100644 --- a/tests/components/tts/test_legacy.py +++ b/tests/components/tts/test_legacy.py @@ -4,11 +4,8 @@ from __future__ import annotations import pytest from homeassistant.components.media_player import ( - ATTR_MEDIA_CONTENT_ID, - ATTR_MEDIA_CONTENT_TYPE, DOMAIN as DOMAIN_MP, SERVICE_PLAY_MEDIA, - MediaType, ) from homeassistant.components.tts import ATTR_MESSAGE, DOMAIN, Provider from homeassistant.const import ATTR_ENTITY_ID @@ -17,7 +14,7 @@ from homeassistant.helpers.discovery import async_load_platform from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.setup import async_setup_component -from .common import SUPPORT_LANGUAGES, MockProvider, MockTTS, get_media_source_url +from .common import SUPPORT_LANGUAGES, MockProvider, MockTTS from tests.common import ( MockModule, @@ -140,34 +137,6 @@ async def test_platform_setup_with_error( assert "Error setting up platform: bad_tts" in caplog.text -async def test_service_base_url_set(hass: HomeAssistant, mock_tts) -> None: - """Set up a TTS platform with ``base_url`` set and call service.""" - calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) - - config = {DOMAIN: {"platform": "test", "base_url": "http://fnord"}} - - with assert_setup_component(1, DOMAIN): - assert await async_setup_component(hass, DOMAIN, config) - - await hass.services.async_call( - DOMAIN, - "test_say", - { - ATTR_ENTITY_ID: "media_player.something", - ATTR_MESSAGE: "There is someone at the door.", - }, - blocking=True, - ) - assert len(calls) == 1 - assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC - assert ( - await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]) - == "http://fnord" - "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491" - "_en-us_-_test.mp3" - ) - - async def test_service_without_cache_config( hass: HomeAssistant, mock_tts_cache_dir, mock_tts ) -> None: