"""Compile the current translation strings files for testing.""" import argparse import json from pathlib import Path import re from shutil import rmtree import sys from . import download, upload from .const import INTEGRATIONS_DIR from .util import get_base_arg_parser def valid_integration(integration): """Test if it's a valid integration.""" if not (INTEGRATIONS_DIR / integration).is_dir(): raise argparse.ArgumentTypeError( f"The integration {integration} does not exist." ) return integration def get_arguments() -> argparse.Namespace: """Get parsed passed in arguments.""" parser = get_base_arg_parser() parser.add_argument( "--integration", type=valid_integration, help="Integration to process." ) return parser.parse_args() def flatten_translations(translations): """Flatten all translations.""" stack = [iter(translations.items())] key_stack = [] flattened_translations = {} while stack: for k, v in stack[-1]: key_stack.append(k) if isinstance(v, dict): stack.append(iter(v.items())) break elif isinstance(v, str): common_key = "::".join(key_stack) flattened_translations[common_key] = v key_stack.pop() else: stack.pop() if len(key_stack) > 0: key_stack.pop() return flattened_translations def substitute_translation_references(integration_strings, flattened_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) result[key] = sub_dict elif isinstance(value, str): result[key] = substitute_reference(value, flattened_translations) return result def substitute_reference(value, flattened_translations): """Substitute localization key references in a translation string.""" matches = re.findall(r"\[\%key:((?:[\w]+|[:]{2})*)\%\]", value) if not matches: return value new = value for key in matches: if key in flattened_translations: new = new.replace( f"[%key:{key}%]", # New value can also be a substitution reference substitute_reference( flattened_translations[key], flattened_translations ), ) else: print(f"Invalid substitution key '{key}' found in string '{value}'") sys.exit(1) return new def run(): """Run the script.""" args = get_arguments() if args.integration: integration = args.integration else: integration = None while ( integration is None or not Path(f"homeassistant/components/{integration}").exists() ): if integration is not None: print(f"Integration {integration} doesn't exist!") print() integration = input("Integration to process: ") translations = upload.generate_upload_data() if integration not in translations["component"]: print("Integration has no strings.json") sys.exit(1) flattened_translations = flatten_translations(translations) integration_strings = translations["component"][integration] translations["component"][integration] = substitute_translation_references( integration_strings, flattened_translations ) if download.DOWNLOAD_DIR.is_dir(): rmtree(str(download.DOWNLOAD_DIR)) download.DOWNLOAD_DIR.mkdir(parents=True) (download.DOWNLOAD_DIR / "en.json").write_text( json.dumps({"component": {integration: translations["component"][integration]}}) ) download.write_integration_translations() return 0