From c270edff159ca82aa671068ba1fe89642584838f Mon Sep 17 00:00:00 2001 From: Stefan Allius <122395479+s-allius@users.noreply.github.com> Date: Sat, 19 Apr 2025 16:51:06 +0200 Subject: [PATCH] S allius/issue385 (#386) * ignore translation and log files * add quart-babel * build and install translation files * don't export the web-ui port 8127 - for security reason the user should use the HA ingress and not the direkt access to the web dashboard * set 'lang' in html tag --- .gitignore | 4 ++++ Makefile | 5 +++-- app/.dockerignore | 4 +++- app/Makefile | 24 +++++++++++++++++--- app/requirements.txt | 3 ++- app/src/.babel.cfg | 2 ++ app/src/server.py | 20 ++++++++++++++++- app/src/web/templates/base.html | 2 +- app/src/web/templates/index.html | 2 +- app/translations/de/LC_MESSAGES/messages.po | 25 +++++++++++++++++++++ ha_addons/Makefile | 12 +++++++++- ha_addons/templates/config.jinja | 2 +- 12 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 app/src/.babel.cfg create mode 100644 app/translations/de/LC_MESSAGES/messages.po diff --git a/.gitignore b/.gitignore index 3e39de3..4fde1fe 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ Doku/** .env .venv coverage.xml +*.pot +*.mo +*.log +*.log.* diff --git a/Makefile b/Makefile index 49be846..a6549e2 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,13 @@ -.PHONY: build clean addon-dev addon-debug addon-rc addon-rel debug dev preview rc rel check-docker-compose install +.PHONY: build babel clean addon-dev addon-debug addon-rc addon-rel debug dev preview rc rel check-docker-compose install -debug dev preview rc rel: +babel debug dev preview rc rel: $(MAKE) -C app $@ clean build: $(MAKE) -C ha_addons $@ addon-dev addon-debug addon-rc addon-rel: + $(MAKE) -C app babel $(MAKE) -C ha_addons $(patsubst addon-%,%,$@) check-docker-compose: diff --git a/app/.dockerignore b/app/.dockerignore index a746428..6348e0f 100644 --- a/app/.dockerignore +++ b/app/.dockerignore @@ -2,4 +2,6 @@ tests/ **/__pycache__ *.pyc .DS_Store -build.sh \ No newline at end of file +build.sh +*.pot +*.po \ No newline at end of file diff --git a/app/Makefile b/app/Makefile index dff4631..f380714 100644 --- a/app/Makefile +++ b/app/Makefile @@ -6,10 +6,16 @@ IMAGE = tsun-gen3-proxy # Folders -SRC=. +APP=. +SRC=$(APP)/src +# Folders for Babel translation +BABEL_INPUT_JINJA=$(SRC)/web/templates +BABEL_INPUT= $(foreach dir,$(BABEL_INPUT_JINJA),$(wildcard $(dir)/*.html)) \ + +BABEL_TRANSLATIONS=$(APP)/translations export BUILD_DATE := ${shell date -Iminutes} -VERSION := $(shell cat $(SRC)/.version) +VERSION := $(shell cat $(APP)/.version) export MAJOR := $(shell echo $(VERSION) | cut -f1 -d.) PUBLIC_URL := $(shell echo $(PUBLIC_CONTAINER_REGISTRY) | cut -f1 -d/) @@ -39,5 +45,17 @@ preview rel: export IMAGE=$(PUBLIC_CONTAINER_REGISTRY)$(IMAGE) && \ docker buildx bake -f docker-bake.hcl $@ +babel: $(BABEL_TRANSLATIONS)/de/LC_MESSAGES/messages.mo $(BABEL_TRANSLATIONS)/de/LC_MESSAGES/messages.po $(BABEL_TRANSLATIONS)/messages.pot -.PHONY: debug dev preview rc rel +$(BABEL_TRANSLATIONS)/%.pot : $(SRC)/.babel.cfg $(BABEL_INPUT) + @mkdir -p $(@D) + @pybabel extract -F $< --project=$(IMAGE) --version=$(VERSION) -o $@ $(SRC) + +$(BABEL_TRANSLATIONS)/%/LC_MESSAGES/messages.po : $(BABEL_TRANSLATIONS)/messages.pot + @mkdir -p $(@D) + @pybabel update --init-missing -i $< -d $(BABEL_TRANSLATIONS) -l $* + +$(BABEL_TRANSLATIONS)/%/LC_MESSAGES/messages.mo : $(BABEL_TRANSLATIONS)/%/LC_MESSAGES/messages.po + @pybabel compile -d $(BABEL_TRANSLATIONS) -l $* + +.PHONY: babel debug dev preview rc rel diff --git a/app/requirements.txt b/app/requirements.txt index 9d636fc..c26f354 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -1,4 +1,5 @@ aiomqtt==2.3.2 schema==0.7.7 aiocron==2.1 - quart==0.20 \ No newline at end of file + quart==0.20 + quart-babel==1.0.7 \ No newline at end of file diff --git a/app/src/.babel.cfg b/app/src/.babel.cfg new file mode 100644 index 0000000..cfaa201 --- /dev/null +++ b/app/src/.babel.cfg @@ -0,0 +1,2 @@ +[python: **.py] +[jinja2: web/templates/**.html] \ No newline at end of file diff --git a/app/src/server.py b/app/src/server.py index e3fcdc1..0b5b2f4 100644 --- a/app/src/server.py +++ b/app/src/server.py @@ -4,7 +4,9 @@ import logging.handlers import os import argparse from asyncio import StreamReader, StreamWriter -from quart import Quart, Response +from quart import Quart, Response, request +from quart_babel import Babel +from quart_babel.locale import get_locale from logging import config # noqa F401 from proxy import Proxy from inverter_ifc import InverterIfc @@ -31,12 +33,28 @@ class ProxyState: ProxyState._is_up = value +def my_get_locale(): + # check how to get the locale form for the add-on - hass.selectedLanguage + # logging.info("get_locale(%s)", request.accept_languages) + return request.accept_languages.best_match( + ['de', 'en'] + ) + + app = Quart(__name__, template_folder='web/templates', static_folder='web/static') +babel = Babel(app, + locale_selector=my_get_locale, + default_translation_directories='../translations') app.register_blueprint(web_routes) +@app.context_processor +def utility_processor(): + return dict(lang=get_locale()) + + @app.route('/-/ready') async def ready(): if ProxyState.is_up(): diff --git a/app/src/web/templates/base.html b/app/src/web/templates/base.html index e91b9fb..5227c58 100644 --- a/app/src/web/templates/base.html +++ b/app/src/web/templates/base.html @@ -1,5 +1,5 @@ - + {% block title %}{% endblock title %} diff --git a/app/src/web/templates/index.html b/app/src/web/templates/index.html index e7de164..806c68a 100644 --- a/app/src/web/templates/index.html +++ b/app/src/web/templates/index.html @@ -2,7 +2,7 @@ {% block title %} TSUN Proxy - Dashboard {% endblock title%} {% block menu1_class %}w3-blue{% endblock %} -{% block headline %} My Dashboard{% endblock headline %} +{% block headline %} {{_('My Dashboard')}}{% endblock headline %} {% block content %}
diff --git a/app/translations/de/LC_MESSAGES/messages.po b/app/translations/de/LC_MESSAGES/messages.po new file mode 100644 index 0000000..d76f60d --- /dev/null +++ b/app/translations/de/LC_MESSAGES/messages.po @@ -0,0 +1,25 @@ +# German translations for tsun-gen3-proxy. +# Copyright (C) 2025 ORGANIZATION +# This file is distributed under the same license as the tsun-gen3-proxy +# project. +# FIRST AUTHOR , 2025. +# +msgid "" +msgstr "" +"Project-Id-Version: tsun-gen3-proxy 0.14.0\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2025-04-18 20:46+0200\n" +"PO-Revision-Date: 2025-04-18 16:24+0200\n" +"Last-Translator: FULL NAME \n" +"Language: de\n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.17.0\n" + +#: src/web/templates/index.html:5 +msgid "My Dashboard" +msgstr "Mein Dashboard" + diff --git a/ha_addons/Makefile b/ha_addons/Makefile index 33f0c86..505db46 100644 --- a/ha_addons/Makefile +++ b/ha_addons/Makefile @@ -12,11 +12,14 @@ IMAGE = tsun-gen3-addon SRC=../app SRC_PROXY=$(SRC)/src CNF_PROXY=$(SRC)/config +TRANSLATION_PROXY=$(SRC)/translations # Target folders for building the local add-on and the docker container ADDON_PATH = ha_addon DST=$(ADDON_PATH)/rootfs DST_PROXY=$(DST)/home/proxy +DST_TRANSLATION=$(DST)/home/translations + # base director of the add-on repro for installing the add-on git repros INST_BASE=../../ha-addons @@ -92,12 +95,14 @@ SRC_FILES := $(wildcard $(SRC_PROXY)/*.py)\ $(wildcard $(SRC_PROXY)/web/static/images/*) CNF_FILES := $(wildcard $(CNF_PROXY)/*.toml) +MO_FILES := $(wildcard $(TRANSLATION_PROXY)/de/LC_MESSAGES/*.mo) # determine destination files TARGET_FILES = $(SRC_FILES:$(SRC_PROXY)/%=$(DST_PROXY)/%) CONFIG_FILES = $(CNF_FILES:$(CNF_PROXY)/%=$(DST_PROXY)/%) +TRANSLATION_FILES = $(MO_FILES:$(TRANSLATION_PROXY)/%=$(DST_TRANSLATION)/%) -rootfs: $(TARGET_FILES) $(CONFIG_FILES) $(DST)/requirements.txt +rootfs: $(TARGET_FILES) $(CONFIG_FILES) $(TRANSLATION_FILES) $(DST)/requirements.txt $(CONFIG_FILES): $(DST_PROXY)/% : $(CNF_PROXY)/% @echo Copy $< to $@ @@ -109,6 +114,11 @@ $(TARGET_FILES): $(DST_PROXY)/% : $(SRC_PROXY)/% @mkdir -p $(@D) @cp $< $@ +$(TRANSLATION_FILES): $(DST_TRANSLATION)/% : $(TRANSLATION_PROXY)/% + @echo Copy $< to $@ + @mkdir -p $(@D) + @cp $< $@ + $(DST)/requirements.txt : $(SRC)/requirements.txt @echo Copy $< to $@ @cp $< $@ diff --git a/ha_addons/templates/config.jinja b/ha_addons/templates/config.jinja index a381594..913e3ed 100755 --- a/ha_addons/templates/config.jinja +++ b/ha_addons/templates/config.jinja @@ -23,11 +23,11 @@ services: ports: 5005/tcp: 5005 10000/tcp: 10000 - 8127/tcp: 8127 webui: "http://[HOST]:[PORT:8127]/" watchdog: "http://[HOST]:[PORT:8127]/-/healthy" ingress: true ingress_port: 8127 +panel_icon: "mdi:application-cog-outline" # Definition of parameters in the configuration tab of the addon # parameters are available within the container as /data/options.json