Changeset - 4005eddcc559
[Not reviewed]
i18n
0 4 1
Dennis Fink - 3 years ago 2022-01-16 21:46:21
dennis.fink@c3l.lu
Add Flask-Babel

This allows us to to i18n an l10n of the membership form.
5 files changed with 81 insertions and 4 deletions:
0 comments (0 inline, 0 general)
babel.cfg
Show inline comments
 
new file 100644
 
[python: **.py]
 
[jinja2: **/templates/**.html]
 
extensions=jinja2.ext.autoescape,jinja2.ext.with_
c3l_membership/__init__.py
Show inline comments
 
import base64
 
import json
 
import os.path
 
import secrets
 

	
 
from flask import Flask
 
from flask import Flask, g, redirect, request, url_for
 
from flask_babel import Babel
 
from flask_qrcode import QRcode
 

	
 
config_file = os.path.abspath("/etc/membership.json")
 

	
 
qrcode = QRcode()
 
babel = Babel()
 

	
 

	
 
def create_app():
 

	
 
    app = Flask(__name__)
 

	
 
    try:
 
        app.config.from_file(config_file, load=json.load)
 
    except FileNotFoundError:
 
        pass
 

	
 
    qrcode.init_app(app)
 
    babel.init_app(app)
 

	
 
    _default_secret_key = base64.b64encode(secrets.token_bytes()).decode("utf-8")
 
    app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY", _default_secret_key)
 
    app.config["LANGUAGES"] = ["en", "de", "fr", "lb"]
 

	
 
    app.config.setdefault("SUPPORTING_FEE", 40)
 
    app.config.setdefault("REGULAR_FEE", 120)
 

	
 
    app.config.setdefault("DIGICASH_ENABLED", True)
 
    app.config.setdefault("BITCOIN_ENABLED", True)
 
@@ -44,14 +48,25 @@ def create_app():
 
        "MONERO_CONVERSION_SCRIPT", "/usr/local/share/xmr/XMR_Membership.pl"
 
    )
 
    app.config.setdefault(
 
        "ZCASH_CONVERSION_SCRIPT", "/usr/local/share/zcash/ZCASH_Membership.pl"
 
    )
 

	
 
    @babel.localeselector
 
    def get_locale():
 
        if not g.get("lang_code", None):
 
            g.lang_code = request.accept_languages.best_match(app.config["LANGUAGES"])
 
        return g.lang_code
 

	
 
    from .views import root_page
 

	
 
    app.register_blueprint(root_page)
 

	
 
    @app.route("/")
 
    def home():
 
        g.lang_code = request.accept_languages.best_match(app.config["LANGUAGES"])
 
        return redirect(url_for("root.index"))
 

	
 
    return app
 

	
 

	
 
app = create_app()
c3l_membership/views.py
Show inline comments
 
import re
 
import subprocess
 
from datetime import date
 

	
 
from flask import Blueprint, current_app, render_template, request
 
from flask import Blueprint, current_app, g, render_template, request
 
from flask_weasyprint import HTML, render_pdf
 

	
 
from .forms import MembershipForm
 

	
 
root_page = Blueprint("root", __name__)
 
root_page = Blueprint("root", __name__, url_prefix="/<lang_code>")
 

	
 
xml_template = "<member><numm>{name}</numm><gebuertsdag>{birthday:%d.%m.%Y}</gebuertsdag><address>{address}</address><nick>{username}</nick><email>{email}</email><status>{status}</status><stemmrecht>{voting}</stemmrecht></member>"
 

	
 

	
 
@root_page.url_defaults
 
def add_lang_code(endpoint, values):
 
    values.setdefault("lang_code", g.lang_code)
 

	
 

	
 
@root_page.url_value_preprocessor
 
def pull_lang_code(endpoint, values):
 
    g.lang_code = values.pop("lang_code")
 

	
 

	
 
@root_page.route("/", methods=("GET", "POST"))
 
def index():
 
    form = MembershipForm()
 

	
 
    choices = [("cash", "by cash"), ("wire transfer", "by wire transfer")]
 

	
poetry.lock
Show inline comments
 
[[package]]
 
name = "babel"
 
version = "2.9.1"
 
description = "Internationalization utilities"
 
category = "main"
 
optional = false
 
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 

	
 
[package.dependencies]
 
pytz = ">=2015.7"
 

	
 
[[package]]
 
name = "black"
 
version = "21.12b0"
 
description = "The uncompromising code formatter."
 
category = "dev"
 
optional = false
 
@@ -169,12 +180,29 @@ Werkzeug = ">=2.0"
 

	
 
[package.extras]
 
async = ["asgiref (>=3.2)"]
 
dotenv = ["python-dotenv"]
 

	
 
[[package]]
 
name = "flask-babel"
 
version = "2.0.0"
 
description = "Adds i18n/l10n support to Flask applications"
 
category = "main"
 
optional = false
 
python-versions = "*"
 

	
 
[package.dependencies]
 
Babel = ">=2.3"
 
Flask = "*"
 
Jinja2 = ">=2.5"
 
pytz = "*"
 

	
 
[package.extras]
 
dev = ["pytest", "pytest-mock", "bumpversion", "ghp-import", "sphinx", "pallets-sphinx-themes"]
 

	
 
[[package]]
 
name = "flask-qrcode"
 
version = "3.0.0"
 
description = "A concise Flask extension to render QR codes on Jinja2 templates using python-qrcode"
 
category = "main"
 
optional = false
 
python-versions = "*"
 
@@ -371,12 +399,20 @@ python-versions = ">=3.7"
 

	
 
[package.extras]
 
doc = ["sphinx", "sphinx-rtd-theme"]
 
test = ["pytest", "pytest-cov", "pytest-flake8", "pytest-isort", "coverage"]
 

	
 
[[package]]
 
name = "pytz"
 
version = "2021.3"
 
description = "World timezone definitions, modern and historical"
 
category = "main"
 
optional = false
 
python-versions = "*"
 

	
 
[[package]]
 
name = "qrcode"
 
version = "7.3.1"
 
description = "QR Code image generator"
 
category = "main"
 
optional = false
 
python-versions = ">=3.6"
 
@@ -505,15 +541,19 @@ python-versions = ">=3.6"
 
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
 
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
 

	
 
[metadata]
 
lock-version = "1.1"
 
python-versions = ">=3.7.0,<4"
 
content-hash = "71f2f5db862ef41b627c0a05e0c0b4ceaf7aa1316f8cd13232df304a470dacf4"
 
content-hash = "e6337b7e5ae01abe852dbd202497fef50c09546e0a0f98f26b3ee81beb262237"
 

	
 
[metadata.files]
 
babel = [
 
    {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"},
 
    {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"},
 
]
 
black = [
 
    {file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"},
 
    {file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"},
 
]
 
cairocffi = [
 
    {file = "cairocffi-1.3.0.tar.gz", hash = "sha256:108a3a7cb09e203bdd8501d9baad91d786d204561bd71e9364e8b34897c47b91"},
 
@@ -602,12 +642,16 @@ email-validator = [
 
    {file = "email_validator-1.1.3.tar.gz", hash = "sha256:aa237a65f6f4da067119b7df3f13e89c25c051327b2b5b66dc075f33d62480d7"},
 
]
 
flask = [
 
    {file = "Flask-2.0.2-py3-none-any.whl", hash = "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a"},
 
    {file = "Flask-2.0.2.tar.gz", hash = "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2"},
 
]
 
flask-babel = [
 
    {file = "Flask-Babel-2.0.0.tar.gz", hash = "sha256:f9faf45cdb2e1a32ea2ec14403587d4295108f35017a7821a2b1acb8cfd9257d"},
 
    {file = "Flask_Babel-2.0.0-py3-none-any.whl", hash = "sha256:e6820a052a8d344e178cdd36dd4bb8aea09b4bda3d5f9fa9f008df2c7f2f5468"},
 
]
 
flask-qrcode = [
 
    {file = "Flask-QRcode-3.0.0.tar.gz", hash = "sha256:96a49da1396a600e79cc4b119610a2e61cb1433f9449994eabf36bbe1478b96b"},
 
]
 
flask-weasyprint = [
 
    {file = "Flask-WeasyPrint-0.6.tar.gz", hash = "sha256:ceb48d15dca49d6f32be60a19fb6d6a43f0668978ac8af4240292b85630652b1"},
 
    {file = "Flask_WeasyPrint-0.6-py2.py3-none-any.whl", hash = "sha256:688424cd47e1b06915feeb295c4a03df667222865676c3029ed52a6be5622caf"},
 
@@ -793,12 +837,16 @@ pycparser = [
 
    {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
 
]
 
pyphen = [
 
    {file = "pyphen-0.12.0-py3-none-any.whl", hash = "sha256:459020cd320eb200c0c5ba46b98b2278fd34c5546f520fdcd2ce5f8d733eb994"},
 
    {file = "pyphen-0.12.0.tar.gz", hash = "sha256:b7d3dfc24b6f2178cdb2b1757ace0bd5d222de3e62c28d22ac578c5f22a13e9b"},
 
]
 
pytz = [
 
    {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
 
    {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
 
]
 
qrcode = [
 
    {file = "qrcode-7.3.1.tar.gz", hash = "sha256:375a6ff240ca9bd41adc070428b5dfc1dcfbb0f2507f1ac848f6cded38956578"},
 
]
 
six = [
 
    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
 
    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
pyproject.toml
Show inline comments
 
@@ -13,12 +13,13 @@ Flask-QRcode = "^3.0.0"
 
Flask-WeasyPrint = "^0.6"
 
Flask-WTF = "^1.0.0"
 
email-validator = "^1.1.3"
 
WTForms="^3.0.1"
 
WeasyPrint="52.5"
 
djhtml = "^1.4.11"
 
Flask-Babel = "^2.0.0"
 

	
 
[tool.poetry.dev-dependencies]
 
black = "^21.12b0"
 
mypy = "^0.930"
 
isort = "^5.10.1"
 

	
0 comments (0 inline, 0 general)