feat: jinja template for cards
Python Lint CI / ruff (push) Successful in 1m13s
Python Lint CI / ty (push) Successful in 1m23s
Python Lint CI / ruff-format-check (push) Successful in 1m23s
TS Lint / Oxlint (push) Failing after 2m17s
TS Lint / ESLint (push) Successful in 3m0s
TS Lint / TypeScript (push) Successful in 2m47s
Docker Build / build (push) Successful in 6m4s
Python Lint CI / ruff (push) Successful in 1m13s
Python Lint CI / ty (push) Successful in 1m23s
Python Lint CI / ruff-format-check (push) Successful in 1m23s
TS Lint / Oxlint (push) Failing after 2m17s
TS Lint / ESLint (push) Successful in 3m0s
TS Lint / TypeScript (push) Successful in 2m47s
Docker Build / build (push) Successful in 6m4s
This commit is contained in:
+35
@@ -0,0 +1,35 @@
|
||||
from collections.abc import MutableMapping
|
||||
from json import load
|
||||
from pathlib import Path
|
||||
|
||||
LANG_DIR = Path(__file__).parent / "lang"
|
||||
FALLBACK_LANG = "en"
|
||||
LANG_CACHE: dict[str, dict[str, str]] = {}
|
||||
|
||||
|
||||
# https://stackoverflow.com/questions/6027558/flatten-nested-dictionaries-compressing-keys
|
||||
def __flatten(dictionary: dict, parent_key: str = "") -> dict[str, str]:
|
||||
items = []
|
||||
for key, value in dictionary.items():
|
||||
new_key = parent_key + "." + key if parent_key else key
|
||||
if isinstance(value, MutableMapping):
|
||||
items.extend(__flatten(value, new_key).items())
|
||||
else:
|
||||
items.append((new_key, value))
|
||||
return dict(items)
|
||||
|
||||
|
||||
def __get_lang_data(lang: str) -> dict[str, str]:
|
||||
if lang not in LANG_CACHE:
|
||||
file = LANG_DIR / f"{lang}.json"
|
||||
if not file.exists():
|
||||
return __get_lang_data(FALLBACK_LANG)
|
||||
with file.open() as f:
|
||||
raw_data: dict = load(f)
|
||||
LANG_CACHE[lang] = __flatten(raw_data)
|
||||
return LANG_CACHE[lang]
|
||||
|
||||
|
||||
def get_lang(lang: str, key: str) -> str:
|
||||
data = __get_lang_data(lang)
|
||||
return data.get(key, key)
|
||||
+10
-4
@@ -8,6 +8,7 @@ import gunicorn.app.base
|
||||
import tortoise
|
||||
|
||||
from app import PKG_NAME
|
||||
from app.lang import get_lang
|
||||
from app.models import Task
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
@@ -36,11 +37,16 @@ class Server(gunicorn.app.base.BaseApplication):
|
||||
super().__init__()
|
||||
|
||||
def register_routes(self) -> typing.Self:
|
||||
@self.app.route("/", defaults={"_": ""})
|
||||
@self.app.route("/<_>")
|
||||
@self.app.route("/", defaults={"path": ""})
|
||||
@self.app.route("/<path>")
|
||||
@self.limiter.exempt
|
||||
def index(_: str) -> str:
|
||||
return flask.render_template("index.html")
|
||||
def index(path: str) -> str:
|
||||
lang = flask.request.args.get("lang", "en")
|
||||
return flask.render_template(
|
||||
"index.html",
|
||||
title=("Tout Doux" if not len(path) else f"Tout Doux - {path}"),
|
||||
lang=lambda key: get_lang(lang, key),
|
||||
)
|
||||
|
||||
@self.app.route("/api/lists/<list_name>/tasks", methods=["GET"])
|
||||
async def get_tasks(list_name: str) -> list:
|
||||
|
||||
Reference in New Issue
Block a user