From fc49858cc5d0a0438edf8f753a58ae13ba29f667 Mon Sep 17 00:00:00 2001 From: Tom Wojcik Date: Sun, 2 Jul 2023 12:28:25 +0200 Subject: [PATCH 1/4] add test_constants_translations_are_up_to_date, fix broken translations --- djoser/locale/ja/LC_MESSAGES/django.po | 12 +------ djoser/locale/pl/LC_MESSAGES/django.po | 11 +------ djoser/locale/pt_BR/LC_MESSAGES/django.po | 12 +------ djoser/locale/ru_RU/LC_MESSAGES/django.po | 11 +------ .../testapp/tests/test_translations.py | 32 +++++++++++++++++++ 5 files changed, 36 insertions(+), 42 deletions(-) create mode 100644 testproject/testapp/tests/test_translations.py diff --git a/djoser/locale/ja/LC_MESSAGES/django.po b/djoser/locale/ja/LC_MESSAGES/django.po index 999d7c30..c772afe7 100644 --- a/djoser/locale/ja/LC_MESSAGES/django.po +++ b/djoser/locale/ja/LC_MESSAGES/django.po @@ -15,7 +15,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: djoser/constants.py:4 -msgid "Unable to login with provided credentials." +msgid "Unable to log in with provided credentials." msgstr "入力された情報でログインできませんでした。" #: djoser/constants.py:5 @@ -55,16 +55,6 @@ msgstr "入力されたemailを使用しているユーザーは見つかりま msgid "Unable to create account." msgstr "アカウント作成失敗。" -#: djoser/constants.py:15 -msgid "" -"User model does not contain specified email field. Please see http://djoser." -"readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME for more " -"details." -msgstr "" -"指定されたemailフィールドを持つユーザーモデルが存在しません。 " -"http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME " -"上記から詳細を確認してください。" - #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" diff --git a/djoser/locale/pl/LC_MESSAGES/django.po b/djoser/locale/pl/LC_MESSAGES/django.po index c1b9b9dc..99a26b8c 100644 --- a/djoser/locale/pl/LC_MESSAGES/django.po +++ b/djoser/locale/pl/LC_MESSAGES/django.po @@ -17,7 +17,7 @@ msgstr "" "%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n" "%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" #: djoser/constants.py:4 -msgid "Unable to login with provided credentials." +msgid "Unable to log in with provided credentials." msgstr "Nie udało się zalogować przy pomocy tych danych." #: djoser/constants.py:5 @@ -57,15 +57,6 @@ msgstr "Użytkownik z tym adresem email nie istnieje." msgid "Unable to create account." msgstr "Nie udało się stworzyć konta." -#: djoser/constants.py:15 -msgid "" -"User model does not contain specified email field. Please see http://djoser." -"readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME for more " -"details." -msgstr "Model użytkownika nie zawiera wskazanego pola email. Zobacz " -"http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME " -"by zobaczyć więcej szczegółów" - #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" diff --git a/djoser/locale/pt_BR/LC_MESSAGES/django.po b/djoser/locale/pt_BR/LC_MESSAGES/django.po index 80d62eb6..68cf7b5f 100644 --- a/djoser/locale/pt_BR/LC_MESSAGES/django.po +++ b/djoser/locale/pt_BR/LC_MESSAGES/django.po @@ -15,7 +15,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: djoser/constants.py:4 -msgid "Unable to login with provided credentials." +msgid "Unable to log in with provided credentials." msgstr "Não foi possível fazer login com os dados inseridos." #: djoser/constants.py:5 @@ -55,16 +55,6 @@ msgstr "Não existe um usuário com o email fornecido." msgid "Unable to create account." msgstr "Não foi possível criar a conta." -#: djoser/constants.py:15 -msgid "" -"User model does not contain specified email field. Please see http://djoser." -"readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME for more " -"details." -msgstr "" -"O usuário fornecido não possui campo de email definido. Por favor, confira " -"http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME " -"para mais detalhes." - #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" diff --git a/djoser/locale/ru_RU/LC_MESSAGES/django.po b/djoser/locale/ru_RU/LC_MESSAGES/django.po index 8c9b4bed..61fde784 100644 --- a/djoser/locale/ru_RU/LC_MESSAGES/django.po +++ b/djoser/locale/ru_RU/LC_MESSAGES/django.po @@ -20,7 +20,7 @@ msgstr "" "X-Poedit-SearchPath-0: .\n" #: djoser/constants.py:4 -msgid "Unable to login with provided credentials." +msgid "Unable to log in with provided credentials." msgstr "Невозможно войти с предоставленными учетными данными." #: djoser/constants.py:5 @@ -60,15 +60,6 @@ msgstr "Пользователь с данным адресом электрон msgid "Unable to create account." msgstr "Невозможно создать учетную запись." -#: djoser/constants.py:15 -msgid "" -"User model does not contain specified email field. Please see http://djoser." -"readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME for more details." -msgstr "" -"Модель пользователя не содержит указанное поле для электронной почты. Пожалуйста, " -"посмотрите http://djoser.readthedocs.io/en/latest/settings." -"html#USER_EMAIL_FIELD_NAME для получения дополнительной информации." - #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" diff --git a/testproject/testapp/tests/test_translations.py b/testproject/testapp/tests/test_translations.py new file mode 100644 index 00000000..9463a775 --- /dev/null +++ b/testproject/testapp/tests/test_translations.py @@ -0,0 +1,32 @@ +from io import StringIO + +from babel.messages.pofile import read_po +from django.utils.encoding import force_str +import pathlib + +from djoser.constants import Messages + + +def test_constants_translations_are_up_to_date(): + messages = set(force_str(v) for k, v in vars(Messages).items() if k.isupper()) + ERROR_TEMPALTE = "Error message '{message}' was found in locale {locale} but can't be found in the messages class" + + root = pathlib.Path(__file__).parent.parent.parent.parent + locale_dir = root / 'djoser' / 'locale' + for specific_locale in locale_dir.iterdir(): + po_file = specific_locale / 'LC_MESSAGES' / 'django.po' + po_contents = po_file.read_text() + with StringIO() as buf: + buf.write(po_contents) + buf.seek(0) + parsed_po = read_po(buf) + for message in parsed_po: + if not message.id: + continue + if 'djoser/constants.py' not in [loc[0] for loc in message.locations]: + continue + if message.id not in messages: + raise ValueError(ERROR_TEMPALTE.format( + message=message.id, + locale=specific_locale.name + )) From e4e9eeaf78e8977f7f290f4a02f49e79c4a76405 Mon Sep 17 00:00:00 2001 From: uichi <37263474+uichi@users.noreply.github.com> Date: Mon, 7 Feb 2022 16:12:40 +0900 Subject: [PATCH 2/4] Modify Japanese translations --- djoser/locale/ja/LC_MESSAGES/django.po | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/djoser/locale/ja/LC_MESSAGES/django.po b/djoser/locale/ja/LC_MESSAGES/django.po index c772afe7..dcef4689 100644 --- a/djoser/locale/ja/LC_MESSAGES/django.po +++ b/djoser/locale/ja/LC_MESSAGES/django.po @@ -53,12 +53,12 @@ msgstr "入力されたemailを使用しているユーザーは見つかりま #: djoser/constants.py:13 msgid "Unable to create account." -msgstr "アカウント作成失敗。" +msgstr "アカウントを作成できませんでした。" #: djoser/templates/email/activation.html:4 #, python-format msgid "Account activation on %(site_name)s" -msgstr "%(site_name)s のアカウントを有効化してください" +msgstr "%(site_name)s でアカウントを有効化してください" #: templates/email/activation.html:8 templates/email/activation.html:19 #, python-format @@ -66,13 +66,12 @@ msgid "" "You're receiving this email because you need to finish activation process on " "%(site_name)s." msgstr "" -"アカウントの有効化を忘れずに行ってください。 " -"%(site_name)s." +"%(site_name)s でアカウントを有効化する必要があります。" #: djoser/templates/email/activation.html:10 #: djoser/templates/email/activation.html:22 msgid "Please go to the following page to activate account:" -msgstr "次に記載されているページでアカウントの有効化を行ってください:" +msgstr "こちらのページでアカウントの有効化を行ってください:" #: djoser/templates/email/activation.html:13 #: djoser/templates/email/activation.html:25 @@ -91,7 +90,7 @@ msgstr "ご利用ありがとうございます!" #: djoser/templates/email/password_reset.html:28 #, python-format msgid "The %(site_name)s team" -msgstr "チーム %(site_name)s" +msgstr "%(site_name)s チーム" #: djoser/templates/email/confirmation.html:4 #, python-format @@ -102,7 +101,7 @@ msgstr "%(site_name)s - アカウントの有効化が完了しました!" #: djoser/templates/email/confirmation.html:8 #: djoser/templates/email/confirmation.html:16 msgid "Your account has been created and is ready to use!" -msgstr "アカウントの有効化が完了し使用可能となりました!" +msgstr "アカウントが有効になりました!" #: djoser/templates/email/password_reset.html:4 #, python-format @@ -116,14 +115,14 @@ msgid "" "You're receiving this email because you requested a password reset for your " "user account at %(site_name)s." msgstr "" -"%(site_name)s のパスワードをリセットするためのemailとなります。" +"%(site_name)s のパスワードリセットを受け付けました。" #: djoser/templates/email/password_reset.html:10 #: djoser/templates/email/password_reset.html:22 msgid "Please go to the following page and choose a new password:" -msgstr "次のページにて新規パスワードを登録してください:" +msgstr "こちらのページで新規パスワードを登録してください:" #: djoser/templates/email/password_reset.html:12 #: djoser/templates/email/password_reset.html:24 msgid "Your username, in case you've forgotten:" -msgstr "念のためこちらがユーザーネームとなります:" +msgstr "ユーザーネーム:" From 95c468721ff21b8f09a25abdec63eb05ecb3c0d0 Mon Sep 17 00:00:00 2001 From: Tom Wojcik Date: Sun, 2 Jul 2023 12:37:56 +0200 Subject: [PATCH 3/4] add babel to test deps --- poetry.lock | 7 ++++--- pyproject.toml | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 00cb3122..220fcc59 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. [[package]] name = "alabaster" @@ -1222,7 +1222,8 @@ files = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, @@ -1713,4 +1714,4 @@ webauthn = ["webauthn"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "d8730b81fd2ed5f2fb36b7bd7f0c8303b9817254e716f9d42e14fa9666723da7" +content-hash = "4b8e29ce8141ab945560299f666ba070b6dd7c9ce3f0062bbcfaf0ae4a58fee7" diff --git a/pyproject.toml b/pyproject.toml index f05c7732..40be9aa8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,6 +54,7 @@ coverage = "^7.2.2" pytest-cov = "^4.0.0" pytest-django = "^4.5.2" tox = "^4.4.8" +babel = "^2.12.1" [tool.poetry.group.code-quality.dependencies] black = "^23.1.0" From a0c8a7358533d6e686ef9671bee9307c53306c22 Mon Sep 17 00:00:00 2001 From: Tom Wojcik Date: Sun, 2 Jul 2023 12:44:34 +0200 Subject: [PATCH 4/4] fix linting --- .../testapp/tests/test_translations.py | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/testproject/testapp/tests/test_translations.py b/testproject/testapp/tests/test_translations.py index 9463a775..4dc79046 100644 --- a/testproject/testapp/tests/test_translations.py +++ b/testproject/testapp/tests/test_translations.py @@ -8,13 +8,16 @@ def test_constants_translations_are_up_to_date(): - messages = set(force_str(v) for k, v in vars(Messages).items() if k.isupper()) - ERROR_TEMPALTE = "Error message '{message}' was found in locale {locale} but can't be found in the messages class" + messages = {force_str(v) for k, v in vars(Messages).items() if k.isupper()} + ERROR_TEMPALTE = ( + "Error message '{message}' was found in " + "locale {locale} but can't be found in the messages class" + ) root = pathlib.Path(__file__).parent.parent.parent.parent - locale_dir = root / 'djoser' / 'locale' + locale_dir = root / "djoser" / "locale" for specific_locale in locale_dir.iterdir(): - po_file = specific_locale / 'LC_MESSAGES' / 'django.po' + po_file = specific_locale / "LC_MESSAGES" / "django.po" po_contents = po_file.read_text() with StringIO() as buf: buf.write(po_contents) @@ -23,10 +26,11 @@ def test_constants_translations_are_up_to_date(): for message in parsed_po: if not message.id: continue - if 'djoser/constants.py' not in [loc[0] for loc in message.locations]: + if "djoser/constants.py" not in [loc[0] for loc in message.locations]: continue if message.id not in messages: - raise ValueError(ERROR_TEMPALTE.format( - message=message.id, - locale=specific_locale.name - )) + raise ValueError( + ERROR_TEMPALTE.format( + message=message.id, locale=specific_locale.name + ) + )