From 9351b9f53ac18db8c9886e76ff467f7059a0ca4d Mon Sep 17 00:00:00 2001 From: shmyga Date: Thu, 23 Apr 2026 15:47:16 +0300 Subject: [PATCH] feat(easel): add localization --- .gitignore | 1 + Dockerfile | 3 +- gallery/easel/__init__.py | 8 +- gallery/easel/route/view/__init__.py | 16 ++- gallery/easel/route/view/common/__init__.py | 43 +++--- .../route/view/common/static/favicon.ico | Bin 15406 -> 0 bytes .../route/view/common/static/gallery.png | Bin 22215 -> 0 bytes .../route/view/common/templates/base.html | 59 +++++--- .../view/common/templates/root_index.html | 14 +- .../view/locales/ru/LC_MESSAGES/messages.po | 15 ++ gallery/easel/route/view/schedule/__init__.py | 129 +++++++++--------- .../route/view/schedule/static/favicon.ico | Bin 15406 -> 0 bytes .../route/view/schedule/static/schedule.png | Bin 13377 -> 0 bytes .../route/view/schedule/static/style.css | 0 .../view/schedule/templates/channel.html | 12 +- .../route/view/schedule/templates/index.html | 12 +- .../view/schedule/templates/schedule.html | 14 +- gallery/easel/route/view/translation.py | 34 +++++ gallery/easel/route/view/weather/__init__.py | 123 +++++++++-------- .../route/view/weather/static/favicon.ico | Bin 15406 -> 0 bytes .../easel/route/view/weather/static/style.css | 71 ---------- .../route/view/weather/static/weather.png | Bin 9757 -> 0 bytes .../route/view/weather/templates/index.html | 8 -- .../route/view/weather/templates/weather.html | 16 +-- scripts/locales | 6 + static/package.json | 2 +- static/src/components.ts | 17 +++ static/src/index.ts | 2 + static/src/language.ts | 62 +++++++++ static/src/main.scss | 10 ++ static/src/{theme.js => theme.ts} | 16 +-- static/src/weather.scss | 73 ++++++++++ .../style.css => static/src/widget.scss | 7 - static/vite.config.ts | 2 +- 34 files changed, 464 insertions(+), 311 deletions(-) delete mode 100644 gallery/easel/route/view/common/static/favicon.ico delete mode 100644 gallery/easel/route/view/common/static/gallery.png create mode 100644 gallery/easel/route/view/locales/ru/LC_MESSAGES/messages.po delete mode 100644 gallery/easel/route/view/schedule/static/favicon.ico delete mode 100644 gallery/easel/route/view/schedule/static/schedule.png delete mode 100644 gallery/easel/route/view/schedule/static/style.css create mode 100644 gallery/easel/route/view/translation.py delete mode 100644 gallery/easel/route/view/weather/static/favicon.ico delete mode 100644 gallery/easel/route/view/weather/static/style.css delete mode 100644 gallery/easel/route/view/weather/static/weather.png create mode 100755 scripts/locales create mode 100644 static/src/components.ts create mode 100644 static/src/language.ts rename static/src/{theme.js => theme.ts} (86%) create mode 100644 static/src/weather.scss rename gallery/easel/route/view/common/static/style.css => static/src/widget.scss (70%) diff --git a/.gitignore b/.gitignore index 8f9a392..e2a0b63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.pyc +*.mo .pytest_cache .venv #.vscode diff --git a/Dockerfile b/Dockerfile index 5049f85..fe60189 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,7 @@ FROM python:3.12-slim ENV PATH="/app/.venv/bin:$PATH" WORKDIR /app RUN apt update && \ - apt install -y locales && \ + apt install -y locales gettext && \ sed -i -e 's/# ru_RU.UTF-8 UTF-8/ru_RU.UTF-8 UTF-8/' /etc/locale.gen && \ dpkg-reconfigure --frontend=noninteractive locales ENV LANG=ru_RU.UTF-8 @@ -28,5 +28,6 @@ ENV TZ="Europe/Moscow" COPY --from=builder /app ./ COPY --from=node-builder /app/dist ./static/dist COPY gallery gallery/ +RUN cd gallery/easel/route/view/locales/ru/LC_MESSAGES && msgfmt messages.po CMD ["uvicorn", "gallery.main:app", "--host", "0.0.0.0", "--port", "80", "--log-config", "gallery/logging.yaml"] diff --git a/gallery/easel/__init__.py b/gallery/easel/__init__.py index f6ab94d..ea1ec59 100644 --- a/gallery/easel/__init__.py +++ b/gallery/easel/__init__.py @@ -1,10 +1,13 @@ import locale as _locale from fastapi import FastAPI +from fastapi.staticfiles import StaticFiles from gallery.sketch.bundle import ApiBundle +from gallery.util import root_path -from .route import api, doc, view +from .route import api, doc +from .route.view import router as view_router DEFAULT_LOCALE = "ru_RU.UTF-8" @@ -17,7 +20,8 @@ def build_app(api_bundle: ApiBundle, *, locale: str = DEFAULT_LOCALE) -> FastAPI redoc_url=None, ) app.state.api = api_bundle + app.mount("/static", StaticFiles(directory=root_path / "static/dist")) doc.mount(app) api.mount(app) - view.mount(app) + app.include_router(view_router) return app diff --git a/gallery/easel/route/view/__init__.py b/gallery/easel/route/view/__init__.py index b99b8d6..303a42d 100644 --- a/gallery/easel/route/view/__init__.py +++ b/gallery/easel/route/view/__init__.py @@ -1,9 +1,11 @@ -from fastapi import FastAPI +from fastapi import APIRouter, Depends -from . import common, schedule, weather +from .common import router as common_router +from .schedule import router as schedule_router +from .translation import set_language +from .weather import router as weather_router - -def mount(app: FastAPI): - common.mount(app) - weather.mount(app) - schedule.mount(app) +router = APIRouter(dependencies=[Depends(set_language)]) +router.include_router(common_router) +router.include_router(weather_router) +router.include_router(schedule_router) diff --git a/gallery/easel/route/view/common/__init__.py b/gallery/easel/route/view/common/__init__.py index 22aca52..a112193 100644 --- a/gallery/easel/route/view/common/__init__.py +++ b/gallery/easel/route/view/common/__init__.py @@ -1,40 +1,41 @@ from pathlib import Path from typing import NamedTuple -from fastapi import FastAPI, Request +from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse -from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates -from gallery.util import root_path from gallery.version import __version__ +from ..translation import _ + class Section(NamedTuple): link: str title: str + icon: str SECTIONS = [ - Section("weather", "Weather"), - Section("schedule", "TV program"), + Section("weather", "Weather", "brightness-high"), + Section("schedule", "TV program", "tv"), ] +base_dir = Path(__file__).parent -def mount(app: FastAPI): - base_dir = Path(__file__).parent - print("!", root_path / "static/dist") - app.mount("/static/main", StaticFiles(directory=root_path / "static/dist")) - app.mount("/static/common", StaticFiles(directory=base_dir / "static")) - templates = Jinja2Templates(directory=base_dir / "templates") +router = APIRouter() - @app.get("/", response_class=HTMLResponse) - async def get_section_list(request: Request): - return templates.TemplateResponse( - request=request, - name="root_index.html", - context={ - "version": __version__, - "sections": SECTIONS, - }, - ) +templates = Jinja2Templates(directory=base_dir / "templates") +templates.env.globals.update({"_": _}) + + +@router.get("/", response_class=HTMLResponse) +async def get_section_list(request: Request): + return templates.TemplateResponse( + request=request, + name="root_index.html", + context={ + "version": __version__, + "sections": SECTIONS, + }, + ) diff --git a/gallery/easel/route/view/common/static/favicon.ico b/gallery/easel/route/view/common/static/favicon.ico deleted file mode 100644 index 99e44cdd3f88c8df86a345bd40f0815a6bbb3795..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15406 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 Ksx(lM8u&khI|x1i diff --git a/gallery/easel/route/view/common/static/gallery.png b/gallery/easel/route/view/common/static/gallery.png deleted file mode 100644 index 93b0ee06121570fe7e355bd4d262560580f55387..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22215 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 diff --git a/gallery/easel/route/view/common/templates/base.html b/gallery/easel/route/view/common/templates/base.html index f334ed7..7879fcc 100644 --- a/gallery/easel/route/view/common/templates/base.html +++ b/gallery/easel/route/view/common/templates/base.html @@ -1,5 +1,5 @@ - + {% block head %} @@ -10,13 +10,11 @@ content="ie=edge"> {% block title %}{% endblock %} + href="/static/gallery.css?v={{version}}"> - + src="/static/gallery.es.js?v={{version}}"> {% endblock %} @@ -24,13 +22,43 @@
- -
- API Gallery -
+ API Gallery + {% block header %}{% endblock %}