WebUI: Implement double-click behavior controls
[qBittorrent.git] / src / webui / www / translations_qt2i18next.py
blob4c0f4a856953a4c41f44dd2ce64caf02ec2d3f1b
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
4 # translations_qt2i18next.py - script for migrating translations from Qt's .ts files
5 # to i18next compatible JSON files.
6 # Copyright (C) 2024 sledgehammer999 <hammered999@gmail.com>
8 # License: Public domain.
10 import argparse
11 import glob
12 import json
13 import os
14 import sys
15 import xml.etree.ElementTree as ET
18 def getTsStrings(ts_file: str, key: str) -> list[str]:
19 tr_strings: list[str] = []
20 tree = ET.parse(ts_file)
21 root = tree.getroot()
23 for context in root.findall('context'):
24 for message in context.findall('message'):
25 source = message.find('source').text
26 if key != source:
27 continue
29 translation = message.find('translation').text
30 if not translation:
31 continue
32 if translation not in tr_strings:
33 tr_strings.append(translation)
35 return tr_strings
38 def migrate2Json(ts_dir: str, json_dir: str, locale: str) -> None:
39 ts_file: str = f"{ts_dir}/webui_{locale}.ts"
40 js_file: str = f"{json_dir}/{locale}.json"
42 print(f"Processing lang {locale}")
43 if not os.path.exists(ts_file):
44 print(f"\tERROR: {ts_file} doesn't exist.")
45 return
47 with open(js_file, mode="r+", encoding='utf-8') as file:
48 translations = json.load(file)
49 if not isinstance(translations, dict):
50 print(f"\tERROR: {js_file} is malformed.")
51 return
53 for key, value in translations.items():
54 if not (isinstance(key, str) and isinstance(value, str) and not value):
55 continue
57 ts_strings: list[str] = getTsStrings(ts_file, key)
58 ts_len: int = len(ts_strings)
59 if ts_len == 0:
60 print(f"\tWARNING: Translation for '{key}' not found.")
61 continue
63 if ts_len > 1:
64 print(f"\tWARNING: Multiple translations for '{key}' found.")
65 continue
67 translations[key] = ts_strings[0]
69 file.seek(0)
70 json.dump(translations, file, ensure_ascii=False, indent=2, sort_keys=True)
71 file.write("\n")
72 file.truncate()
74 print("\tFinished.")
77 def main() -> int:
78 script_path: str = os.path.dirname(os.path.realpath(__file__))
79 ts_dir: str = f"{script_path}/translations"
80 json_dir: str = f"{script_path}/public/lang"
82 parser = argparse.ArgumentParser()
83 parser.add_argument("--ts-dir", default=ts_dir, nargs=1, help=f"directory of WebUI .ts translation files (default: '{ts_dir}')")
84 parser.add_argument("--json-dir", default=json_dir, nargs=1, help=f"directory of WebUI .json translation files(default: '{json_dir}')")
86 args = parser.parse_args()
88 if not os.path.isdir(args.ts_dir):
89 raise RuntimeError(f"'{args.ts_dir}' isn't a directory")
91 if not os.path.isdir(args.json_dir):
92 raise RuntimeError(f"'{args.json_dir}' isn't a directory")
94 locales: list[str] = glob.glob("*.json", root_dir=json_dir)
95 locales = [x.removesuffix(".json") for x in locales if x != "en.json"]
96 for locale in locales:
97 migrate2Json(ts_dir, json_dir, locale)
99 print("Done.")
101 return 0
104 if __name__ == '__main__':
105 sys.exit(main())