diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index b2c1060..dbaea9a 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -50,6 +50,29 @@ jobs: run: | python -m flake8 snikket_web + translation-check: + runs-on: ubuntu-latest + + name: 'lint: i18n' + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: '3.9' + - name: Install + run: | + set -euo pipefail + pip install flask-babel + - name: Linting + run: | + sed -ri '/^"POT-Creation-Date: /d' snikket_web/translations/messages.pot + git add snikket_web/translations/messages.pot + make extract_translations + sed -ri '/^"POT-Creation-Date: /d' snikket_web/translations/messages.pot + git diff --exit-code --color -- snikket_web/translations/messages.pot + + build: runs-on: ubuntu-latest diff --git a/babel.cfg b/babel.cfg index d82fb6e..4a6f19b 100644 --- a/babel.cfg +++ b/babel.cfg @@ -1,4 +1,3 @@ [python: snikket_web/**.py] [jinja2: snikket_web/templates/**.html] [jinja2: snikket_web/templates/**.j2] -extensions=jinja2.ext.autoescape,jinja2.ext.with_ diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 5aeb33d..8fcae91 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -5,4 +5,4 @@ export SNIKKET_WEB_DOMAIN="$SNIKKET_DOMAIN" export SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE="${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE-127.0.0.1}" export SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT="${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT-5765}" -exec hypercorn -b "${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE}:${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT}" 'snikket_web:create_app()' +exec hypercorn -b "${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE}:${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT}" --access-logfile=- --log-file=- 'snikket_web:create_app()' diff --git a/requirements.txt b/requirements.txt index 1098981..c1dfa3e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,5 +5,5 @@ hsluv~=5.0 flask-babel~=1.0 email-validator~=1.1 environ-config~=20.0 -wtforms~=2.3 +wtforms~=3.0 typing-extensions diff --git a/snikket_web/__init__.py b/snikket_web/__init__.py index b352cc1..493fca3 100644 --- a/snikket_web/__init__.py +++ b/snikket_web/__init__.py @@ -147,9 +147,13 @@ class AppConfig: site_name = environ.var("") avatar_cache_ttl = environ.var(1800, converter=int) languages = environ.var([ + # Keep `en` as the first language, because it is used as a fallback + # if the language negotiation cannot find another match. It is more + # likely that users are able to read english (or find a suitable + # online translator) than, for instance, danish. + "en", "da", "de", - "en", "fr", "id", "it", diff --git a/snikket_web/admin.py b/snikket_web/admin.py index afcb9b7..05fe166 100644 --- a/snikket_web/admin.py +++ b/snikket_web/admin.py @@ -12,7 +12,6 @@ import werkzeug.exceptions import quart.flask_patch import wtforms -import wtforms.fields.html5 from quart import ( Blueprint, diff --git a/snikket_web/infra.py b/snikket_web/infra.py index c5e9ef0..12ce581 100644 --- a/snikket_web/infra.py +++ b/snikket_web/infra.py @@ -8,6 +8,7 @@ import quart.flask_patch # noqa:F401 from quart import ( current_app, request, + g, ) import flask_babel @@ -34,6 +35,7 @@ BYTE_UNIT_SCALE_MAP = [ @babel.localeselector # type:ignore def selected_locale() -> str: + g.language_header_accessed = True selected = request.accept_languages.best_match( current_app.config['LANGUAGES'] ) or current_app.config['LANGUAGES'][0] @@ -68,6 +70,12 @@ def format_bytes(n: float) -> str: return "{} {}".format(n, unit) +def add_vary_language_header(resp: quart.Response) -> quart.Response: + if getattr(g, "language_header_accessed", False): + resp.vary.add("Accept-Language") + return resp + + def init_templating(app: quart.Quart) -> None: app.template_filter("repr")(repr) app.template_filter("format_datetime")(flask_babel.format_datetime) @@ -78,6 +86,7 @@ def init_templating(app: quart.Quart) -> None: app.template_filter("format_bytes")(format_bytes) app.template_filter("flatten")(flatten) app.template_filter("circle_name")(circle_name) + app.after_request(add_vary_language_header) def generate_error_id() -> str: diff --git a/snikket_web/main.py b/snikket_web/main.py index 73b3ff2..286ee1d 100644 --- a/snikket_web/main.py +++ b/snikket_web/main.py @@ -34,7 +34,7 @@ bp = quart.Blueprint("main", __name__) class LoginForm(BaseForm): - address = wtforms.TextField( + address = wtforms.StringField( _l("Address"), validators=[wtforms.validators.InputRequired()], ) @@ -93,10 +93,16 @@ async def login() -> typing.Union[str, werkzeug.Response]: @bp.route("/meta/about.html") async def about() -> str: version = None + core_versions = {} extra_versions = {} - if current_app.debug or client.is_admin_session: version = _version.version + try: + core_versions["Prosody"] = await client.get_server_version() + except werkzeug.exceptions.Unauthorized: + core_versions["Prosody"] = "unknown" + + if current_app.debug: extra_versions["aiohttp"] = aiohttp.__version__ extra_versions["babel"] = babel.__version__ extra_versions["wtforms"] = wtforms.__version__ @@ -110,6 +116,7 @@ async def about() -> str: "about.html", version=version, extra_versions=extra_versions, + core_versions=core_versions, ) diff --git a/snikket_web/templates/about.html b/snikket_web/templates/about.html index 001eb50..b6e4b05 100644 --- a/snikket_web/templates/about.html +++ b/snikket_web/templates/about.html @@ -17,9 +17,12 @@
{% trans trademarks_url="https://snikket.org/about/trademarks/" %}“Snikket” and the parrot logo are trademarks of Snikket Community Interest Company. For more information about the trademarks, visit the Snikket Trademarks information page.{% endtrans %}
Snikket Server
-Domain: {{ config["SNIKKET_DOMAIN"] }}
-Snikket Web Portal{% if version %} ({{ version }}){% endif %}
+ Domain: {{ config["SNIKKET_DOMAIN"] }}
+Web Portal{% if version %} ({{ version }}){% endif %}
+{%- if core_versions -%}
+{% for name, version in core_versions.items() %}
+{{ name }} ({{ version }}){% endfor %}
+{%- endif -%}
{%- if extra_versions -%}
{% for name, version in extra_versions.items() %}
{{ name }} ({{ version }}){% endfor %}
diff --git a/snikket_web/templates/user_manage_data.html b/snikket_web/templates/user_manage_data.html
index 0f958e8..8fcb9e6 100644
--- a/snikket_web/templates/user_manage_data.html
+++ b/snikket_web/templates/user_manage_data.html
@@ -11,6 +11,8 @@
{% call render_errors(form) %}{% endcall %}
+ {%- call standard_button("back", url_for('.index'), class="tertiary") %}{% trans %}Back{% endtrans %}{% endcall -%}
+