diff --git a/scripts/README.md b/scripts/README.md index 0a9c94e..4d8d9c4 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -24,6 +24,8 @@ Execute `uv run build_meshes.py` Validate the correction of BME prorotype JSON files. +Validation is VERY crucial. Before running anything involving BME prototype JSONs, please validate them first. + Execute `uv run validate_json.py` ## Extract BME Translation diff --git a/scripts/extract_json.py b/scripts/extract_json.py deleted file mode 100644 index 7bba7b7..0000000 --- a/scripts/extract_json.py +++ /dev/null @@ -1,6 +0,0 @@ -import common - - - -if __name__ == '__main__': - common.setup_logging() diff --git a/scripts/extract_jsons.py b/scripts/extract_jsons.py new file mode 100644 index 0000000..a2332d3 --- /dev/null +++ b/scripts/extract_jsons.py @@ -0,0 +1,88 @@ +import json, logging, typing, itertools +from pathlib import Path +import common, bme +from common import AssetKind +import pydantic, polib + +## YYC MARK: +# This translation context string prefix is cpoied from UTIL_translation.py. +# If the context string of translation changed, please synchronize it. + +CTX_TRANSLATION: str = 'BBP/BME' + + +def _extract_prototype(prototype: bme.Prototype) -> typing.Iterator[polib.POEntry]: + identifier = prototype.identifier + showcase = prototype.showcase + + # Show message + logging.info(f'Extracting prototype {identifier}') + + # Extract showcase + if showcase is None: + return + + # Extract showcase title + yield polib.POEntry(msgid=showcase.title, msgstr='', msgctxt=f'{CTX_TRANSLATION}/{identifier}') + # Extract showcase entries + for i, cfg in enumerate(showcase.cfgs): + # extract title and description + yield polib.POEntry(msgid=cfg.title, msgstr='', msgctxt=f'{CTX_TRANSLATION}/{identifier}/[{i}]') + yield polib.POEntry(msgid=cfg.desc, msgstr='', msgctxt=f'{CTX_TRANSLATION}/{identifier}/[{i}]') + + +def _extract_json(json_file: Path) -> typing.Iterator[polib.POEntry]: + # Show message + logging.info(f'Extracting file {json_file}') + + try: + # Read file and convert it into BME struct. + with open(json_file, 'r', encoding='utf-8') as f: + document = json.load(f) + prototypes = bme.Prototypes.model_validate(document) + # Extract translation + return itertools.chain.from_iterable(_extract_prototype(prototype) for prototype in prototypes.root) + except json.JSONDecodeError: + logging.error(f'Can not extract translation from {json_file} due to JSON error. Please validate it first.') + except pydantic.ValidationError: + logging.error(f'Can not extract translation from {json_file} due to struct error. Please validate it first.') + + # Output nothing + return itertools.chain.from_iterable(()) + + +def extract_jsons() -> None: + raw_jsons_dir = common.get_raw_assets_folder(AssetKind.Jsons) + + # Create POT content + po = polib.POFile() + po.metadata = { + 'Project-Id-Version': '1.0', + 'Report-Msgid-Bugs-To': 'you@example.com', + 'POT-Creation-Date': 'YEAR-MO-DA HO:MI+ZONE', + 'PO-Revision-Date': 'YEAR-MO-DA HO:MI+ZONE', + 'Last-Translator': 'FULL NAME ', + 'Language-Team': 'LANGUAGE ', + 'MIME-Version': '1.0', + 'Content-Type': 'text/plain; charset=utf-8', + 'Content-Transfer-Encoding': '8bit', + 'X-Generator': 'polib', + } + + # Iterate all prototypes and add into POT + for raw_json_file in raw_jsons_dir.glob('*.json'): + # Skip non-file. + if not raw_json_file.is_file(): + continue + # Extract json and append it. + po.extend(_extract_json(raw_json_file)) + + # Write into POT file + pot_file = common.get_root_folder() / 'i18n' / 'bme.pot' + logging.info(f'Saving POT into {pot_file}') + po.save(str(pot_file)) + + +if __name__ == '__main__': + common.setup_logging() + extract_jsons() diff --git a/scripts/validate_json.py b/scripts/validate_jsons.py similarity index 91% rename from scripts/validate_json.py rename to scripts/validate_jsons.py index 369809c..8ef7aa3 100644 --- a/scripts/validate_json.py +++ b/scripts/validate_jsons.py @@ -1,7 +1,7 @@ import json, logging, ast, typing -import pydantic import common, bme from common import AssetKind +import pydantic #region Assistant Validator @@ -27,7 +27,12 @@ def _validate_prototype(prototype: bme.Prototype) -> None: #endregion -def validate_json() -> None: +# 把提取JSON翻译的要求写入到验证中: +# - Showcase::Cfgs::Title或Desc不能为空。 +# - Showcase::Cfgs::Title和Showcase::Cfgs::Desc不能重复 + + +def validate_jsons() -> None: raw_jsons_dir = common.get_raw_assets_folder(AssetKind.Jsons) # Load all prototypes and check their basic format @@ -68,4 +73,4 @@ def validate_json() -> None: if __name__ == '__main__': common.setup_logging() - validate_json() + validate_jsons()