Skip to content

Add Russian (ru) translation#4236

Open
Marfa wants to merge 5 commits into
dgtlmoon:masterfrom
Marfa:add-russian-translation
Open

Add Russian (ru) translation#4236
Marfa wants to merge 5 commits into
dgtlmoon:masterfrom
Marfa:add-russian-translation

Conversation

@Marfa

@Marfa Marfa commented Jun 23, 2026

Copy link
Copy Markdown

Summary

  • Add Russian (ru) gettext catalog based on en_US (~993 strings)
  • Document ru in the translations README
  • Extend i18n tests to verify key settings-page labels in Russian

Test plan

  • python setup.py compile_catalog
  • dennis-cmd lint --errorsonly changedetectionio/translations/ru/
  • pytest changedetectionio/tests/test_i18n.py::test_time_unit_translations
  • Switch UI language to Russian and spot-check main pages

Introduce a full Russian gettext catalog based on en_US, document ru in the translations guide, and extend i18n coverage tests for the settings page.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Marfa

Marfa commented Jun 23, 2026

Copy link
Copy Markdown
Author

Manual spot-check: Russian UI

Tested locally at http://127.0.0.1:5050 after switching language to Русский.

Page Result
/ (watchlist) ✓ Language selector shows Русский
/settings Интервал проверки, Часы, Минуты, Секунды, Расширение Chrome
/tags/list ✓ loads in Russian
/imports/import Импорт
/backups/ Резервные копии
/edit/<uuid> ✓ tabs Общий, Запрос, Уведомления, Статистика

Automated checks also pass:

  • pytest changedetectionio/tests/test_i18n.py::test_time_unit_translations
  • pytest changedetectionio/tests/test_i18n.py::test_language_switching

Konstantin and others added 2 commits June 25, 2026 13:15
Fixes lint-translations CI check for the Russian locale PR.

Co-authored-by: Cursor <cursoragent@cursor.com>
The previous Babel sync stripped msgids that CI still extracts, causing
lint-translations to fail. Revert non-ru catalogs to upstream master and
update ru from the full messages.pot template.

Co-authored-by: Cursor <cursoragent@cursor.com>
@dgtlmoon

Copy link
Copy Markdown
Owner

thanks, checking again

@AmirF194 AmirF194 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structurally this looks clean and safe to merge. I want to be upfront that I can vouch for the structure, not the quality of the Russian itself, that needs a native speaker.

What I could verify: placeholder parity is intact. Across the 993 entries, the printf placeholders (%(name)s, %s, %d), brace placeholders ({count}, {name}), and HTML tags are all preserved with nothing dropped or altered, and CI backs this independently since lint-translations runs msgfmt --check-format and dennis-cmd lint --strict, both green. Registration is correct and not orphaned: get_available_languages() offers a language only when both a LANGUAGE_DATA entry and the .po exist, and the ru entry (Русский) is already on master, so dropping in the .po activates it with no hardcoded list to edit. The header is right (utf-8, Language: ru, nplurals=3), there are no fuzzy markers, and I loaded the committed .mo through gettext and it returns the expected Russian. The catalog-sync CI step also passed, which means the 993 msgids match the current .pot exactly.

No blocking concerns. One optional note: there are 26 genuinely empty msgstr entries (a naive grep reports more, but most of those are multiline continuations). They fall back to English at runtime, so nothing breaks, and the most visible ones are the lowercase relative-time units in flask_app.py (hour, minute, and so on) that show up in "X ago" timestamps. Filling those in would remove the English leakage but is not required. Minor doc nit: the README language table lists ru slightly out of alphabetical order (tr, ru, uk).

@Marfa

Marfa commented Jul 6, 2026

Copy link
Copy Markdown
Author

I am a native Russian speaker. I didn't check all strings, but what I saw looks correct.

Should I fix issues from the note?

@AmirF194

AmirF194 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Thanks, and your native-speaker read covers the exact part I couldn't check myself, so that's the main thing.

None of the note is blocking, so please don't feel obligated. It's structurally sound and fine to merge as-is if @dgtlmoon would rather land it and polish later.

If you do want to fill the gaps, the 26 empty msgstr split by how visible they are:

  1. Highest value: the relative-time units at flask_app.py:331-343 (year, years, month, months, week, weeks, day, days, hour, hours, minute, minutes, second). These render in the "X ago" timestamps on the watch overview, so right now a Russian user sees "5 minutes" there instead of the Russian. The capitalized settings labels like Seconds are already done, it's only these lowercase duration words.
  2. The content-analysis / Levenshtein strings on the diff stats tab (Diff, Content Analysis, Word count (latest snapshot), Similarity ratio, and the rest of that block). Lower traffic, still nice.
  3. The README ordering is cosmetic, take it or leave it.

So I'd suggest group 1 for a quick high-impact pass and the rest whenever. Either way the PR looks good.

@dgtlmoon

dgtlmoon commented Jul 6, 2026

Copy link
Copy Markdown
Owner

time units absolutely need to be fixed before this can be merged

@Marfa

Marfa commented Jul 6, 2026

Copy link
Copy Markdown
Author

Will do

Konstantin and others added 2 commits July 6, 2026 23:16
Translate relative-time units (year/minute/etc.), Levenshtein stats
labels, and content-analysis strings. Sort ru before tr in the README table.

Co-authored-by: Cursor <cursoragent@cursor.com>
Align multiline Levenshtein msgstr wrap with Babel width=120 formatting.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants