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 99e44cd..0000000 Binary files a/gallery/easel/route/view/common/static/favicon.ico and /dev/null differ 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 93b0ee0..0000000 Binary files a/gallery/easel/route/view/common/static/gallery.png and /dev/null differ 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 %}