summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rw-r--r--bin/web_kbn.py57
1 files changed, 41 insertions, 16 deletions
diff --git a/bin/web_kbn.py b/bin/web_kbn.py
index 18b50ad..21ae2ef 100644
--- a/bin/web_kbn.py
+++ b/bin/web_kbn.py
@@ -14,7 +14,8 @@ from io import StringIO
from aiohttp import web
from typing import Optional, Union
from urllib.parse import quote_plus
-from homekit.config import config, AppConfigUnit, is_development_mode, Translation
+from contextvars import ContextVar
+from homekit.config import config, AppConfigUnit, is_development_mode, Translation, Language
from homekit.camera import IpcamConfig
from homekit.util import homekit_path, filesize_fmt, seconds_to_human_readable_string, json_serial, validate_ipv4
from homekit.modem import E3372, ModemsConfig, MacroNetWorkType
@@ -45,10 +46,10 @@ common_static_files = [
'app.js',
'app.css'
]
-static_version = 3
+static_version = 4
routes = web.RouteTableDef()
-webkbn_strings = Translation('web_kbn')
logger = logging.getLogger(__name__)
+lang_context_var = ContextVar('lang', default=Translation.DEFAULT_LANGUAGE)
def get_js_link(file, version=static_version) -> str:
@@ -201,8 +202,29 @@ def get_current_upstream() -> str:
return upstream
-def lang(key: str):
- return webkbn_strings.get()[key]
+def get_preferred_lang(req: web.Request) -> Language:
+ lang_cookie = req.cookies.get('lang', None)
+ if lang_cookie is None:
+ return Translation.DEFAULT_LANGUAGE
+ try:
+ return Language(lang_cookie)
+ except ValueError:
+ logger.debug(f"unsupported lang_cookie value: {lang_cookie}")
+ return Translation.DEFAULT_LANGUAGE
+
+
+@web.middleware
+async def language_middleware(request, handler):
+ lang_context_var.set(get_preferred_lang(request))
+ return await handler(request)
+
+
+def lang(key, unit='web_kbn'):
+ strings = Translation(unit)
+ if isinstance(key, str) and '.' in key:
+ return strings.get(lang_context_var.get()).get(key)
+ else:
+ return strings.get(lang_context_var.get())[key]
async def render(req: web.Request,
@@ -214,7 +236,8 @@ async def render(req: web.Request,
context = {}
context = {
**context,
- 'head_static': get_head_static(assets)
+ 'head_static': get_head_static(assets),
+ 'user_lang': lang_context_var.get().value
}
if title is not None:
context['title'] = title
@@ -231,6 +254,8 @@ async def index(req: web.Request):
cc = IpcamConfig()
ctx['camzones'] = cc['zones'].keys()
ctx['allcams'] = cc.get_all_cam_names()
+ ctx['lang_enum'] = Language
+ ctx['lang_selected'] = lang_context_var.get()
return await render(req, 'index',
title=lang('sitename'),
@@ -240,7 +265,7 @@ async def index(req: web.Request):
@routes.get('/modems.cgi')
async def modems(req: web.Request):
return await render(req, 'modems',
- title='Состояние модемов',
+ title=lang('modem_statuses'),
context=dict(modems=ModemsConfig()))
@@ -280,9 +305,9 @@ async def modems_verbose(req: web.Request):
['Dialup connection', dialup_conn]
]
- modem_name = ModemsConfig().getfullname(modem)
+ modem_name = Translation('modems').get(lang_context_var.get())[modem]['full']
return await render(req, 'modem_verbose',
- title=f'Подробная информация о модеме "{modem_name}"',
+ title=lang('modem_verbose_info_about_modem') % (modem_name,),
context=dict(data=data, modem_name=modem_name))
@@ -296,7 +321,7 @@ async def sms(req: web.Request):
cl = get_modem_client(ModemsConfig()[modem])
messages = cl.sms_list(1, 20, is_outbox)
return await render(req, 'sms',
- title=f"SMS-сообщения ({'исходящие' if is_outbox else 'входящие'}, {modem})",
+ title=lang('sms_page_title') % (lang('sms_outbox') if is_outbox else lang('sms_inbox'), modem),
context=dict(
modems=ModemsConfig(),
selected_modem=modem,
@@ -512,6 +537,7 @@ async def routing_dhcp(req: web.Request):
def init_web_app(app: web.Application):
+ app.middlewares.append(language_middleware)
aiohttp_jinja2.setup(
app,
loader=jinja2.FileSystemLoader(homekit_path('web', 'kbn_templates')),
@@ -519,12 +545,11 @@ def init_web_app(app: web.Application):
)
env = aiohttp_jinja2.get_env(app)
- def filter_lang(key, unit='web_kbn'):
- strings = Translation(unit)
- if isinstance(key, str) and '.' in key:
- return strings.get().get(key)
- else:
- return strings.get()[key]
+ # @pass_context is used only to prevent jinja2 from caching the result of lang filter results of constant values.
+ # as of now i don't know a better way of doing it
+ @jinja2.pass_context
+ def filter_lang(ctx, key, unit='web_kbn'):
+ return lang(key, unit)
env.filters['tojson'] = lambda obj: json.dumps(obj, separators=(',', ':'), default=json_serial)
env.filters['lang'] = filter_lang