Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 39 additions & 37 deletions homeassistant/components/tts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ async def async_setup_platform(p_type, p_config=None, discovery_info=None):
hass, p_config, discovery_info
)
else:
provider = await hass.async_add_job(
provider = await hass.async_add_executor_job(
platform.get_engine, hass, p_config, discovery_info
)

Expand Down Expand Up @@ -226,41 +226,17 @@ async def async_init_cache(self, use_cache, cache_dir, time_memory, base_url):
self.time_memory = time_memory
self.base_url = base_url

def init_tts_cache_dir(cache_dir):
"""Init cache folder."""
if not os.path.isabs(cache_dir):
cache_dir = self.hass.config.path(cache_dir)
if not os.path.isdir(cache_dir):
_LOGGER.info("Create cache dir %s.", cache_dir)
os.mkdir(cache_dir)
return cache_dir

try:
self.cache_dir = await self.hass.async_add_job(
init_tts_cache_dir, cache_dir
self.cache_dir = await self.hass.async_add_executor_job(
_init_tts_cache_dir, self.hass, cache_dir
)
except OSError as err:
raise HomeAssistantError(f"Can't init cache dir {err}")

def get_cache_files():
"""Return a dict of given engine files."""
cache = {}

folder_data = os.listdir(self.cache_dir)
for file_data in folder_data:
record = _RE_VOICE_FILE.match(file_data)
if record:
key = KEY_PATTERN.format(
record.group(1),
record.group(2),
record.group(3),
record.group(4),
)
cache[key.lower()] = file_data.lower()
return cache

try:
cache_files = await self.hass.async_add_job(get_cache_files)
cache_files = await self.hass.async_add_executor_job(
_get_cache_files, self.cache_dir
)
except OSError as err:
raise HomeAssistantError(f"Can't read cache dir {err}")

Expand All @@ -273,13 +249,13 @@ async def async_clear_cache(self):

def remove_files():
"""Remove files from filesystem."""
for _, filename in self.file_cache.items():
for filename in self.file_cache.values():
try:
os.remove(os.path.join(self.cache_dir, filename))
except OSError as err:
_LOGGER.warning("Can't remove cache file '%s': %s", filename, err)

await self.hass.async_add_job(remove_files)
await self.hass.async_add_executor_job(remove_files)
self.file_cache = {}

@callback
Expand Down Expand Up @@ -312,6 +288,7 @@ async def async_get_url(
merged_options.update(options)
options = merged_options
options = options or provider.default_options

if options is not None:
invalid_opts = [
opt_name
Expand Down Expand Up @@ -378,10 +355,10 @@ def save_speech():
speech.write(data)

try:
await self.hass.async_add_job(save_speech)
await self.hass.async_add_executor_job(save_speech)
self.file_cache[key] = filename
except OSError:
_LOGGER.error("Can't write %s", filename)
except OSError as err:
_LOGGER.error("Can't write %s: %s", filename, err)

async def async_file_to_mem(self, key):
"""Load voice from file cache into memory.
Expand All @@ -400,7 +377,7 @@ def load_speech():
return speech.read()

try:
data = await self.hass.async_add_job(load_speech)
data = await self.hass.async_add_executor_job(load_speech)
except OSError:
del self.file_cache[key]
raise HomeAssistantError(f"Can't read {voice_file}")
Expand Down Expand Up @@ -506,11 +483,36 @@ async def async_get_tts_audio(self, message, language, options=None):

Return a tuple of file extension and data as bytes.
"""
return await self.hass.async_add_job(
return await self.hass.async_add_executor_job(
ft.partial(self.get_tts_audio, message, language, options=options)
)


def _init_tts_cache_dir(hass, cache_dir):
"""Init cache folder."""
if not os.path.isabs(cache_dir):
cache_dir = hass.config.path(cache_dir)
if not os.path.isdir(cache_dir):
_LOGGER.info("Create cache dir %s", cache_dir)
os.mkdir(cache_dir)
return cache_dir


def _get_cache_files(cache_dir):
"""Return a dict of given engine files."""
cache = {}

folder_data = os.listdir(cache_dir)
for file_data in folder_data:
record = _RE_VOICE_FILE.match(file_data)
if record:
key = KEY_PATTERN.format(
record.group(1), record.group(2), record.group(3), record.group(4),
)
cache[key.lower()] = file_data.lower()
return cache


class TextToSpeechUrlView(HomeAssistantView):
"""TTS view to get a url to a generated speech file."""

Expand Down
16 changes: 2 additions & 14 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from unittest.mock import MagicMock, Mock, patch
import uuid

from aiohttp.test_utils import unused_port as get_test_instance_port # noqa

from homeassistant import auth, config_entries, core as ha, loader
from homeassistant.auth import (
auth_store,
Expand All @@ -37,7 +39,6 @@
EVENT_PLATFORM_DISCOVERED,
EVENT_STATE_CHANGED,
EVENT_TIME_CHANGED,
SERVER_PORT,
STATE_OFF,
STATE_ON,
)
Expand All @@ -59,7 +60,6 @@
from homeassistant.util.unit_system import METRIC_SYSTEM
import homeassistant.util.yaml.loader as yaml_loader

_TEST_INSTANCE_PORT = SERVER_PORT
_LOGGER = logging.getLogger(__name__)
INSTANCES = []
CLIENT_ID = "https://example.com/app"
Expand Down Expand Up @@ -217,18 +217,6 @@ def clear_instance(event):
return hass


def get_test_instance_port():
"""Return unused port for running test instance.

The socket that holds the default port does not get released when we stop
HA in a different test case. Until I have figured out what is going on,
let's run each test on a different port.
"""
global _TEST_INSTANCE_PORT
_TEST_INSTANCE_PORT += 1
return _TEST_INSTANCE_PORT


def async_mock_service(hass, domain, service, schema=None):
"""Set up a fake service & return a calls log list to this service."""
calls = []
Expand Down
Loading