diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index f5edfe5929..0ff0092b02 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -307,6 +307,7 @@ jobs: $UNIT_TEST tools/lib/tests && \ ./selfdrive/ui/tests/create_test_translations.sh && \ QT_QPA_PLATFORM=offscreen ./selfdrive/ui/tests/test_translations && \ + ./selfdrive/ui/tests/test_translations.py && \ ./common/tests/test_util && \ ./common/tests/test_swaglog && \ ./selfdrive/boardd/tests/test_boardd_usbprotocol && \ diff --git a/release/files_common b/release/files_common index 7e8dbd37a6..acf74e2137 100644 --- a/release/files_common +++ b/release/files_common @@ -60,6 +60,8 @@ release/* tools/lib/* tools/joystick/* +tools/replay/*.cc +tools/replay/*.h selfdrive/__init__.py selfdrive/sentry.py @@ -287,6 +289,7 @@ selfdrive/ui/soundd/*.cc selfdrive/ui/soundd/*.h selfdrive/ui/soundd/soundd selfdrive/ui/soundd/.gitignore +selfdrive/ui/translations/* selfdrive/ui/qt/*.cc selfdrive/ui/qt/*.h @@ -295,10 +298,6 @@ selfdrive/ui/qt/offroad/*.h selfdrive/ui/qt/offroad/*.qml selfdrive/ui/qt/widgets/*.cc selfdrive/ui/qt/widgets/*.h - -tools/replay/*.cc -tools/replay/*.h - selfdrive/ui/qt/maps/*.cc selfdrive/ui/qt/maps/*.h diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py new file mode 100755 index 0000000000..ccea748e24 --- /dev/null +++ b/selfdrive/ui/tests/test_translations.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +import json +import os +import unittest + +from selfdrive.ui.update_translations import TRANSLATIONS_DIR, LANGUAGES_FILE, update_translations + + +class TestTranslations(unittest.TestCase): + @classmethod + def setUpClass(cls): + with open(LANGUAGES_FILE, "r") as f: + cls.translation_files = json.load(f) + + def test_missing_translation_files(self): + for name, file in self.translation_files.items(): + with self.subTest(name=name, file=file): + if not len(file): + self.skipTest(f"{name} translation has no file") + + self.assertTrue(os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.ts")), + f"{name} has no XML translation file, run selfdrive/ui/update_translations.py") + self.assertTrue(os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.qm")), + f"{name} has no compiled QM translation file, run selfdrive/ui/update_translations.py --release") + + def test_translations_updated(self): + suffix = "_test" + update_translations(suffix=suffix) + + for name, file in self.translation_files.items(): + with self.subTest(name=name, file=file): + cur_tr_file = os.path.join(TRANSLATIONS_DIR, f"{file}.ts") + new_tr_file = os.path.join(TRANSLATIONS_DIR, f"{file}{suffix}.ts") + + if not len(file): + self.skipTest(f"{name} translation has no file") + elif not os.path.exists(cur_tr_file): + self.skipTest(f"{name} missing translation file") # caught by test_missing_translation_files + + with open(cur_tr_file, "r") as f: + cur_translations = f.read() + with open(new_tr_file, "r") as f: + new_translations = f.read() + + self.assertEqual(cur_translations, new_translations, + f"{name} translation file out of date. Run selfdrive/ui/update_translations.py to update the translation files") + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/ui/translations/languages.json b/selfdrive/ui/translations/languages.json new file mode 100644 index 0000000000..f2f9400d64 --- /dev/null +++ b/selfdrive/ui/translations/languages.json @@ -0,0 +1,3 @@ +{ + "English": "" +} diff --git a/selfdrive/ui/update_translations.py b/selfdrive/ui/update_translations.py new file mode 100755 index 0000000000..5d57fa39d2 --- /dev/null +++ b/selfdrive/ui/update_translations.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +import argparse +import os +import json + +from common.basedir import BASEDIR + +UI_DIR = os.path.join(BASEDIR, "selfdrive", "ui") +TRANSLATIONS_DIR = os.path.join(UI_DIR, "translations") +LANGUAGES_FILE = os.path.join(TRANSLATIONS_DIR, "languages.json") + + +def update_translations(release=False, suffix=""): + with open(LANGUAGES_FILE, "r") as f: + translation_files = json.load(f) + + for name, file in translation_files.items(): + if not len(file): + print(f"{name} has no translation file, skipping...") + continue + + tr_file = os.path.join(TRANSLATIONS_DIR, f"{file}{suffix}.ts") + ret = os.system(f"lupdate -recursive {UI_DIR} -ts {tr_file}") + assert ret == 0 + + if release: + ret = os.system(f"lrelease {tr_file}") + assert ret == 0 + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Update translation files for UI", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument("--release", action="store_true", help="Create compiled QM translation files used by UI") + args = parser.parse_args() + + update_translations(args.release)