Updated to flask-babel 3

This commit is contained in:
Éloi Rivard 2023-03-01 15:30:07 +01:00
parent a57c86cc2c
commit d345218557
6 changed files with 52 additions and 46 deletions

View file

@ -17,6 +17,7 @@ from flask import send_file
from flask import session from flask import session
from flask import url_for from flask import url_for
from flask_babel import gettext as _ from flask_babel import gettext as _
from flask_babel import refresh
from flask_themer import render_template from flask_themer import render_template
from werkzeug.datastructures import CombinedMultiDict from werkzeug.datastructures import CombinedMultiDict
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
@ -499,14 +500,15 @@ def profile_edit(editor, username):
): ):
user.set_password(form["password1"].data) user.set_password(form["password1"].data)
if ( if "preferredLanguage" in request.form:
"preferredLanguage" in request.form # Refresh the babel cache in case the lang is updated
and form["preferredLanguage"].data == "auto" refresh()
):
if form["preferredLanguage"].data == "auto":
user.preferredLanguage = None user.preferredLanguage = None
flash(_("Profile updated successfuly."), "success")
user.save() user.save()
flash(_("Profile updated successfuly."), "success")
return redirect(url_for("account.profile_edition", username=username)) return redirect(url_for("account.profile_edition", username=username))
return render_template( return render_template(

View file

@ -13,7 +13,7 @@ babel = Babel()
def setup_i18n(app): def setup_i18n(app):
babel.init_app(app) babel.init_app(app, locale_selector=locale_selector)
@app.before_request @app.before_request
def before_request(): def before_request():
@ -26,8 +26,7 @@ def setup_i18n(app):
} }
@babel.localeselector def locale_selector():
def localeselector():
from .flaskutils import current_user from .flaskutils import current_user
user = current_user() user = current_user()
@ -53,6 +52,4 @@ def native_language_name_from_code(code):
def available_language_codes(): def available_language_codes():
return [str(translation) for translation in babel.list_translations()] + [ return [str(translation) for translation in babel.list_translations()]
DEFAULT_LANGUAGE_CODE
]

52
poetry.lock generated
View file

@ -77,18 +77,18 @@ cryptography = ">=3.2"
[[package]] [[package]]
name = "babel" name = "babel"
version = "2.11.0" version = "2.12.1"
description = "Internationalization utilities" description = "Internationalization utilities"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.7"
files = [ files = [
{file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
{file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
] ]
[package.dependencies] [package.dependencies]
pytz = ">=2015.7" pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
[[package]] [[package]]
name = "beautifulsoup4" name = "beautifulsoup4"
@ -549,14 +549,14 @@ test = ["pytest (>=6)"]
[[package]] [[package]]
name = "faker" name = "faker"
version = "17.3.0" version = "17.4.0"
description = "Faker is a Python package that generates fake data for you." description = "Faker is a Python package that generates fake data for you."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "Faker-17.3.0-py3-none-any.whl", hash = "sha256:1dfffa43b4492b899a839619f2056060b585ba0bc76f329525194ca04dde0988"}, {file = "Faker-17.4.0-py3-none-any.whl", hash = "sha256:fdd9cc16cd7e0d8dfcd2bb19d80c1bca5ce52d79690f93bfbb13916d7ed1cb2e"},
{file = "Faker-17.3.0.tar.gz", hash = "sha256:26b2864a5332094f2c7f3968deebabce69be39ed5db4dbf22b4fa0ba3d1acdae"}, {file = "Faker-17.4.0.tar.gz", hash = "sha256:7b225dd6bc33405188f33f77c990bd08057f5c512042f7e0966e026c633ec646"},
] ]
[package.dependencies] [package.dependencies]
@ -620,24 +620,21 @@ dotenv = ["python-dotenv"]
[[package]] [[package]]
name = "flask-babel" name = "flask-babel"
version = "2.0.0" version = "3.0.1"
description = "Adds i18n/l10n support to Flask applications" description = "Adds i18n/l10n support fo Flask applications."
category = "main" category = "main"
optional = false optional = false
python-versions = "*" python-versions = ">=3.7,<4.0"
files = [ files = [
{file = "Flask-Babel-2.0.0.tar.gz", hash = "sha256:f9faf45cdb2e1a32ea2ec14403587d4295108f35017a7821a2b1acb8cfd9257d"}, {file = "flask_babel-3.0.1-py3-none-any.whl", hash = "sha256:ceb8c82039954a6b29da33ec5deb84878b78069d1ea628b21cac3f8233e9189c"},
{file = "Flask_Babel-2.0.0-py3-none-any.whl", hash = "sha256:e6820a052a8d344e178cdd36dd4bb8aea09b4bda3d5f9fa9f008df2c7f2f5468"}, {file = "flask_babel-3.0.1.tar.gz", hash = "sha256:d408cace25514bea8b92e898fd7e55877fbac79b71bc230e266ff515408eba38"},
] ]
[package.dependencies] [package.dependencies]
Babel = ">=2.3" Babel = ">=2.11.0,<3.0.0"
Flask = "*" Flask = ">=2.0.0,<3.0.0"
Jinja2 = ">=2.5" Jinja2 = ">=3.1.2,<4.0.0"
pytz = "*" pytz = ">=2022.7,<2023.0"
[package.extras]
dev = ["Pallets-Sphinx-Themes", "bumpversion", "ghp-import", "pytest", "pytest-mock", "sphinx"]
[[package]] [[package]]
name = "flask-themer" name = "flask-themer"
@ -1437,14 +1434,14 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]] [[package]]
name = "sentry-sdk" name = "sentry-sdk"
version = "1.15.0" version = "1.16.0"
description = "Python client for Sentry (https://sentry.io)" description = "Python client for Sentry (https://sentry.io)"
category = "main" category = "main"
optional = true optional = true
python-versions = "*" python-versions = "*"
files = [ files = [
{file = "sentry-sdk-1.15.0.tar.gz", hash = "sha256:69ecbb2e1ff4db02a06c4f20f6f69cb5dfe3ebfbc06d023e40d77cf78e9c37e7"}, {file = "sentry-sdk-1.16.0.tar.gz", hash = "sha256:a900845bd78c263d49695d48ce78a4bce1030bbd917e0b6cc021fc000c901113"},
{file = "sentry_sdk-1.15.0-py2.py3-none-any.whl", hash = "sha256:7ad4d37dd093f4a7cb5ad804c6efe9e8fab8873f7ffc06042dc3f3fd700a93ec"}, {file = "sentry_sdk-1.16.0-py2.py3-none-any.whl", hash = "sha256:633edefead34d976ff22e7edc367cdf57768e24bc714615ccae746d9d91795ae"},
] ]
[package.dependencies] [package.dependencies]
@ -1455,6 +1452,7 @@ urllib3 = {version = ">=1.26.11", markers = "python_version >= \"3.6\""}
[package.extras] [package.extras]
aiohttp = ["aiohttp (>=3.5)"] aiohttp = ["aiohttp (>=3.5)"]
arq = ["arq (>=0.23)"]
beam = ["apache-beam (>=2.12)"] beam = ["apache-beam (>=2.12)"]
bottle = ["bottle (>=0.12.13)"] bottle = ["bottle (>=0.12.13)"]
celery = ["celery (>=3)"] celery = ["celery (>=3)"]
@ -1808,14 +1806,14 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]] [[package]]
name = "virtualenv" name = "virtualenv"
version = "20.19.0" version = "20.20.0"
description = "Virtual Python Environment builder" description = "Virtual Python Environment builder"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "virtualenv-20.19.0-py3-none-any.whl", hash = "sha256:54eb59e7352b573aa04d53f80fc9736ed0ad5143af445a1e539aada6eb947dd1"}, {file = "virtualenv-20.20.0-py3-none-any.whl", hash = "sha256:3c22fa5a7c7aa106ced59934d2c20a2ecb7f49b4130b8bf444178a16b880fa45"},
{file = "virtualenv-20.19.0.tar.gz", hash = "sha256:37a640ba82ed40b226599c522d411e4be5edb339a0c0de030c0dc7b646d61590"}, {file = "virtualenv-20.20.0.tar.gz", hash = "sha256:a8a4b8ca1e28f864b7514a253f98c1d62b64e31e77325ba279248c65fb4fcef4"},
] ]
[package.dependencies] [package.dependencies]
@ -1951,4 +1949,4 @@ sentry = ["sentry-sdk"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.7, <4" python-versions = ">=3.7, <4"
content-hash = "900f978d01c5fa55afd81cfb2d6a995e1d087e0f5b8dd073fcd489a6378c4a2d" content-hash = "738b1b041b1a712f0f8b7a93114fa725200c16a9a22fa0e07ce270ea43e681a1"

View file

@ -41,7 +41,7 @@ authlib = ">1,<2"
click = "<9" click = "<9"
email_validator = "<2" email_validator = "<2"
flask = "<3" flask = "<3"
flask-babel = "^2.0.0" flask-babel = "^3.0.0"
flask-themer = "<2" flask-themer = "<2"
flask-wtf = "<2" flask-wtf = "<2"
pycountry = "^22.3.5" pycountry = "^22.3.5"

View file

@ -1,7 +1,8 @@
from canaille.models import User from canaille.models import User
from flask_babel import refresh
def test_preferred_language(testclient, logged_user): def test_preferred_language(slapd_server, testclient, logged_user):
logged_user.preferredLanguage = None logged_user.preferredLanguage = None
logged_user.save() logged_user.save()
@ -12,7 +13,9 @@ def test_preferred_language(testclient, logged_user):
assert "Mon profil" not in res.text assert "Mon profil" not in res.text
res.form["preferredLanguage"] = "fr" res.form["preferredLanguage"] = "fr"
res = res.form.submit(name="action", value="edit").follow() res = res.form.submit(name="action", value="edit")
assert res.flashes == [("success", "Le profil a été mis à jour avec succès.")]
res = res.follow()
logged_user = User.get(dn=logged_user.dn) logged_user = User.get(dn=logged_user.dn)
assert logged_user.preferredLanguage == "fr" assert logged_user.preferredLanguage == "fr"
assert res.form["preferredLanguage"].value == "fr" assert res.form["preferredLanguage"].value == "fr"
@ -21,7 +24,9 @@ def test_preferred_language(testclient, logged_user):
assert "Mon profil" in res.text assert "Mon profil" in res.text
res.form["preferredLanguage"] = "en" res.form["preferredLanguage"] = "en"
res = res.form.submit(name="action", value="edit").follow() res = res.form.submit(name="action", value="edit")
assert res.flashes == [("success", "Profile updated successfuly.")]
res = res.follow()
logged_user = User.get(dn=logged_user.dn) logged_user = User.get(dn=logged_user.dn)
assert logged_user.preferredLanguage == "en" assert logged_user.preferredLanguage == "en"
assert res.form["preferredLanguage"].value == "en" assert res.form["preferredLanguage"].value == "en"
@ -30,7 +35,9 @@ def test_preferred_language(testclient, logged_user):
assert "Mon profil" not in res.text assert "Mon profil" not in res.text
res.form["preferredLanguage"] = "auto" res.form["preferredLanguage"] = "auto"
res = res.form.submit(name="action", value="edit").follow() res = res.form.submit(name="action", value="edit")
assert res.flashes == [("success", "Profile updated successfuly.")]
res = res.follow()
logged_user = User.get(dn=logged_user.dn) logged_user = User.get(dn=logged_user.dn)
assert logged_user.preferredLanguage is None assert logged_user.preferredLanguage is None
assert res.form["preferredLanguage"].value == "auto" assert res.form["preferredLanguage"].value == "auto"
@ -49,6 +56,7 @@ def test_language_config(testclient, logged_user):
assert "Mon profil" not in res.text assert "Mon profil" not in res.text
testclient.app.config["LANGUAGE"] = "fr" testclient.app.config["LANGUAGE"] = "fr"
refresh()
res = testclient.get("/profile/user", status=200) res = testclient.get("/profile/user", status=200)
assert res.pyquery("html")[0].attrib["lang"] == "fr" assert res.pyquery("html")[0].attrib["lang"] == "fr"
assert "My profile" not in res.text assert "My profile" not in res.text

View file

@ -55,8 +55,9 @@ def test_edition(
] ]
res.form["preferredLanguage"] = "fr" res.form["preferredLanguage"] = "fr"
res.form["jpegPhoto"] = Upload("logo.jpg", jpeg_photo) res.form["jpegPhoto"] = Upload("logo.jpg", jpeg_photo)
res = res.form.submit(name="action", value="edit").follow() res = res.form.submit(name="action", value="edit")
assert "Profile updated successfuly." in res, str(res) assert res.flashes == [("success", "Le profil a été mis à jour avec succès.")]
res = res.follow()
logged_user = User.get(dn=logged_user.dn) logged_user = User.get(dn=logged_user.dn)
logged_user.load_groups() logged_user.load_groups()