From 17b0498034e1d1e1d50af9c14df176db49aefbb4 Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 28 Nov 2024 18:12:09 -0500 Subject: [PATCH] Set up GHUtilsTranslator using Fluent --- bot/pyproject.toml | 1 + bot/src/ghutils/app.py | 1 + bot/src/ghutils/core/bot.py | 5 +++ bot/src/ghutils/core/translator.py | 36 +++++++++++++++++++ bot/src/ghutils/resources/__init__.py | 8 +++++ bot/src/ghutils/resources/l10n/en-US/main.ftl | 0 requirements-dev.lock | 11 ++++++ requirements.lock | 11 ++++++ 8 files changed, 73 insertions(+) create mode 100644 bot/src/ghutils/core/translator.py create mode 100644 bot/src/ghutils/resources/l10n/en-US/main.ftl diff --git a/bot/pyproject.toml b/bot/pyproject.toml index 2fec9cf..5a43883 100644 --- a/bot/pyproject.toml +++ b/bot/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "githubkit[auth-app]>=0.11.8", "pfzy>=0.3.4", "more-itertools>=10.5.0", + "fluent-runtime>=0.4.0", ] [tool.rye] diff --git a/bot/src/ghutils/app.py b/bot/src/ghutils/app.py index 95694d8..1f2705a 100644 --- a/bot/src/ghutils/app.py +++ b/bot/src/ghutils/app.py @@ -11,6 +11,7 @@ async def main(): env = GHUtilsEnv.get() async with GHUtilsBot(env) as bot: create_db_and_tables(bot.engine) + await bot.load_translator() await bot.load_cogs() await bot.start(env.token.get_secret_value()) diff --git a/bot/src/ghutils/core/bot.py b/bot/src/ghutils/core/bot.py index 02c393c..37322ee 100644 --- a/bot/src/ghutils/core/bot.py +++ b/bot/src/ghutils/core/bot.py @@ -16,6 +16,7 @@ from ghutils.utils.imports import iter_modules from .env import GHUtilsEnv +from .translator import GHUtilsTranslator from .tree import GHUtilsCommandTree from .types import LoginState @@ -60,6 +61,10 @@ def db_session_of(cls, interaction: Interaction): def github_app_of(cls, interaction: Interaction): return cls.of(interaction).github_app(interaction) + async def load_translator(self): + logger.info("Loading translator") + await self.tree.set_translator(GHUtilsTranslator()) + async def load_cogs(self): for cog in iter_modules(cogs, skip_internal=True): try: diff --git a/bot/src/ghutils/core/translator.py b/bot/src/ghutils/core/translator.py new file mode 100644 index 0000000..03e6c9d --- /dev/null +++ b/bot/src/ghutils/core/translator.py @@ -0,0 +1,36 @@ +from contextlib import ExitStack + +from discord import Locale +from discord.app_commands import TranslationContextTypes, Translator, locale_str +from fluent.runtime import FluentLocalization, FluentResourceLoader + +from ghutils.resources import load_resource_dir + + +class GHUtilsTranslator(Translator): + async def load(self) -> None: + self.exit_stack = ExitStack() + + path = self.exit_stack.enter_context(load_resource_dir("l10n")) + loader = FluentResourceLoader(path.as_posix() + "/{locale}") + + self.l10n = { + locale: FluentLocalization( + locales=[locale.value, "en-US"], + resource_ids=["main.ftl"], + resource_loader=loader, + ) + for locale in Locale + } + + async def unload(self) -> None: + self.exit_stack.close() + + async def translate( + self, + string: locale_str, + locale: Locale, + context: TranslationContextTypes, + ) -> str | None: + l10n = self.l10n[locale] + return l10n.format_value(string.extras["id"]) diff --git a/bot/src/ghutils/resources/__init__.py b/bot/src/ghutils/resources/__init__.py index 2c5515e..66f9c5d 100644 --- a/bot/src/ghutils/resources/__init__.py +++ b/bot/src/ghutils/resources/__init__.py @@ -1,3 +1,4 @@ +from contextlib import contextmanager from importlib import resources @@ -8,3 +9,10 @@ def get_resource(name: str): def load_resource(name: str, encoding: str = "utf-8"): return get_resource(name).read_text(encoding) + + +@contextmanager +def load_resource_dir(name: str): + resource = get_resource(name) + with resources.as_file(resource) as path: + yield path diff --git a/bot/src/ghutils/resources/l10n/en-US/main.ftl b/bot/src/ghutils/resources/l10n/en-US/main.ftl new file mode 100644 index 0000000..e69de29 diff --git a/requirements-dev.lock b/requirements-dev.lock index d0355a0..59c5fed 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -27,6 +27,7 @@ anyio==4.4.0 attrs==23.2.0 # via aiohttp # via cattrs + # via fluent-runtime # via jsii aws-cdk-asset-awscli-v1==2.2.202 # via aws-cdk-lib @@ -43,6 +44,8 @@ aws-cdk-lib==2.158.0 # via aws-cdk-github-oidc # via ghutils-infrastructure # via object-ci +babel==2.16.0 + # via fluent-runtime cattrs==23.2.3 # via jsii certifi==2024.6.2 @@ -77,6 +80,10 @@ fastapi-cli==0.0.4 # via fastapi filelock==3.15.4 # via virtualenv +fluent-runtime==0.4.0 + # via ghutils-bot +fluent-syntax==0.19.0 + # via fluent-runtime frozenlist==1.4.1 # via aiohttp # via aiosignal @@ -172,6 +179,8 @@ python-dotenv==1.0.1 # via uvicorn python-multipart==0.0.9 # via fastapi +pytz==2024.2 + # via fluent-runtime pyyaml==6.0.1 # via pre-commit # via uvicorn @@ -204,6 +213,8 @@ typer==0.12.3 # via fastapi-cli typing-extensions==4.12.2 # via fastapi + # via fluent-runtime + # via fluent-syntax # via githubkit # via hishel # via jsii diff --git a/requirements.lock b/requirements.lock index cd8b068..dd54dd9 100644 --- a/requirements.lock +++ b/requirements.lock @@ -27,6 +27,7 @@ anyio==4.4.0 attrs==23.2.0 # via aiohttp # via cattrs + # via fluent-runtime # via jsii aws-cdk-asset-awscli-v1==2.2.202 # via aws-cdk-lib @@ -43,6 +44,8 @@ aws-cdk-lib==2.158.0 # via aws-cdk-github-oidc # via ghutils-infrastructure # via object-ci +babel==2.16.0 + # via fluent-runtime cattrs==23.2.3 # via jsii certifi==2024.6.2 @@ -71,6 +74,10 @@ fastapi==0.111.0 # via ghutils-bot fastapi-cli==0.0.4 # via fastapi +fluent-runtime==0.4.0 + # via ghutils-bot +fluent-syntax==0.19.0 + # via fluent-runtime frozenlist==1.4.1 # via aiohttp # via aiosignal @@ -159,6 +166,8 @@ python-dotenv==1.0.1 # via uvicorn python-multipart==0.0.9 # via fastapi +pytz==2024.2 + # via fluent-runtime pyyaml==6.0.1 # via uvicorn rich==13.7.1 @@ -189,6 +198,8 @@ typer==0.12.3 # via fastapi-cli typing-extensions==4.12.2 # via fastapi + # via fluent-runtime + # via fluent-syntax # via githubkit # via hishel # via jsii