diff --git a/homeassistant/components/sql/strings.json b/homeassistant/components/sql/strings.json index cbc0deda96a..1aa683acd0b 100644 --- a/homeassistant/components/sql/strings.json +++ b/homeassistant/components/sql/strings.json @@ -38,35 +38,11 @@ "options": { "step": { "init": { - "data": { - "db_url": "[%key:component::sql::config::step::user::data::db_url%]", - "name": "[%key:common::config_flow::data::name%]", - "query": "[%key:component::sql::config::step::user::data::query%]", - "column": "[%key:component::sql::config::step::user::data::column%]", - "unit_of_measurement": "[%key:component::sql::config::step::user::data::unit_of_measurement%]", - "value_template": "[%key:component::sql::config::step::user::data::value_template%]", - "device_class": "[%key:component::sql::config::step::user::data::device_class%]", - "state_class": "[%key:component::sql::config::step::user::data::state_class%]" - }, - "data_description": { - "db_url": "[%key:component::sql::config::step::user::data_description::db_url%]", - "name": "[%key:component::sql::config::step::user::data_description::name%]", - "query": "[%key:component::sql::config::step::user::data_description::query%]", - "column": "[%key:component::sql::config::step::user::data_description::column%]", - "unit_of_measurement": "[%key:component::sql::config::step::user::data_description::unit_of_measurement%]", - "value_template": "[%key:component::sql::config::step::user::data_description::value_template%]", - "device_class": "[%key:component::sql::config::step::user::data_description::device_class%]", - "state_class": "[%key:component::sql::config::step::user::data_description::state_class%]" - } + "data": "[%dict:component::sql::config::step::user::data%]", + "data_description": "[%dict:component::sql::config::step::user::data_description%]" } }, - "error": { - "db_url_invalid": "[%key:component::sql::config::error::db_url_invalid%]", - "query_invalid": "[%key:component::sql::config::error::query_invalid%]", - "query_no_read_only": "[%key:component::sql::config::error::query_no_read_only%]", - "multiple_queries": "[%key:component::sql::config::error::multiple_queries%]", - "column_invalid": "[%key:component::sql::config::error::column_invalid%]" - } + "error": "[%dict:component::sql::config::error%]" }, "selector": { "device_class": { @@ -130,14 +106,7 @@ "wind_speed": "[%key:component::sensor::entity_component::wind_speed::name%]" } }, - "state_class": { - "options": { - "measurement": "[%key:component::sensor::entity_component::_::state_attributes::state_class::state::measurement%]", - "measurement_angle": "[%key:component::sensor::entity_component::_::state_attributes::state_class::state::measurement_angle%]", - "total": "[%key:component::sensor::entity_component::_::state_attributes::state_class::state::total%]", - "total_increasing": "[%key:component::sensor::entity_component::_::state_attributes::state_class::state::total_increasing%]" - } - } + "state_class": "[%dict:component::sensor::entity_component::_::state_attributes::state_class%]" }, "issues": { "entity_id_query_does_full_table_scan": { diff --git a/script/translations/develop.py b/script/translations/develop.py index 00ac7bf98ac..59ebb89b081 100644 --- a/script/translations/develop.py +++ b/script/translations/develop.py @@ -31,16 +31,34 @@ def get_arguments() -> argparse.Namespace: return parser.parse_args() -def substitute_translation_references(integration_strings, flattened_translations): +def substitute_translation_references( + integration_strings, flattened_translations, translations +): """Recursively processes all translation strings for the integration.""" result = {} for key, value in integration_strings.items(): if isinstance(value, dict): - sub_dict = substitute_translation_references(value, flattened_translations) + sub_dict = substitute_translation_references( + value, flattened_translations, translations + ) result[key] = sub_dict elif isinstance(value, str): - result[key] = substitute_reference(value, flattened_translations) - + if value.startswith(r"[%dict:"): + paths = value.removeprefix(r"[%dict:").removesuffix("%]").split("::") + values = translations + for path in paths: + if path not in values: + print( + f"Invalid dict key '{'::'.join(paths)}' found in string '{value}'" + ) + sys.exit(1) + values = values[path] + sub_dict = substitute_translation_references( + values, flattened_translations, translations + ) + result[key] = sub_dict + else: + result[key] = substitute_reference(value, flattened_translations) return result @@ -78,7 +96,7 @@ def run_single(translations, flattened_translations, integration): integration_strings = translations["component"][integration] translations["component"][integration] = substitute_translation_references( - integration_strings, flattened_translations + integration_strings, flattened_translations, translations ) if download.DOWNLOAD_DIR.is_dir(): diff --git a/script/translations/download.py b/script/translations/download.py index 0c9504f44cd..4d084ae617f 100755 --- a/script/translations/download.py +++ b/script/translations/download.py @@ -151,7 +151,16 @@ def pick_keys(component: str, translations: dict[str, Any]) -> dict[str, Any]: flat_translations = flatten_translations(translations) flat_current_keys = flatten_translations(get_current_keys(component)) flatten_result = {} - for key in flat_current_keys: + for key, value in flat_current_keys.items(): + if value.startswith(r"[%dict"): + flatten_result.update( + { + translated_key: translated_value + for translated_key, translated_value in flat_translations.items() + if translated_key.startswith(key) + } + ) + if key in flat_translations: flatten_result[key] = flat_translations[key] result = {} diff --git a/script/translations/util.py b/script/translations/util.py index d78b2c4faff..a11dedcb572 100644 --- a/script/translations/util.py +++ b/script/translations/util.py @@ -68,7 +68,7 @@ def load_json_from_path(path: pathlib.Path) -> Any: raise JSONDecodeErrorWithPath(err.msg, err.doc, err.pos, path) from err -def flatten_translations(translations): +def flatten_translations(translations: dict[str, Any]) -> dict[str, Any]: """Flatten all translations.""" stack = [iter(translations.items())] key_stack = []