diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb5e9f23..ce2f68ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,6 +52,7 @@ After adding or modifying `{% translate %}` tags, regenerate the `.po` files: ```bash cd src/imgtests/web django-admin makemessages -l ru +django-admin makemessages -d djangojs -l ru ``` Then edit the `.po` file and fill in the `msgstr` fields. diff --git a/docker/python.dockerfile b/docker/python.dockerfile index a19ed2ed..1639a0ac 100644 --- a/docker/python.dockerfile +++ b/docker/python.dockerfile @@ -19,9 +19,9 @@ RUN apt update && \ nano \ iperf3 \ supervisor \ - gettext -RUN apt-get clean -RUN rm --recursive --force /tmp/* /var/tmp/* + gettext && \ + apt-get clean && \ + rm --recursive --force /tmp/* /var/tmp/* RUN groupadd -g 510 ${GROUP} && \ useradd -rm -d /home/${USER} -s /bin/bash -g ${GROUP} -u 1010 -G sudo ${USER} && \ @@ -38,11 +38,15 @@ COPY --chown=${USER}:${GROUP} pyproject.toml /home/${USER}/python RUN mkdir --parents /home/${USER}/${LIB_NAME}/conf && \ chown ${USER}:${GROUP} --recursive /home/${USER}/${LIB_NAME}/ COPY --chown=${USER}:${GROUP} conf/supervisord.conf /home/${USER}/${LIB_NAME}/conf/supervisord.conf + RUN msgfmt --output-file \ - /home/${USER}/python/imgtests/web/locale/ru/LC_MESSAGES/django.mo \ - /home/${USER}/python/imgtests/web/locale/ru/LC_MESSAGES/django.po -RUN cd /home/${USER}/python && python3 -m pip install . -RUN rm -rf /home/${USER}/python + /home/${USER}/python/imgtests/web/locale/ru/LC_MESSAGES/django.mo \ + /home/${USER}/python/imgtests/web/locale/ru/LC_MESSAGES/django.po && \ + msgfmt --output-file \ + /home/${USER}/python/imgtests/web/locale/ru/LC_MESSAGES/djangojs.mo \ + /home/${USER}/python/imgtests/web/locale/ru/LC_MESSAGES/djangojs.po + +RUN cd /home/${USER}/python && python3 -m pip install . && rm -rf /home/${USER}/python COPY --chown=${USER}:${GROUP} scripts/entrypoint-analyzer.sh /home/${USER}/${LIB_NAME}/entrypoint-analyzer.sh RUN chmod +x /home/${USER}/${LIB_NAME}/entrypoint-analyzer.sh diff --git a/docs/i18n/CONTRIBUTING_ru.md b/docs/i18n/CONTRIBUTING_ru.md index c952d9c7..08e9f8c1 100644 --- a/docs/i18n/CONTRIBUTING_ru.md +++ b/docs/i18n/CONTRIBUTING_ru.md @@ -52,6 +52,7 @@ pip install uv ```bash cd src/imgtests/web django-admin makemessages -l ru +django-admin makemessages -d djangojs -l ru ``` Затем отредактируйте `.po` файл и заполните поля `msgstr`. diff --git a/src/imgtests/web/locale/ru/LC_MESSAGES/django.po b/src/imgtests/web/locale/ru/LC_MESSAGES/django.po index 1fec9d73..b215f7ac 100644 --- a/src/imgtests/web/locale/ru/LC_MESSAGES/django.po +++ b/src/imgtests/web/locale/ru/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: imgtests 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-16 13:14+0000\n" -"PO-Revision-Date: 2026-05-16 13:14+0000\n" +"POT-Creation-Date: 2026-07-21 15:58+0300\n" +"PO-Revision-Date: 2026-07-21 15:58+0300\n" "Last-Translator: Vadim Kazakov vadimdim308@gmail.com\n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -17,6 +17,7 @@ msgstr "" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || " "(n%100>=11 && n%100<=14)? 2 : 3);\n" + #: tests_interface/templates/tests_interface/base.html:7 #: tests_interface/templates/tests_interface/index.html:4 msgid "Test Dashboard" @@ -28,7 +29,7 @@ msgstr "Тесты" #: tests_interface/templates/tests_interface/distro_page.html:9 #: tests_interface/templates/tests_interface/excel_reports.html:9 -#: tests_interface/templates/tests_interface/reports_list.html:9 +#: tests_interface/templates/tests_interface/reports_list.html:10 msgid "Back to Dashboard" msgstr "На главную страницу" @@ -42,7 +43,7 @@ msgstr "Конфигурация тестов" #: tests_interface/templates/tests_interface/distro_page.html:28 msgid "Select runner:" -msgstr "Выберите runner" +msgstr "Выберите раннер:" #: tests_interface/templates/tests_interface/distro_page.html:30 msgid "Basic" @@ -54,7 +55,7 @@ msgstr "С профилированием" #: tests_interface/templates/tests_interface/distro_page.html:40 msgid "Use Default Configuration" -msgstr "Использовать стандартную конфигурацию" +msgstr "Использовать конфигурацию по умолчанию" #: tests_interface/templates/tests_interface/distro_page.html:43 msgid "Custom Configuration" @@ -62,15 +63,15 @@ msgstr "Пользовательская конфигурация" #: tests_interface/templates/tests_interface/distro_page.html:49 msgid "Number of test runs:" -msgstr "Количество запусков тестов" +msgstr "Количество запусков тестов:" #: tests_interface/templates/tests_interface/distro_page.html:62 msgid "Select Test Suites and Configure Duration:" -msgstr "Выберите наборы тестов и длительность" +msgstr "Выберите сценарии тестов и их длительность:" #: tests_interface/templates/tests_interface/distro_page.html:67 msgid "Individual Tests (optional):" -msgstr "Отдельные тесты (опционально):" +msgstr "Отдельные тесты (не обязательно):" #: tests_interface/templates/tests_interface/distro_page.html:73 msgid "Save Configuration" @@ -81,41 +82,85 @@ msgstr "Сохранить конфигурацию" msgid "Reset to Default" msgstr "Восстановить конфигурацию по умолчанию" -#: tests_interface/templates/tests_interface/distro_page.html:88 +#: tests_interface/templates/tests_interface/distro_page.html:90 +msgid "Use Default Profiled Configuration" +msgstr "Использовать конфигурацию по умолчанию" + +#: tests_interface/templates/tests_interface/distro_page.html:94 +msgid "Custom Profiled Configuration" +msgstr "Пользовательская конфигурация" + +#: tests_interface/templates/tests_interface/distro_page.html:101 +msgid "Single run" +msgstr "Одиночный запуск" + +#: tests_interface/templates/tests_interface/distro_page.html:105 +msgid "Matrix run" +msgstr "Матричный запуск" + +#: tests_interface/templates/tests_interface/distro_page.html:109 +msgid "Duration" +msgstr "Длительность" + +#: tests_interface/templates/tests_interface/distro_page.html:112 +msgid "Profile" +msgstr "Профиль" + +#: tests_interface/templates/tests_interface/distro_page.html:117 +msgid "Profiles and durations" +msgstr "Профили и длительность" + +#: tests_interface/templates/tests_interface/distro_page.html:122 +msgid "Pattern" +msgstr "Шаблон" + +#: tests_interface/templates/tests_interface/distro_page.html:127 +msgid "Subsystems" +msgstr "Подсистемы" + +#: tests_interface/templates/tests_interface/distro_page.html:135 msgid "Run tests" msgstr "Запустить тесты" #: tests_interface/templates/tests_interface/excel_reports.html:4 #: tests_interface/templates/tests_interface/excel_reports.html:11 msgid "Excel Reports" -msgstr "Отчеты Excel" +msgstr "Excel-отчеты" + +#: tests_interface/templates/tests_interface/excel_reports.html:18 +msgid "Distributions" +msgstr "Дистрибутивы" + +#: tests_interface/templates/tests_interface/excel_reports.html:27 +msgid "Tables" +msgstr "Таблицы" -#: tests_interface/templates/tests_interface/excel_reports.html:17 +#: tests_interface/templates/tests_interface/excel_reports.html:39 msgid "Generate New Excel Report" -msgstr "Сгенерировать новый Excel-отчет" +msgstr "Создать новый Excel-отчет" -#: tests_interface/templates/tests_interface/excel_reports.html:61 +#: tests_interface/templates/tests_interface/excel_reports.html:83 #, python-format -msgid "Size: %(report.size|filesizeformat)s" -msgstr "Размер: %(report.size|filesizeformat)s" +msgid "Size: %(size)s" +msgstr "Размер: %(size)s" -#: tests_interface/templates/tests_interface/excel_reports.html:65 +#: tests_interface/templates/tests_interface/excel_reports.html:87 msgid "Download" msgstr "Скачать" -#: tests_interface/templates/tests_interface/excel_reports.html:81 -#: tests_interface/templates/tests_interface/reports_list.html:153 +#: tests_interface/templates/tests_interface/excel_reports.html:103 +#: tests_interface/templates/tests_interface/reports_list.html:155 #, python-format -msgid "Total: %(reports|length)s report(s)" -msgstr "Всего: %(reports|length)s report(s)" +msgid "Total: %(count)s report(s)" +msgstr "Всего: %(count)s отчет(а/ов)" -#: tests_interface/templates/tests_interface/excel_reports.html:95 +#: tests_interface/templates/tests_interface/excel_reports.html:117 msgid "No Excel Reports" msgstr "Нет Excel-отчетов" -#: tests_interface/templates/tests_interface/excel_reports.html:98 +#: tests_interface/templates/tests_interface/excel_reports.html:120 msgid "Click \"Generate New Excel Report\" to create one." -msgstr "Нажмите \"Сгенерировать новый Excel-отчет\" чтобы создать его" +msgstr "Нажмите \"Создать новый Excel-отчет\", чтобы создать его." #: tests_interface/templates/tests_interface/index.html:4 msgid "Home" @@ -137,40 +182,39 @@ msgstr "Добавить дистрибутив" msgid "All Reports" msgstr "Все отчеты" -#: tests_interface/templates/tests_interface/reports_list.html:11 +#: tests_interface/templates/tests_interface/reports_list.html:13 msgid "Test Reports" msgstr "Отчеты о тестировании" -#: tests_interface/templates/tests_interface/reports_list.html:26 +#: tests_interface/templates/tests_interface/reports_list.html:28 msgid "Generate Comparison Report" msgstr "Создать сравнительный отчет" -#: tests_interface/templates/tests_interface/reports_list.html:44 +#: tests_interface/templates/tests_interface/reports_list.html:46 msgid "Experiment 1" msgstr "Эксперимент 1" -#: tests_interface/templates/tests_interface/reports_list.html:55 -#: tests_interface/templates/tests_interface/reports_list.html:77 +#: tests_interface/templates/tests_interface/reports_list.html:57 +#: tests_interface/templates/tests_interface/reports_list.html:79 msgid "Select" msgstr "Выберите" -#: tests_interface/templates/tests_interface/reports_list.html:66 +#: tests_interface/templates/tests_interface/reports_list.html:68 msgid "Experiment 2" msgstr "Эксперимент 2" -#: tests_interface/templates/tests_interface/reports_list.html:87 -#: tests_interface/templates/tests_interface/reports_list.html:258 +#: tests_interface/templates/tests_interface/reports_list.html:89 msgid "Generate" -msgstr "Сгенерировать" +msgstr "Создать" -#: tests_interface/templates/tests_interface/reports_list.html:166 +#: tests_interface/templates/tests_interface/reports_list.html:169 msgid "No Reports Found" msgstr "Отчеты не найдены" -#: tests_interface/templates/tests_interface/reports_list.html:168 +#: tests_interface/templates/tests_interface/reports_list.html:172 msgid "No reports available yet. Run some tests to generate reports." -msgstr "Отчетов еще нет. Запустите тесты для их создания" +msgstr "Отчеты пока недоступны. Запустите тесты, чтобы создать отчеты." -#: tests_interface/templates/tests_interface/reports_list.html:174 +#: tests_interface/templates/tests_interface/reports_list.html:178 msgid "Run Tests" msgstr "Запустить тесты" diff --git a/src/imgtests/web/locale/ru/LC_MESSAGES/djangojs.po b/src/imgtests/web/locale/ru/LC_MESSAGES/djangojs.po new file mode 100644 index 00000000..222217bf --- /dev/null +++ b/src/imgtests/web/locale/ru/LC_MESSAGES/djangojs.po @@ -0,0 +1,272 @@ +# Translation file +# This file is distributed under the same license as the imgtests package. +# Nikita Pivoev nikita.pivoev@yandex.ru, 2026. +# +# +msgid "" +msgstr "" +"Project-Id-Version: imgtests 0.0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-21 15:45+0300\n" +"PO-Revision-Date: 2026-07-21 15:45+0300\n" +"Last-Translator: Nikita Pivoev nikita.pivoev@yandex.ru\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || " +"(n%100>=11 && n%100<=14)? 2 : 3);\n" + +#: src/imgtests/web/static/js/dashboard.js:46 +msgid "View All .html Reports" +msgstr "Отобразить все .html отчеты" + +#: src/imgtests/web/static/js/dashboard.js:47 +msgid "Browse all generated .html test reports" +msgstr "Просмотреть все сгенерированные .html тестовые отчеты" + +#: src/imgtests/web/static/js/dashboard.js:58 +msgid "View All .xls Reports" +msgstr "Отобразить все .xls отчеты" + +#: src/imgtests/web/static/js/dashboard.js:59 +msgid "Browse all exported .xls test reports" +msgstr "Просмотреть все экспортированные .xls тестовые отчеты" + +#: src/imgtests/web/static/js/dashboard.js:69 +msgid "Enter distribution name (e.g., ubuntu):" +msgstr "Введите название дистрибутива (например, ubuntu):" + +#: src/imgtests/web/static/js/dashboard.js:71 +msgid "Enter display name (e.g., Ubuntu):" +msgstr "Введите отображаемое имя (например, Ubuntu):" + +#: src/imgtests/web/static/js/dashboard.js:74 +msgid "Enter description (optional):" +msgstr "Введите описание (необязательно):" + +#: src/imgtests/web/static/js/dashboard.js:76 +msgid "Run tests for %(display_name)s platform" +msgstr "Запустить тесты для платформы %(display_name)s" + +#: src/imgtests/web/static/js/dashboard.js:98 +#: src/imgtests/web/static/js/dashboard.js:117 +#: src/imgtests/web/static/js/dashboard.js:142 +#: src/imgtests/web/static/js/excel_reports.js:55 +#: src/imgtests/web/static/js/excel_reports.js:61 +#: src/imgtests/web/static/js/html_reports.js:63 +#: src/imgtests/web/static/js/launch_test.js:103 +#: src/imgtests/web/static/js/launch_test.js:111 +msgid "Error: %(error)s" +msgstr "Ошибка: %(error)s" + +#: src/imgtests/web/static/js/dashboard.js:105 +msgid "Are you sure you want to remove this distribution?" +msgstr "Вы уверены, что хотите удалить данный дистрибутив?" + +#: src/imgtests/web/static/js/dashboard.js:126 +msgid "" +"Reset to default distributions? This will remove all custom distributions." +msgstr "" +"Восстановить изначальные дистрибутивы? Это удалит все пользовательские " +"дистрибутивы." + +#: src/imgtests/web/static/js/excel_reports.js:30 +msgid "Please select at least one table." +msgstr "Пожалуйста, выберите хотя бы одну таблицу." + +#: src/imgtests/web/static/js/excel_reports.js:34 +msgid "Please select at least one distribution." +msgstr "Пожалуйста, выберите хотя бы один дистрибутив." + +#: src/imgtests/web/static/js/excel_reports.js:39 +#: src/imgtests/web/static/js/html_reports.js:38 +msgid "Generating..." +msgstr "Создание..." + +#: src/imgtests/web/static/js/excel_reports.js:57 +#: src/imgtests/web/static/js/excel_reports.js:63 +msgid "Generate New Excel Report" +msgstr "Создать новый Excel-отчет" + +#: src/imgtests/web/static/js/html_reports.js:10 +msgid "(no description)" +msgstr "(нет описания)" + +#: src/imgtests/web/static/js/html_reports.js:58 +msgid "Report generated! Reload page to see it" +msgstr "Отчет создан! Перезагрузите страницу, чтобы увидеть его" + +#: src/imgtests/web/static/js/html_reports.js:63 +msgid "unknown" +msgstr "неизвестно" + +#: src/imgtests/web/static/js/html_reports.js:71 +msgid "Request failed: %(message)s" +msgstr "Запрос не удался: %(message)s" + +#: src/imgtests/web/static/js/html_reports.js:77 +msgid "Generate" +msgstr "Создать" + +#: src/imgtests/web/static/js/launch_test.js:78 +msgid "Running..." +msgstr "Выполнение..." + +#: src/imgtests/web/static/js/launch_test.js:79 +msgid "Tests Running..." +msgstr "Тесты выполняются..." + +#: src/imgtests/web/static/js/launch_test.js:97 +msgid "Tests running... (Task ID: %(task_id)s)" +msgstr "Тесты выполняются... (ID задачи: %(task_id)s)" + +#: src/imgtests/web/static/js/launch_test.js:104 +msgid "Failed to start tests" +msgstr "Не удалось запустить тесты" + +#: src/imgtests/web/static/js/launch_test.js:107 +#: src/imgtests/web/static/js/launch_test.js:113 +#: src/imgtests/web/static/js/launch_test.js:133 +#: src/imgtests/web/static/js/launch_test.js:144 +#: src/imgtests/web/static/js/launch_test.js:148 +#: src/imgtests/web/static/js/launch_test.js:157 +msgid "Run tests" +msgstr "Запустить тесты" + +#: src/imgtests/web/static/js/launch_test.js:127 +msgid "Tests running... Please wait." +msgstr "Тесты выполняются... Пожалуйста, подождите." + +#: src/imgtests/web/static/js/launch_test.js:131 +msgid "Tests completed successfully." +msgstr "Тесты завершены успешно." + +#: src/imgtests/web/static/js/launch_test.js:135 +msgid "Test failed" +msgstr "Тест не пройден" + +#: src/imgtests/web/static/js/launch_test.js:146 +msgid "Unknown status" +msgstr "Неизвестный статус" + +#: src/imgtests/web/static/js/launch_test.js:153 +msgid "Error checking status: %(error)s" +msgstr "Ошибка проверки статуса: %(error)s" + +#: src/imgtests/web/static/js/test_config.js:21 +msgid "Failed to load configuration: %(message)s" +msgstr "Не удалось загрузить конфигурацию: %(message)s" + +#: src/imgtests/web/static/js/test_config.js:44 +msgid "Failed to load test suites: %(message)s" +msgstr "Не удалось загрузить тестовые сценарии: %(message)s" + +#: src/imgtests/web/static/js/test_config.js:64 +msgid "Failed to load tests for %(distro_name)s" +msgstr "Не удалось загрузить тесты для %(distro_name)s" + +#: src/imgtests/web/static/js/test_config.js:150 +msgid "Failed to load test suites. Please refresh the page." +msgstr "Не удалось загрузить тестовые сценарии. Пожалуйста, обновите страницу." + +#: src/imgtests/web/static/js/test_config.js:173 +msgid "No test suites available" +msgstr "Нет доступных тестовых сценариев" + +#: src/imgtests/web/static/js/test_config.js:204 +msgid "No description" +msgstr "(нет описания)" + +#: src/imgtests/web/static/js/test_config.js:208 +msgid "Default duration:" +msgstr "Продолжительность по умолчанию:" + +#: src/imgtests/web/static/js/test_config.js:209 +msgid "Tests:" +msgstr "Тесты:" + +#: src/imgtests/web/static/js/test_config.js:213 +msgid "Custom duration (seconds):" +msgstr "Продолжительность (секунды):" + +#: src/imgtests/web/static/js/test_config.js:226 +msgid "Select Individual Tests" +msgstr "Выбрать отдельные тесты" + +#: src/imgtests/web/static/js/test_config.js:231 +msgid "test(s) selected" +msgstr "тест(ов) выбрано" + +#: src/imgtests/web/static/js/test_config.js:303 +msgid "Select tests for" +msgstr "Выберите тесты для" + +#: src/imgtests/web/static/js/test_config.js:304 +msgid "Leave all unchecked to run all tests" +msgstr "Оставьте все неотмеченными, чтобы запустить все тесты" + +#: src/imgtests/web/static/js/test_config.js:321 +msgid "Save Selection" +msgstr "Сохранить выбор" + +#: src/imgtests/web/static/js/test_config.js:322 +msgid "Cancel" +msgstr "Отмена" + +#: src/imgtests/web/static/js/test_config.js:345 +msgid "Selected %(count)s tests for %(suite_name)s" +msgstr "Выбрано %(count)s тестов для %(suite_name)s" + +#: src/imgtests/web/static/js/test_config.js:354 +msgid "Will run all tests for %(suite_name)s" +msgstr "Будут запущены все тесты для %(suite_name)s" + +#: src/imgtests/web/static/js/test_config.js:375 +msgid "Failed to load tests for %(suite_name)s" +msgstr "Не удалось загрузить тесты для %(suite_name)s" + +#: src/imgtests/web/static/js/test_config.js:433 +msgid "Configuration saved successfully!" +msgstr "Конфигурация успешно сохранена!" + +#: src/imgtests/web/static/js/test_config.js:443 +msgid "Error saving configuration: %(message)s" +msgstr "Ошибка сохранения конфигурации: %(message)s" + +#: src/imgtests/web/static/js/test_config.js:487 +msgid "Configuration reset to default" +msgstr "Конфигурация сброшена до значений по умолчанию" + +#: src/imgtests/web/static/js/test_config.js:491 +msgid "Failed to reset configuration" +msgstr "Не удалось сбросить конфигурацию" + +#: src/imgtests/web/static/js/test_config.js:548 +msgid "Duration (sec)" +msgstr "Длительность (сек)" + +#: src/imgtests/web/static/js/test_config.js:575 +msgid "File" +msgstr "Файловая" + +#: src/imgtests/web/static/js/test_config.js:576 +msgid "IPC" +msgstr "IPC" + +#: src/imgtests/web/static/js/test_config.js:577 +msgid "Memory" +msgstr "Память" + +#: src/imgtests/web/static/js/test_config.js:578 +msgid "Network" +msgstr "Сетевая" + +#: src/imgtests/web/static/js/test_config.js:579 +msgid "Syscalls" +msgstr "Системные вызовы" + +#: src/imgtests/web/static/js/test_config.js:580 +msgid "System" +msgstr "Система" diff --git a/src/imgtests/web/static/js/dashboard.js b/src/imgtests/web/static/js/dashboard.js index 2bf9ecb6..c7bd62f2 100644 --- a/src/imgtests/web/static/js/dashboard.js +++ b/src/imgtests/web/static/js/dashboard.js @@ -43,8 +43,8 @@ function renderDistributions(distributions) { htmlReportsLink.innerHTML = ` `; @@ -55,8 +55,8 @@ function renderDistributions(distributions) { excelReportsLink.innerHTML = ` `; @@ -66,13 +66,17 @@ function renderDistributions(distributions) { } function addDistro() { - const name = prompt("Enter distribution name (e.g., ubuntu):"); + const name = prompt(gettext("Enter distribution name (e.g., ubuntu):")); if (!name) return; - const displayName = prompt("Enter display name (e.g., Ubuntu):"); + const displayName = prompt(gettext("Enter display name (e.g., Ubuntu):")); if (!displayName) return; const description = prompt( - "Enter description (optional):", - `Run tests for ${displayName} platform`, + gettext("Enter description (optional):"), + interpolate( + gettext("Run tests for %(display_name)s platform"), + {display_name: displayName}, + true + ), ); fetch("/api/distros/add/", { method: "POST", @@ -91,14 +95,18 @@ function addDistro() { if (data.success) { loadDistributions(); } else { - alert("Error: " + data.error); + alert(interpolate( + gettext("Error: %(error)s"), + {error: data.error}, + true + )); } }) .catch((error) => console.error("Error:", error)); } function removeDistro(distroId) { - if (!confirm("Are you sure you want to remove this distribution?")) return; + if (!confirm(gettext("Are you sure you want to remove this distribution?"))) return; fetch(`/api/distros/remove/${distroId}/`, { method: "POST", headers: { @@ -110,7 +118,11 @@ function removeDistro(distroId) { if (data.success) { loadDistributions(); } else { - alert("Error: " + data.error); + alert(interpolate( + gettext("Error: %(error)s"), + {error: data.error}, + true + )); } }) .catch((error) => console.error("Error:", error)); @@ -119,7 +131,7 @@ function removeDistro(distroId) { function resetDistributions() { if ( !confirm( - "Reset to default distributions? This will remove all custom distributions.", + gettext("Reset to default distributions? This will remove all custom distributions."), ) ) return; @@ -135,7 +147,11 @@ function resetDistributions() { if (data.success) { loadDistributions(); } else { - alert("Error: " + data.error); + alert(interpolate( + gettext("Error: %(error)s"), + {error: data.error}, + true + )); } }) .catch((error) => console.error("Error:", error)); diff --git a/src/imgtests/web/static/js/excel_reports.js b/src/imgtests/web/static/js/excel_reports.js index cd7f0237..04b1d7b0 100644 --- a/src/imgtests/web/static/js/excel_reports.js +++ b/src/imgtests/web/static/js/excel_reports.js @@ -27,16 +27,16 @@ document.getElementById("exportBtn").addEventListener("click", function () { const distributions = getCheckedValues(".distro-checkbox"); if (tables.length === 0) { - alert("Please select at least one table."); + alert(gettext("Please select at least one table.")); return; } if (distributions.length === 0) { - alert("Please select at least one distribution."); + alert(gettext("Please select at least one distribution.")); return; } btn.disabled = true; - btn.textContent = "Generating..."; + btn.textContent = gettext("Generating..."); fetch("/api/export-excel/", { method: "POST", @@ -52,14 +52,22 @@ document.getElementById("exportBtn").addEventListener("click", function () { window.location.href = data.file_url; location.reload(); } else { - alert("Error: " + data.error); + alert(interpolate( + gettext("Error: %(error)s"), + {error: data.error}, + true + )); btn.disabled = false; - btn.textContent = "Generate New Excel Report"; + btn.textContent = gettext("Generate New Excel Report"); } }) .catch((error) => { - alert("Error: " + error); + alert(interpolate( + gettext("Error: %(error)s"), + {error: error}, + true + )); btn.disabled = false; - btn.textContent = "Generate New Excel Report"; + btn.textContent = gettext("Generate New Excel Report"); }); }); diff --git a/src/imgtests/web/static/js/html_reports.js b/src/imgtests/web/static/js/html_reports.js index b251697c..8ebc7b12 100644 --- a/src/imgtests/web/static/js/html_reports.js +++ b/src/imgtests/web/static/js/html_reports.js @@ -7,7 +7,7 @@ function fillSelect(select, data) { data.forEach((exp) => { const opt = document.createElement("option"); opt.value = exp.id; - opt.textContent = `#${exp.id} | ${exp.os} | ${exp.description || "(no description)"} | ${exp.started_at || "?"}`; + opt.textContent = `#${exp.id} | ${exp.os} | ${exp.description || gettext("(no description)")} | ${exp.started_at || "?"}`; select.appendChild(opt); }); } @@ -35,7 +35,7 @@ genBtn.addEventListener("click", function () { const id1 = parseInt(select1.value, 10); const id2 = parseInt(select2.value, 10); genBtn.disabled = true; - genBtn.textContent = "Generating..."; + genBtn.textContent = gettext("Generating..."); resultDiv.style.display = "none"; fetch("/api/generate-compare-report/", { @@ -55,25 +55,33 @@ genBtn.addEventListener("click", function () { const reportUrl = "/reports/view/" + data.report_url.replace(/\\/g, "/"); resultDiv.innerHTML = - 'Report generated! Reload page to see it'; + `${gettext("Report generated! Reload page to see it")}`; resultDiv.style.display = "block"; } else { resultDiv.innerHTML = - 'Error: ' + - (data.error || "unknown") + + '' + + interpolate( + gettext("Error: %(error)s"), + {error: data.error || gettext("unknown")}, + true + ) + ""; resultDiv.style.display = "block"; } }) .catch((err) => { resultDiv.innerHTML = - 'Request failed: ' + - err.message + + '' + + interpolate( + gettext("Request failed: %(message)s"), + {message: err.message}, + true + ) + ""; resultDiv.style.display = "block"; }) .finally(() => { genBtn.disabled = false; - genBtn.textContent = "Generate"; + genBtn.textContent = gettext("Generate"); }); }); diff --git a/src/imgtests/web/static/js/launch_test.js b/src/imgtests/web/static/js/launch_test.js index 2b2b4590..a1fc3161 100644 --- a/src/imgtests/web/static/js/launch_test.js +++ b/src/imgtests/web/static/js/launch_test.js @@ -75,8 +75,8 @@ document.getElementById("runTestsBtn").addEventListener("click", function () { } btn.disabled = true; - btn.textContent = "Running..."; - outputContainer.textContent = "Tests Running..."; + btn.textContent = gettext("Running..."); + outputContainer.textContent = gettext("Tests Running..."); fetch("/run-tests/", { method: "POST", @@ -93,20 +93,30 @@ document.getElementById("runTestsBtn").addEventListener("click", function () { .then((response) => response.json()) .then((data) => { if (data.success && data.task_id) { - outputContainer.textContent = - "Tests running... (Task ID: " + data.task_id + ")"; + outputContainer.textContent = interpolate( + gettext("Tests running... (Task ID: %(task_id)s)"), + {task_id: data.task_id}, + true + ); pollStatus(data.task_id); } else { - outputContainer.textContent = - "Error: " + (data.error || "Failed to start tests"); + outputContainer.textContent = interpolate( + gettext("Error: %(error)s"), + {error: data.error || gettext("Failed to start tests")}, + true + ); btn.disabled = false; - btn.textContent = "Run tests"; + btn.textContent = gettext("Run tests"); } }) .catch((error) => { - outputContainer.textContent = "Error: " + error; + outputContainer.textContent = interpolate( + gettext("Error: %(error)s"), + {error: error}, + true + ); btn.disabled = false; - btn.textContent = "Run tests"; + btn.textContent = gettext("Run tests"); }); }); @@ -120,15 +130,15 @@ function pollStatus(taskId) { .then((data) => { if (data.status === "running") { outputContainer.textContent = - "Tests running... Please wait."; + gettext("Tests running... Please wait."); setTimeout(checkStatus, 2000); } else if (data.status === "completed") { outputContainer.textContent = - data.output || "Tests completed successfully."; + data.output || gettext("Tests completed successfully."); btn.disabled = false; - btn.textContent = "Run tests"; + btn.textContent = gettext("Run tests"); } else if (data.status === "failed") { - let errorMsg = data.error || "Test failed"; + let errorMsg = data.error || gettext("Test failed"); if (data.stderr) { errorMsg += "\n\nError output:\n" + data.stderr; } @@ -137,17 +147,21 @@ function pollStatus(taskId) { } outputContainer.textContent = errorMsg; btn.disabled = false; - btn.textContent = "Run tests"; + btn.textContent = gettext("Run tests"); } else { - outputContainer.textContent = "Unknown status"; + outputContainer.textContent = gettext("Unknown status"); btn.disabled = false; - btn.textContent = "Run tests"; + btn.textContent = gettext("Run tests"); } }) .catch((error) => { - outputContainer.textContent = "Error checking status: " + error; + outputContainer.textContent = interpolate( + gettext("Error checking status: %(error)s"), + {error: error}, + true + ); btn.disabled = false; - btn.textContent = "Run tests"; + btn.textContent = gettext("Run tests"); }); }; diff --git a/src/imgtests/web/static/js/test_config.js b/src/imgtests/web/static/js/test_config.js index c5cfcf25..9599ae4c 100644 --- a/src/imgtests/web/static/js/test_config.js +++ b/src/imgtests/web/static/js/test_config.js @@ -18,7 +18,11 @@ class TestConfigManager { } catch (error) { console.error("Failed to initialize TestConfigManager:", error); this.showStatus( - "Failed to load configuration: " + error.message, + interpolate( + gettext("Failed to load configuration: %(message)s"), + {message: error.message}, + true + ), "error", ); } @@ -41,7 +45,11 @@ class TestConfigManager { } catch (error) { console.error("Failed to load available suites:", error); this.showStatus( - "Failed to load test suites: " + error.message, + interpolate( + gettext("Failed to load test suites: %(message)s"), + {message: error.message}, + true + ), "error", ); throw error; @@ -61,7 +69,11 @@ class TestConfigManager { } else { console.warn("No existing config, using default"); this.showStatus( - "Failed to load tests for " + window.distroName, + interpolate( + gettext("Failed to load tests for %(distro_name)s"), + {distro_name: window.distroName}, + true + ), "error", ); } @@ -146,7 +158,9 @@ class TestConfigManager { const suitesDiv = document.getElementById("suitesCheckboxes"); if (suitesDiv) { suitesDiv.innerHTML = - '

Failed to load test suites. Please refresh the page.

'; + '

' + + gettext("Failed to load test suites. Please refresh the page.") + + "

"; } return; } @@ -168,7 +182,7 @@ class TestConfigManager { console.log("Rendering suites:", suiteNames); if (suiteNames.length === 0) { - suitesDiv.innerHTML = "

No test suites available

"; + suitesDiv.innerHTML = "

" + gettext("No test suites available") + "

"; return; } @@ -199,16 +213,16 @@ class TestConfigManager {
${suiteName} - ${suiteInfo.description || "No description"} + ${suiteInfo.description || gettext("No description")}
- Default duration: ${suiteInfo.default_duration}s | - Tests: ${suiteInfo.test_count || 0} + ${gettext("Default duration:")} ${suiteInfo.default_duration}s | + ${gettext("Tests:")} ${suiteInfo.test_count || 0}
- + `; const checkbox = div.querySelector('input[type="checkbox"]'); const durationInput = div.querySelector('input[type="number"]'); @@ -563,6 +599,14 @@ class TestConfigManager { } renderSubsystemsUI() { + const subsystemLabels = { + file: gettext("File"), + IPC: gettext("IPC"), + memory: gettext("Memory"), + network: gettext("Network"), + syscalls: gettext("Syscalls"), + system: gettext("System"), + }; const subsystems = ["file","IPC","memory","network","syscalls","system"]; const container = document.getElementById("subsystemsCheckboxes"); container.innerHTML = ""; @@ -572,7 +616,7 @@ class TestConfigManager { div.innerHTML = ` `; container.appendChild(div); diff --git a/src/imgtests/web/tests_interface/templates/tests_interface/base.html b/src/imgtests/web/tests_interface/templates/tests_interface/base.html index e31e4cf2..c5a9d1d2 100644 --- a/src/imgtests/web/tests_interface/templates/tests_interface/base.html +++ b/src/imgtests/web/tests_interface/templates/tests_interface/base.html @@ -8,6 +8,7 @@ {% load static %} +
diff --git a/src/imgtests/web/tests_interface/templates/tests_interface/distro_page.html b/src/imgtests/web/tests_interface/templates/tests_interface/distro_page.html index b49818ee..3af981f0 100644 --- a/src/imgtests/web/tests_interface/templates/tests_interface/distro_page.html +++ b/src/imgtests/web/tests_interface/templates/tests_interface/distro_page.html @@ -87,44 +87,44 @@

{% translate "Individual Tests (optional):" %}

diff --git a/src/imgtests/web/tests_interface/templates/tests_interface/excel_reports.html b/src/imgtests/web/tests_interface/templates/tests_interface/excel_reports.html index de00423e..f417947d 100644 --- a/src/imgtests/web/tests_interface/templates/tests_interface/excel_reports.html +++ b/src/imgtests/web/tests_interface/templates/tests_interface/excel_reports.html @@ -15,7 +15,7 @@

{% translate "Excel Reports" %}

- Distributions: + {% translate "Distributions" %}: {% for key, desc in distributions.items %}
- Tables: + {% translate "Tables" %}:
@@ -100,7 +100,7 @@

{% translate "Excel Reports" %}

color: #8d6e63; " > - {% blocktranslate %}Total: {{ reports|length }} report(s){% endblocktranslate %} + {% blocktranslate with count=reports|length %}Total: {{ count }} report(s){% endblocktranslate %}
{% else %}
color: #8d6e63; " > - {% blocktranslate %}Total: {{ reports|length }} report(s){% endblocktranslate %} + {% blocktranslate with count=reports|length %}Total: {{ count }} report(s){% endblocktranslate %}
{% else %}