1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 12:59:34 +00:00

Add support for service translations (#95984)

This commit is contained in:
Franck Nijhof
2023-07-11 15:52:12 +02:00
committed by GitHub
parent f12f8bca03
commit f054de0ad5
7 changed files with 483 additions and 119 deletions

View File

@@ -1,6 +1,8 @@
"""Validate dependencies."""
from __future__ import annotations
import contextlib
import json
import pathlib
import re
from typing import Any
@@ -25,7 +27,7 @@ def exists(value: Any) -> Any:
FIELD_SCHEMA = vol.Schema(
{
vol.Required("description"): str,
vol.Optional("description"): str,
vol.Optional("name"): str,
vol.Optional("example"): exists,
vol.Optional("default"): exists,
@@ -46,7 +48,7 @@ FIELD_SCHEMA = vol.Schema(
SERVICE_SCHEMA = vol.Schema(
{
vol.Required("description"): str,
vol.Optional("description"): str,
vol.Optional("name"): str,
vol.Optional("target"): vol.Any(selector.TargetSelector.CONFIG_SCHEMA, None),
vol.Optional("fields"): vol.Schema({str: FIELD_SCHEMA}),
@@ -70,7 +72,7 @@ def grep_dir(path: pathlib.Path, glob_pattern: str, search_pattern: str) -> bool
return False
def validate_services(integration: Integration) -> None:
def validate_services(config: Config, integration: Integration) -> None:
"""Validate services."""
try:
data = load_yaml(str(integration.path / "services.yaml"))
@@ -92,15 +94,75 @@ def validate_services(integration: Integration) -> None:
return
try:
SERVICES_SCHEMA(data)
services = SERVICES_SCHEMA(data)
except vol.Invalid as err:
integration.add_error(
"services", f"Invalid services.yaml: {humanize_error(data, err)}"
)
# Try loading translation strings
if integration.core:
strings_file = integration.path / "strings.json"
else:
# For custom integrations, use the en.json file
strings_file = integration.path / "translations/en.json"
strings = {}
if strings_file.is_file():
with contextlib.suppress(ValueError):
strings = json.loads(strings_file.read_text())
# For each service in the integration, check if the description if set,
# if not, check if it's in the strings file. If not, add an error.
for service_name, service_schema in services.items():
if "name" not in service_schema:
try:
strings["services"][service_name]["name"]
except KeyError:
integration.add_error(
"services",
f"Service {service_name} has no name and is not in the translations file",
)
if "description" not in service_schema:
try:
strings["services"][service_name]["description"]
except KeyError:
integration.add_error(
"services",
f"Service {service_name} has no description and is not in the translations file",
)
# The same check is done for the description in each of the fields of the
# service schema.
for field_name, field_schema in service_schema.get("fields", {}).items():
if "description" not in field_schema:
try:
strings["services"][service_name]["fields"][field_name][
"description"
]
except KeyError:
integration.add_error(
"services",
f"Service {service_name} has a field {field_name} with no description and is not in the translations file",
)
if "selector" in field_schema:
with contextlib.suppress(KeyError):
translation_key = field_schema["selector"]["select"][
"translation_key"
]
try:
strings["selector"][translation_key]
except KeyError:
integration.add_error(
"services",
f"Service {service_name} has a field {field_name} with a selector with a translation key {translation_key} that is not in the translations file",
)
def validate(integrations: dict[str, Integration], config: Config) -> None:
"""Handle dependencies for integrations."""
# check services.yaml is cool
for integration in integrations.values():
validate_services(integration)
validate_services(config, integration)

View File

@@ -326,6 +326,20 @@ def gen_strings_schema(config: Config, integration: Integration) -> vol.Schema:
),
slug_validator=cv.slug,
),
vol.Optional("services"): cv.schema_with_slug_keys(
{
vol.Required("name"): translation_value_validator,
vol.Required("description"): translation_value_validator,
vol.Optional("fields"): cv.schema_with_slug_keys(
{
vol.Required("name"): str,
vol.Required("description"): translation_value_validator,
},
slug_validator=translation_key_validator,
),
},
slug_validator=translation_key_validator,
),
}
)