#!/usr/bin/env python3 """ Merge i18n translations from all pipeline modules into wwwroot/i18n. Scans each module's i18n directory and merges into the app's centralized i18n. Usage: python scripts/merge_i18n.py """ import os, json, sys from collections import OrderedDict from pathlib import Path SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) ROOT_DIR = os.path.dirname(SCRIPT_DIR) WWWROOT = os.path.join(ROOT_DIR, 'wwwroot') I18N_OUT = os.path.join(WWWROOT, 'i18n') # Modules to scan for i18n MODULES = [ ('pipeline_core', os.path.join(ROOT_DIR, 'pipeline_core', 'i18n')), ('pipeline_ops', os.path.join(ROOT_DIR, 'pipeline_ops', 'i18n')), ('pipeline_dist', os.path.join(ROOT_DIR, 'pipeline_dist', 'i18n')), ('pipeline-sdlc', os.path.join(os.path.dirname(ROOT_DIR), 'pipeline-sdlc', 'i18n')), ('showcase', os.path.join(os.path.dirname(ROOT_DIR), 'showcase', 'i18n')), ] LANGS = ['zh', 'en', 'ko', 'jp'] def parse_msg_txt(filepath): """Parse msg.txt: key=value format.""" result = OrderedDict() if not os.path.exists(filepath): return result with open(filepath, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if not line or line.startswith('#'): continue if '=' in line: key, val = line.split('=', 1) result[key.strip()] = val.strip() return result def merge(): os.makedirs(I18N_OUT, exist_ok=True) stats = {} for lang in LANGS: merged = OrderedDict() out_dir = os.path.join(I18N_OUT, lang) os.makedirs(out_dir, exist_ok=True) # Load existing merged translations i18n_file = os.path.join(out_dir, 'i18n.json') if os.path.exists(i18n_file): with open(i18n_file, 'r', encoding='utf-8') as f: merged = json.load(f, object_pairs_hook=OrderedDict) # Scan each module for mod_name, mod_i18n_dir in MODULES: lang_dir = os.path.join(mod_i18n_dir, lang) if not os.path.isdir(lang_dir): # Try app's internal i18n alt_dir = os.path.join(ROOT_DIR, 'pipeline_core', 'i18n', lang) if not os.path.isdir(alt_dir): continue lang_dir = alt_dir # Load msg.txt msg_file = os.path.join(lang_dir, 'msg.txt') if os.path.exists(msg_file): msgs = parse_msg_txt(msg_file) for k, v in msgs.items(): if k not in merged: merged[k] = v stats.setdefault(mod_name, 0) stats[mod_name] += 1 # Load i18n.json mod_i18n = os.path.join(lang_dir, 'i18n.json') if os.path.exists(mod_i18n): with open(mod_i18n, 'r', encoding='utf-8') as f: extra = json.load(f, object_pairs_hook=OrderedDict) for k, v in extra.items(): if k not in merged: merged[k] = v # Write merged with open(i18n_file, 'w', encoding='utf-8') as f: json.dump(merged, f, ensure_ascii=False, indent=2) print(f' {lang}: {len(merged)} keys') # Write msg.txt for the app root print(f'\nMerged i18n for {len(MODULES)} modules -> {I18N_OUT}') if __name__ == '__main__': merge()