import os
import re
import json
from collections import OrderedDict
SRC_DIR = "src"
EN_JSON = os.path.join(SRC_DIR, "i18n", "locales", "en.json")
PATTERN = re.compile(
r'(?:print_info|print_ok|print_err|print_warn|println!|eprintln!|panic!)\(\s*"([^"]+)"'
)
def scan_source_files():
found = set()
for root, _, files in os.walk(SRC_DIR):
for file in files:
if not file.endswith(".rs"):
continue
path = os.path.join(root, file)
with open(path, "r", encoding="utf-8") as f:
for i, line in enumerate(f, start=1):
for match in PATTERN.findall(line):
match = match.strip()
if len(match) > 0:
found.add(match)
return sorted(found)
def load_existing_translations():
if not os.path.exists(EN_JSON):
return OrderedDict()
with open(EN_JSON, "r", encoding="utf-8") as f:
try:
return json.load(f, object_pairs_hook=OrderedDict)
except json.JSONDecodeError:
print("⚠️ Warning: en.json is not valid JSON, starting fresh.")
return OrderedDict()
def generate_key(base_index, text):
return f"auto.msg.{base_index:03d}"
def update_translations(existing, extracted):
current_values = set(existing.values())
next_index = len(existing) + 1
for text in extracted:
if text not in current_values:
key = generate_key(next_index, text)
existing[key] = text
next_index += 1
return existing
def save_translations(translations):
os.makedirs(os.path.dirname(EN_JSON), exist_ok=True)
with open(EN_JSON, "w", encoding="utf-8") as f:
json.dump(translations, f, indent=4, ensure_ascii=False)
f.write("\n")
def main():
print("🔍 Scanning Rust source files for translatable strings...")
extracted = scan_source_files()
print(f" → Found {len(extracted)} unique strings")
existing = load_existing_translations()
before = len(existing)
updated = update_translations(existing, extracted)
added = len(updated) - before
save_translations(updated)
print(f"✅ Done. Added {added} new strings to {EN_JSON}")
print(f" Total keys: {len(updated)}")
if __name__ == "__main__":
main()