mirror of
https://github.com/home-assistant/core.git
synced 2026-09-29 16:18:13 +01:00
Guard for unnecessary translations and fix offenders (#183292)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"wrong_location": "[%key:component::airly::config::error::wrong_location%]"
|
||||
},
|
||||
"error": {
|
||||
|
||||
@@ -25,7 +25,7 @@ from homeassistant.config_entries import (
|
||||
ConfigFlowResult,
|
||||
)
|
||||
from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_PIN
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback
|
||||
from homeassistant.data_entry_flow import AbortFlow
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
@@ -289,7 +289,9 @@ class AppleTVConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
def _async_check_and_update_in_progress(self, host: str, unique_id: str) -> None:
|
||||
"""Check for in-progress flows and update them with identifiers if needed."""
|
||||
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||
raise AbortFlow("already_in_progress")
|
||||
raise AbortFlow(
|
||||
"already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
|
||||
@override
|
||||
def is_matching(self, other_flow: Self) -> bool:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"backoff": "Device does not accept pairing requests at this time (you might have entered an invalid PIN code too many times), try again later.",
|
||||
"device_did_not_pair": "No attempt to finish pairing process was made from the device.",
|
||||
"device_not_found": "Device was not found during discovery, please try adding it again.",
|
||||
|
||||
@@ -15,6 +15,7 @@ from homeassistant.components.bluetooth import (
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_ADDRESS
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
@@ -174,7 +175,9 @@ class BTHomeConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
return await self.async_step_get_encryption_key()
|
||||
|
||||
# Otherwise there wasn't actually encryption so abort
|
||||
return self.async_abort(reason="reauth_successful")
|
||||
return self.async_abort(
|
||||
reason="reauth_successful", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
|
||||
def _async_get_or_create_entry(
|
||||
self, bindkey: str | None = None
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
|
||||
},
|
||||
"error": {
|
||||
"decryption_failed": "The provided bindkey did not work, sensor data could not be decrypted. Please check it and try again.",
|
||||
|
||||
@@ -17,6 +17,7 @@ from homeassistant.const import (
|
||||
CONF_PROTOCOL,
|
||||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
@@ -192,7 +193,9 @@ class Elkm1ConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
return self.async_abort(reason="already_configured")
|
||||
self.host = host
|
||||
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
# Handled ignored case since _async_current_entries
|
||||
# is called with include_ignore=False
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"abort": {
|
||||
"address_already_configured": "An Elk-M1 with this address is already configured",
|
||||
"already_configured": "An Elk-M1 with this prefix is already configured",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||
"reconfigure_successful": "Successfully reconfigured Elk-M1 integration",
|
||||
|
||||
@@ -260,6 +260,7 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
if not errors:
|
||||
# successful authentication, update config
|
||||
# Shares the local string with the unique ID abort in async_step_user
|
||||
return self.async_update_reload_and_abort(
|
||||
reauth_entry,
|
||||
data_updates=user_input
|
||||
@@ -268,6 +269,7 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
if isinstance(envoy.auth, EnvoyTokenAuth)
|
||||
else {}
|
||||
),
|
||||
reason="reauth_successful",
|
||||
)
|
||||
if token:
|
||||
token_days_left = token_lifetime(token)
|
||||
|
||||
@@ -22,7 +22,7 @@ from homeassistant.config_entries import (
|
||||
OptionsFlow,
|
||||
)
|
||||
from homeassistant.const import CONF_DEVICE, CONF_HOST
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback
|
||||
from homeassistant.data_entry_flow import AbortFlow
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
@@ -156,7 +156,9 @@ class FluxLedConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
host = device[ATTR_IPADDR]
|
||||
self.host = host
|
||||
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
if not device[ATTR_MODEL_DESCRIPTION]:
|
||||
mac_address = device[ATTR_ID]
|
||||
assert mac_address is not None
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
|
||||
},
|
||||
"error": {
|
||||
|
||||
@@ -17,6 +17,7 @@ from homeassistant.const import (
|
||||
CONF_USERNAME,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
|
||||
from homeassistant.helpers.selector import (
|
||||
TextSelector,
|
||||
TextSelectorConfig,
|
||||
@@ -166,7 +167,9 @@ class FritzboxConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self._abort_if_unique_id_configured({CONF_HOST: self._url})
|
||||
|
||||
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
|
||||
# update old and user-configured config entries
|
||||
for entry in self._async_current_entries(include_ignore=False):
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"ignore_ip6_link_local": "IPv6 link local address is not supported.",
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
|
||||
"not_supported": "Connected to FRITZ!Box but it's unable to control Smart Home devices."
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
},
|
||||
"error": {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"device_not_supported": "This device is not supported",
|
||||
"invalid_discovery_parameters": "Invalid discovery parameters",
|
||||
"reauth_enable_api_successful": "Enabling API was successful",
|
||||
"reauth_successful": "Authorization successful",
|
||||
"unknown_error": "[%key:common::config_flow::error::unknown%]",
|
||||
"unsupported_api_version": "Detected unsupported API version",
|
||||
"wrong_device": "The configured device is not the same found on this IP address."
|
||||
|
||||
@@ -13,7 +13,7 @@ import probatio
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, FlowType
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback
|
||||
from homeassistant.helpers.selector import (
|
||||
SelectOptionDict,
|
||||
SelectSelector,
|
||||
@@ -88,7 +88,9 @@ class IZoneConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
request as part of start-up, and the import step itself will not be repeated.
|
||||
"""
|
||||
if self._async_in_progress(include_uninitialized=True):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
|
||||
try:
|
||||
await izone_discovery.async_ensure_discovery(self.hass)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"continue_setup": "Continue setting up the discovered iZone controller.",
|
||||
"discovery_failed": "Failed to start iZone discovery. Make sure your network is properly configured.",
|
||||
"discovery_started": "iZone discovery has started. Your controllers will appear as discovered devices under Settings \u003e Devices \u0026 services.",
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
},
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "This LibreNMS instance is already configured.",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
|
||||
"already_configured": "This LibreNMS instance is already configured."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
|
||||
"wrong_device": "The device at this address is not the one this entry was set up for."
|
||||
},
|
||||
"error": {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"unique_id_mismatch": "The authenticated Monarch Money account does not match the configured account."
|
||||
},
|
||||
"error": {
|
||||
|
||||
@@ -13,7 +13,7 @@ from homeassistant.config_entries import (
|
||||
OptionsFlowWithReload,
|
||||
)
|
||||
from homeassistant.const import CONF_IP_ADDRESS, CONF_MAC
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
from homeassistant.helpers.selector import SelectSelector, SelectSelectorConfig
|
||||
@@ -244,7 +244,10 @@ class NoboHubConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
# No-op: IP unchanged and the running integration already
|
||||
# proves it works. Skip the reload to avoid a needless
|
||||
# reconnect.
|
||||
return self.async_abort(reason="reconfigure_successful")
|
||||
return self.async_abort(
|
||||
reason="reconfigure_successful",
|
||||
translation_domain=HOMEASSISTANT_DOMAIN,
|
||||
)
|
||||
return self.async_update_reload_and_abort(
|
||||
reconfigure_entry,
|
||||
data_updates={CONF_IP_ADDRESS: new_ip},
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"cannot_discover": "Could not detect a Nobø Ecohub at the discovered IP address.",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
|
||||
"cannot_discover": "Could not detect a Nobø Ecohub at the discovered IP address."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect - check serial number",
|
||||
|
||||
@@ -26,7 +26,7 @@ from homeassistant.const import (
|
||||
CONF_PORT,
|
||||
CONF_TOKEN,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback
|
||||
from homeassistant.data_entry_flow import AbortFlow
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
@@ -489,7 +489,9 @@ class SamsungTVConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
@callback
|
||||
def _async_abort_if_host_already_in_progress(self) -> None:
|
||||
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||
raise AbortFlow("already_in_progress")
|
||||
raise AbortFlow(
|
||||
"already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
|
||||
@override
|
||||
def is_matching(self, other_flow: Self) -> bool:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"auth_missing": "Home Assistant is not authorized to connect to this Samsung TV. Check your TV's External Device Manager settings to authorize Home Assistant.",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"id_missing": "This Samsung device doesn't have a serial number to identify it.",
|
||||
|
||||
@@ -9,7 +9,7 @@ import probatio
|
||||
|
||||
from homeassistant.config_entries import ConfigEntryState, ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_MODEL, CONF_NAME
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
@@ -82,7 +82,9 @@ class SteamistConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
return self.async_abort(reason="already_configured")
|
||||
self.host = host
|
||||
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
if not device.name:
|
||||
discovery = await async_discover_device(self.hass, device.ipaddress)
|
||||
if not discovery:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
|
||||
"not_steamist_device": "Not a steamist device"
|
||||
|
||||
@@ -36,7 +36,7 @@ from homeassistant.const import (
|
||||
CONF_PORT,
|
||||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, callback
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||
@@ -793,7 +793,10 @@ class TPLinkConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self.hass.async_create_task(
|
||||
self._async_reload_requires_auth_entries(), eager_start=False
|
||||
)
|
||||
return self.async_abort(reason="reauth_successful")
|
||||
return self.async_abort(
|
||||
reason="reauth_successful",
|
||||
translation_domain=HOMEASSISTANT_DOMAIN,
|
||||
)
|
||||
|
||||
# Old config entries will not have these values.
|
||||
alias = entry_data.get(CONF_ALIAS) or "unknown"
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
|
||||
},
|
||||
"error": {
|
||||
"camera_creds": "You have to set both username and password",
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
"already_configured": "UniFi Network site is already configured",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"configuration_updated": "Configuration updated",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
|
||||
"unknown_site_id": "Previously configured UniFi Network site can no longer be found"
|
||||
},
|
||||
"error": {
|
||||
|
||||
@@ -23,6 +23,7 @@ from homeassistant.components.bluetooth import (
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_ADDRESS, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
|
||||
from homeassistant.data_entry_flow import AbortFlow
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
@@ -354,7 +355,9 @@ class XiaomiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
return await self.async_step_get_encryption_key_4_5_choose_method()
|
||||
|
||||
# Otherwise there wasn't actually encryption so abort
|
||||
return self.async_abort(reason="reauth_successful")
|
||||
return self.async_abort(
|
||||
reason="reauth_successful", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
|
||||
def _async_get_or_create_entry(
|
||||
self, bindkey: str | None = None
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"api_error": "Error while communicating with Mi API: {error_detail}",
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
|
||||
},
|
||||
"error": {
|
||||
"api_device_not_found": "The device was not found in your Mi account.",
|
||||
|
||||
@@ -30,7 +30,7 @@ from homeassistant.config_entries import (
|
||||
ConfigFlowResult,
|
||||
)
|
||||
from homeassistant.const import CONF_NAME, CONF_URL
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback
|
||||
from homeassistant.data_entry_flow import AbortFlow
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import selector
|
||||
@@ -468,7 +468,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
return await self.async_step_rf_region()
|
||||
if config_updates := self._addon_config_updates:
|
||||
if not self._async_acquire_addon_ownership():
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress",
|
||||
translation_domain=HOMEASSISTANT_DOMAIN,
|
||||
)
|
||||
# If we have updates to the add-on config,
|
||||
# set them before starting the add-on.
|
||||
self._addon_config_updates = {}
|
||||
@@ -634,7 +637,9 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
# at least for a short time.
|
||||
# Zeroconf flows never touch the add-on,
|
||||
# so an idle discovery prompt should not block USB discovery.
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
if current_config_entries := self._async_current_entries(include_ignore=False):
|
||||
self._reconfigure_config_entry = next(
|
||||
(
|
||||
@@ -785,7 +790,9 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
# prompt should not block the add-on discovery.
|
||||
if flow["context"].get("source") != SOURCE_ZEROCONF
|
||||
):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
|
||||
if discovery_info.slug != ADDON_SLUG:
|
||||
return self.async_abort(reason="not_zwave_js_addon")
|
||||
@@ -1270,7 +1277,9 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
|
||||
if not self._async_acquire_addon_ownership():
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress", translation_domain=HOMEASSISTANT_DOMAIN
|
||||
)
|
||||
|
||||
# Remaining prompts, e.g. for other discovered adapters,
|
||||
# are superseded by this migration.
|
||||
@@ -1477,7 +1486,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
}
|
||||
|
||||
if not self._async_acquire_addon_ownership():
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress",
|
||||
translation_domain=HOMEASSISTANT_DOMAIN,
|
||||
)
|
||||
|
||||
addon_config_updates = self._addon_config_updates | addon_config_updates
|
||||
self._addon_config_updates = {}
|
||||
@@ -1719,7 +1731,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
# Config entry already has correct config
|
||||
return self.async_abort(reason="already_configured")
|
||||
if not self._async_acquire_addon_ownership():
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress",
|
||||
translation_domain=HOMEASSISTANT_DOMAIN,
|
||||
)
|
||||
await self._addon_setup.async_set_addon_config(
|
||||
{CONF_ADDON_SOCKET: discovery_info.socket_path}
|
||||
)
|
||||
@@ -1741,7 +1756,10 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
flow["context"].get("unique_id") == placeholder_unique_id
|
||||
for flow in self._async_in_progress()
|
||||
):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
return self.async_abort(
|
||||
reason="already_in_progress",
|
||||
translation_domain=HOMEASSISTANT_DOMAIN,
|
||||
)
|
||||
# We are not aborting if home ID configured
|
||||
# here, we just want to make sure that it's set
|
||||
# We will update a USB based config entry
|
||||
|
||||
@@ -104,7 +104,6 @@
|
||||
"addon_start_failed": "Failed to start the Z-Wave JS app.",
|
||||
"addon_stop_failed": "Failed to stop the Z-Wave JS app.",
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"backup_failed": "Failed to back up network.",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"config_entry_not_loaded": "The Z-Wave configuration entry is not loaded. Please try again when the configuration entry is loaded.",
|
||||
|
||||
@@ -60,6 +60,7 @@ from homeassistant.components import repairs
|
||||
from homeassistant.config_entries import (
|
||||
DISCOVERY_SOURCES,
|
||||
ConfigEntriesFlowManager,
|
||||
ConfigSubentryFlowManager,
|
||||
FlowResult,
|
||||
OptionsFlowManager,
|
||||
)
|
||||
@@ -1013,6 +1014,45 @@ async def _validate_translation(
|
||||
)
|
||||
|
||||
|
||||
async def _validate_abort_translation_not_duplicated(
|
||||
hass: HomeAssistant,
|
||||
translation_errors: dict[str, str],
|
||||
ignore_translations_for_mock_domains: set[str],
|
||||
category: str,
|
||||
component: str,
|
||||
translation_domain: str,
|
||||
key: str,
|
||||
*,
|
||||
shared_category: str | None = None,
|
||||
shared_key: str | None = None,
|
||||
) -> None:
|
||||
"""Raise if an integration duplicates an abort translated by another domain.
|
||||
|
||||
A local translation with different wording is kept, since the integration
|
||||
may raise the same reason itself to show its own wording.
|
||||
"""
|
||||
if component in ignore_translations_for_mock_domains:
|
||||
return
|
||||
full_key = f"component.{component}.{category}.{key}"
|
||||
translations = await async_get_translations(hass, "en", category, [component])
|
||||
if (translation := translations.get(full_key)) is None:
|
||||
return
|
||||
shared_category = shared_category or category
|
||||
shared_translations = await async_get_translations(
|
||||
hass, "en", shared_category, [translation_domain]
|
||||
)
|
||||
if translation == shared_translations.get(
|
||||
f"component.{translation_domain}.{shared_category}.{shared_key or key}"
|
||||
):
|
||||
translation_errors[full_key] = (
|
||||
f"Translation `{category}.{key}` of {component} duplicates the one of "
|
||||
f"{translation_domain}, which translates this abort. Please remove it "
|
||||
f"from homeassistant/components/{component}/strings.json and pass "
|
||||
f'translation_domain="{translation_domain}" wherever {component} '
|
||||
"raises this reason itself"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ignore_missing_translations() -> str | list[str]:
|
||||
"""Ignore specific missing translations.
|
||||
@@ -1147,6 +1187,27 @@ async def _check_config_flow_result_translations(
|
||||
**(issue.translation_placeholders or {}),
|
||||
**(description_placeholders or {}),
|
||||
}
|
||||
elif isinstance(manager, ConfigSubentryFlowManager):
|
||||
# Subentry flows are only checked for duplicated shared abort translations
|
||||
if (
|
||||
result["type"] is FlowResultType.ABORT
|
||||
and (abort_domain := result.get("translation_domain")) is not None
|
||||
and (entry := flow.hass.config_entries.async_get_entry(flow.handler[0]))
|
||||
and abort_domain != entry.domain
|
||||
):
|
||||
# The frontend resolves a shared subentry abort from the config section
|
||||
await _validate_abort_translation_not_duplicated(
|
||||
flow.hass,
|
||||
translation_errors,
|
||||
ignore_translations_for_mock_domains,
|
||||
"config_subentries",
|
||||
entry.domain,
|
||||
abort_domain,
|
||||
f"{flow.handler[1]}.abort.{result['reason']}",
|
||||
shared_category="config",
|
||||
shared_key=f"abort.{result['reason']}",
|
||||
)
|
||||
return
|
||||
else:
|
||||
return
|
||||
|
||||
@@ -1181,11 +1242,22 @@ async def _check_config_flow_result_translations(
|
||||
return
|
||||
|
||||
if result["type"] is FlowResultType.ABORT:
|
||||
abort_domain = result.get("translation_domain")
|
||||
if abort_domain is not None and abort_domain != integration:
|
||||
await _validate_abort_translation_not_duplicated(
|
||||
flow.hass,
|
||||
translation_errors,
|
||||
ignore_translations_for_mock_domains,
|
||||
category,
|
||||
integration,
|
||||
abort_domain,
|
||||
f"{key_prefix}abort.{result['reason']}",
|
||||
)
|
||||
# We don't need translations for a discovery flow which immediately
|
||||
# aborts, since such flows won't be seen by users
|
||||
if not flow.__flow_seen_before and flow.source in DISCOVERY_SOURCES:
|
||||
return
|
||||
if (abort_domain := result.get("translation_domain")) is not None:
|
||||
if abort_domain is not None:
|
||||
integration = abort_domain
|
||||
await _validate_translation(
|
||||
flow.hass,
|
||||
@@ -1330,6 +1402,8 @@ async def check_translations(
|
||||
|
||||
Current checks:
|
||||
- data entry flow results (ConfigFlow/OptionsFlow/RepairFlow)
|
||||
- data entry flow aborts translated by another domain are not duplicated locally
|
||||
(also for ConfigSubentryFlow)
|
||||
- issue registry entries
|
||||
- action (service) exceptions
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user