Compare commits

..

16 Commits

Author SHA1 Message Date
Stefan Allius
9acce70317 add unit tests for all favicons 2025-04-18 03:12:02 +02:00
Stefan Allius
e1cc5c3c2c fix sonarqube warnings 2025-04-18 02:49:48 +02:00
Stefan Allius
a2866955e6 add all font and favicons to add-on 2025-04-18 01:47:10 +02:00
Stefan Allius
f422c5ba91 adapt unit tests 2025-04-18 01:29:23 +02:00
Stefan Allius
ae3cf2a68c load fonts locally 2025-04-18 01:28:43 +02:00
Stefan Allius
5cedece1b3 add more favicons formats 2025-04-18 01:27:07 +02:00
Stefan Allius
b26f7ba591 add more favicon formats 2025-04-18 01:26:11 +02:00
Stefan Allius
2ab200e199 add awesome web font 2025-04-18 01:25:18 +02:00
Stefan Allius
bf523c0713 add Roboto font 2025-04-18 01:24:19 +02:00
Stefan Allius
f33209bf8f add favicon.ico 2025-04-17 20:33:17 +02:00
Stefan Allius
9c7b891a60 add favicon.ico 2025-04-17 20:24:20 +02:00
Stefan Allius
4d3166b81f fix unit test for test dashboard 2025-04-17 18:06:17 +02:00
Stefan Allius
e31a5a2f5a add w3.css dashboard 2025-04-17 00:14:48 +02:00
Stefan Allius
5eded48ee8 add test template and stylesheet 2025-04-16 19:42:52 +02:00
Stefan Allius
7425195b8b copy web-file into the add-on container 2025-04-16 19:42:24 +02:00
Stefan Allius
3862abc8e4 configure path to web files for Quart 2025-04-16 19:41:27 +02:00
17 changed files with 26 additions and 175 deletions

4
.gitignore vendored
View File

@@ -13,7 +13,3 @@ Doku/**
.env .env
.venv .venv
coverage.xml coverage.xml
*.pot
*.mo
*.log
*.log.*

View File

@@ -1,13 +1,12 @@
.PHONY: build babel clean addon-dev addon-debug addon-rc addon-rel debug dev preview rc rel check-docker-compose install .PHONY: build clean addon-dev addon-debug addon-rc addon-rel debug dev preview rc rel check-docker-compose install
babel debug dev preview rc rel: debug dev preview rc rel:
$(MAKE) -C app $@ $(MAKE) -C app $@
clean build: clean build:
$(MAKE) -C ha_addons $@ $(MAKE) -C ha_addons $@
addon-dev addon-debug addon-rc addon-rel: addon-dev addon-debug addon-rc addon-rel:
$(MAKE) -C app babel
$(MAKE) -C ha_addons $(patsubst addon-%,%,$@) $(MAKE) -C ha_addons $(patsubst addon-%,%,$@)
check-docker-compose: check-docker-compose:

View File

@@ -3,5 +3,3 @@ tests/
*.pyc *.pyc
.DS_Store .DS_Store
build.sh build.sh
*.pot
*.po

View File

@@ -6,16 +6,10 @@ IMAGE = tsun-gen3-proxy
# Folders # Folders
APP=. SRC=.
SRC=$(APP)/src
# Folders for Babel translation
BABEL_INPUT_JINJA=$(SRC)/web/templates
BABEL_INPUT= $(foreach dir,$(BABEL_INPUT_JINJA),$(wildcard $(dir)/*.html.j2)) \
BABEL_TRANSLATIONS=$(APP)/translations
export BUILD_DATE := ${shell date -Iminutes} export BUILD_DATE := ${shell date -Iminutes}
VERSION := $(shell cat $(APP)/.version) VERSION := $(shell cat $(SRC)/.version)
export MAJOR := $(shell echo $(VERSION) | cut -f1 -d.) export MAJOR := $(shell echo $(VERSION) | cut -f1 -d.)
PUBLIC_URL := $(shell echo $(PUBLIC_CONTAINER_REGISTRY) | cut -f1 -d/) PUBLIC_URL := $(shell echo $(PUBLIC_CONTAINER_REGISTRY) | cut -f1 -d/)
@@ -45,17 +39,5 @@ preview rel:
export IMAGE=$(PUBLIC_CONTAINER_REGISTRY)$(IMAGE) && \ export IMAGE=$(PUBLIC_CONTAINER_REGISTRY)$(IMAGE) && \
docker buildx bake -f docker-bake.hcl $@ 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
$(BABEL_TRANSLATIONS)/%.pot : $(SRC)/.babel.cfg $(BABEL_INPUT) .PHONY: debug dev preview rc rel
@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

View File

@@ -2,4 +2,3 @@
schema==0.7.7 schema==0.7.7
aiocron==2.1 aiocron==2.1
quart==0.20 quart==0.20
quart-babel==1.0.7

View File

@@ -1,3 +0,0 @@
[python: **.py]
[jinja2: web/templates/**.html]
[jinja2: web/templates/**.html.j2]

View File

@@ -4,9 +4,7 @@ import logging.handlers
import os import os
import argparse import argparse
from asyncio import StreamReader, StreamWriter from asyncio import StreamReader, StreamWriter
from quart import Quart, Response, request from quart import Quart, Response
from quart_babel import Babel
from quart_babel.locale import get_locale
from logging import config # noqa F401 from logging import config # noqa F401
from proxy import Proxy from proxy import Proxy
from inverter_ifc import InverterIfc from inverter_ifc import InverterIfc
@@ -33,28 +31,12 @@ class ProxyState:
ProxyState._is_up = value 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__, app = Quart(__name__,
template_folder='web/templates', template_folder='web/templates',
static_folder='web/static') static_folder='web/static')
babel = Babel(app,
locale_selector=my_get_locale,
default_translation_directories='../translations')
app.register_blueprint(web_routes) app.register_blueprint(web_routes)
@app.context_processor
def utility_processor():
return dict(lang=get_locale())
@app.route('/-/ready') @app.route('/-/ready')
async def ready(): async def ready():
if ProxyState.is_up(): if ProxyState.is_up():

View File

@@ -1,5 +1,5 @@
from quart import Blueprint from quart import Blueprint
from quart import render_template, url_for from quart import render_template
from quart import send_from_directory from quart import send_from_directory
import os import os
@@ -13,44 +13,14 @@ async def get_icon(file: str, mime: str = 'image/png'):
mimetype=mime) mimetype=mime)
def get_inv_count():
return 1234
TsunCnt = 0
def get_tsun_count():
global TsunCnt
TsunCnt += 1
return TsunCnt
@web_routes.context_processor
def utility_processor():
return dict(inv_count=get_inv_count(),
tsun_count=get_tsun_count())
@web_routes.route('/') @web_routes.route('/')
async def index(): async def index():
return await render_template( return await render_template('index.html')
'index.html.j2',
fetch_url='.'+url_for('web_routes.data_fetch'))
@web_routes.route('/page') @web_routes.route('/page')
async def empty(): async def empty():
return await render_template('empty.html.j2') return await render_template('empty.html')
@web_routes.route('/data-fetch')
async def data_fetch():
global TsunCnt
TsunCnt += 1
return {
"geology-fact": f"<h3>{TsunCnt}</h3>",
}
@web_routes.route('/favicon-96x96.png') @web_routes.route('/favicon-96x96.png')

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 729 KiB

After

Width:  |  Height:  |  Size: 151 KiB

View File

@@ -1,6 +1,6 @@
{ {
"name": "TSUN-Proxy", "name": "TSUN-Proxy",
"short_name": "Proxy", "short_name": "TsunProxy",
"icons": [ "icons": [
{ {
"src": "/web-app-manifest-192x192.png", "src": "/web-app-manifest-192x192.png",

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{lang}}" > <html lang="en">
<head> <head>
<title>{% block title %}{% endblock title %}</title> <title>{% block title %}{% endblock title %}</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
@@ -106,36 +106,6 @@
mySidebar.style.display = "none"; mySidebar.style.display = "none";
overlayBg.style.display = "none"; overlayBg.style.display = "none";
} }
{% if fetch_url is defined %}
function fetch_data() {
fetch("{{fetch_url}}")
.then(response => response.json())
.then(function (data) {
Object.keys(data).forEach(key => {
//console.log(`${key}: ${data[key]}`);
try {
elm = document.getElementById(key)
elm.innerHTML = data[key]
}
catch(err) {
console.log('error: ' + err + ' (for key: ' + key + ')');
}
});
})
.catch(function (err) {
console.log('error: ' + err);
});
}
window.addEventListener('load', function () {
// Your document is loaded.
var fetchInterval = 5000; // 5 seconds.
// Invoke the request every 5 seconds.
setInterval(fetch_data, fetchInterval);
});
{% endif %}
</script> </script>
{% endblock trailer %} {% endblock trailer %}

View File

@@ -1,4 +1,4 @@
{% extends 'base.html.j2' %} {% extends 'base.html' %}
{% block title %} TSUN Proxy - View {% endblock title%} {% block title %} TSUN Proxy - View {% endblock title%}
{% block menu2_class %}w3-blue{% endblock %} {% block menu2_class %}w3-blue{% endblock %}

View File

@@ -1,8 +1,8 @@
{% extends 'base.html.j2' %} {% extends 'base.html' %}
{% block title %} TSUN Proxy - Dashboard {% endblock title%} {% block title %} TSUN Proxy - Dashboard {% endblock title%}
{% block menu1_class %}w3-blue{% endblock %} {% block menu1_class %}w3-blue{% endblock %}
{% block headline %}<i class="fa fa-dashboard"></i> {{_('My Dashboard')}}{% endblock headline %} {% block headline %}<i class="fa fa-dashboard"></i> My Dashboard{% endblock headline %}
{% block content %} {% block content %}
<div class="w3-row-padding w3-margin-bottom"> <div class="w3-row-padding w3-margin-bottom">
@@ -10,7 +10,7 @@
<div class="w3-container w3-red w3-padding-16"> <div class="w3-container w3-red w3-padding-16">
<div class="w3-left"><i class="fa fa-comment w3-xxxlarge"></i></div> <div class="w3-left"><i class="fa fa-comment w3-xxxlarge"></i></div>
<div class="w3-right"> <div class="w3-right">
<h3>{{inv_count}}</h3> <h3>52</h3>
</div> </div>
<div class="w3-clear"></div> <div class="w3-clear"></div>
<h4>Messages</h4> <h4>Messages</h4>
@@ -20,7 +20,7 @@
<div class="w3-container w3-blue w3-padding-16"> <div class="w3-container w3-blue w3-padding-16">
<div class="w3-left"><i class="fa fa-eye w3-xxxlarge"></i></div> <div class="w3-left"><i class="fa fa-eye w3-xxxlarge"></i></div>
<div class="w3-right"> <div class="w3-right">
<h3>{{tsun_count}}</h3> <h3>99</h3>
</div> </div>
<div class="w3-clear"></div> <div class="w3-clear"></div>
<h4>Views</h4> <h4>Views</h4>
@@ -29,7 +29,7 @@
<div class="w3-quarter"> <div class="w3-quarter">
<div class="w3-container w3-teal w3-padding-16"> <div class="w3-container w3-teal w3-padding-16">
<div class="w3-left"><i class="fa fa-share-alt w3-xxxlarge"></i></div> <div class="w3-left"><i class="fa fa-share-alt w3-xxxlarge"></i></div>
<div id = "geology-fact" class="w3-right"> <div class="w3-right">
<h3>23</h3> <h3>23</h3>
</div> </div>
<div class="w3-clear"></div> <div class="w3-clear"></div>
@@ -52,6 +52,7 @@
<div class="w3-row-padding" style="margin:0 -16px"> <div class="w3-row-padding" style="margin:0 -16px">
<div class="w3-third"> <div class="w3-third">
<h5>Regions</h5> <h5>Regions</h5>
<img src="/w3images/region.jpg" style="width:100%" alt="Google Regional Map">
</div> </div>
<div class="w3-twothird"> <div class="w3-twothird">
<h5>Feeds</h5> <h5>Feeds</h5>
@@ -177,3 +178,5 @@
</div> </div>
</div> </div>
{% endblock content%} {% endblock content%}

View File

@@ -61,13 +61,3 @@ async def test_manifest():
response = await client.get('/site.webmanifest') response = await client.get('/site.webmanifest')
assert response.status_code == 200 assert response.status_code == 200
assert response.mimetype == 'application/manifest+json' assert response.mimetype == 'application/manifest+json'
@pytest.mark.asyncio
async def test_data_fetch():
"""Test the healthy route."""
client = app.test_client()
response = await client.get('/data-fetch')
assert response.status_code == 200
response = await client.get('/data-fetch')
assert response.status_code == 200

View File

@@ -1,25 +0,0 @@
# 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 <EMAIL@ADDRESS>, 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-20 00:01+0200\n"
"PO-Revision-Date: 2025-04-18 16:24+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de\n"
"Language-Team: de <LL@li.org>\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.j2:5
msgid "My Dashboard"
msgstr "Mein Dashboard"

View File

@@ -12,14 +12,11 @@ IMAGE = tsun-gen3-addon
SRC=../app SRC=../app
SRC_PROXY=$(SRC)/src SRC_PROXY=$(SRC)/src
CNF_PROXY=$(SRC)/config CNF_PROXY=$(SRC)/config
TRANSLATION_PROXY=$(SRC)/translations
# Target folders for building the local add-on and the docker container # Target folders for building the local add-on and the docker container
ADDON_PATH = ha_addon ADDON_PATH = ha_addon
DST=$(ADDON_PATH)/rootfs DST=$(ADDON_PATH)/rootfs
DST_PROXY=$(DST)/home/proxy DST_PROXY=$(DST)/home/proxy
DST_TRANSLATION=$(DST)/home/translations
# base director of the add-on repro for installing the add-on git repros # base director of the add-on repro for installing the add-on git repros
INST_BASE=../../ha-addons INST_BASE=../../ha-addons
@@ -88,21 +85,19 @@ SRC_FILES := $(wildcard $(SRC_PROXY)/*.py)\
$(wildcard $(SRC_PROXY)/gen3/*.py)\ $(wildcard $(SRC_PROXY)/gen3/*.py)\
$(wildcard $(SRC_PROXY)/gen3plus/*.py)\ $(wildcard $(SRC_PROXY)/gen3plus/*.py)\
$(wildcard $(SRC_PROXY)/web/*.py)\ $(wildcard $(SRC_PROXY)/web/*.py)\
$(wildcard $(SRC_PROXY)/web/templates/*.html.j2)\ $(wildcard $(SRC_PROXY)/web/templates/*.html)\
$(wildcard $(SRC_PROXY)/web/static/css/*.css)\ $(wildcard $(SRC_PROXY)/web/static/css/*.css)\
$(wildcard $(SRC_PROXY)/web/static/font/*)\ $(wildcard $(SRC_PROXY)/web/static/font/*)\
$(wildcard $(SRC_PROXY)/web/static/font-awesome/*/*)\ $(wildcard $(SRC_PROXY)/web/static/font-awesome/*/*)\
$(wildcard $(SRC_PROXY)/web/static/images/*) $(wildcard $(SRC_PROXY)/web/static/images/*)
CNF_FILES := $(wildcard $(CNF_PROXY)/*.toml) CNF_FILES := $(wildcard $(CNF_PROXY)/*.toml)
MO_FILES := $(wildcard $(TRANSLATION_PROXY)/de/LC_MESSAGES/*.mo)
# determine destination files # determine destination files
TARGET_FILES = $(SRC_FILES:$(SRC_PROXY)/%=$(DST_PROXY)/%) TARGET_FILES = $(SRC_FILES:$(SRC_PROXY)/%=$(DST_PROXY)/%)
CONFIG_FILES = $(CNF_FILES:$(CNF_PROXY)/%=$(DST_PROXY)/%) CONFIG_FILES = $(CNF_FILES:$(CNF_PROXY)/%=$(DST_PROXY)/%)
TRANSLATION_FILES = $(MO_FILES:$(TRANSLATION_PROXY)/%=$(DST_TRANSLATION)/%)
rootfs: $(TARGET_FILES) $(CONFIG_FILES) $(TRANSLATION_FILES) $(DST)/requirements.txt rootfs: $(TARGET_FILES) $(CONFIG_FILES) $(DST)/requirements.txt
$(CONFIG_FILES): $(DST_PROXY)/% : $(CNF_PROXY)/% $(CONFIG_FILES): $(DST_PROXY)/% : $(CNF_PROXY)/%
@echo Copy $< to $@ @echo Copy $< to $@
@@ -114,11 +109,6 @@ $(TARGET_FILES): $(DST_PROXY)/% : $(SRC_PROXY)/%
@mkdir -p $(@D) @mkdir -p $(@D)
@cp $< $@ @cp $< $@
$(TRANSLATION_FILES): $(DST_TRANSLATION)/% : $(TRANSLATION_PROXY)/%
@echo Copy $< to $@
@mkdir -p $(@D)
@cp $< $@
$(DST)/requirements.txt : $(SRC)/requirements.txt $(DST)/requirements.txt : $(SRC)/requirements.txt
@echo Copy $< to $@ @echo Copy $< to $@
@cp $< $@ @cp $< $@

View File

@@ -23,11 +23,11 @@ services:
ports: ports:
5005/tcp: 5005 5005/tcp: 5005
10000/tcp: 10000 10000/tcp: 10000
8127/tcp: 8127
webui: "http://[HOST]:[PORT:8127]/" webui: "http://[HOST]:[PORT:8127]/"
watchdog: "http://[HOST]:[PORT:8127]/-/healthy" watchdog: "http://[HOST]:[PORT:8127]/-/healthy"
ingress: true ingress: true
ingress_port: 8127 ingress_port: 8127
panel_icon: "mdi:application-cog-outline"
# Definition of parameters in the configuration tab of the addon # Definition of parameters in the configuration tab of the addon
# parameters are available within the container as /data/options.json # parameters are available within the container as /data/options.json