Heroku/hikka/translations.py

122 lines
3.6 KiB
Python
Executable File

# █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
# █▀█ █ █ █ █▀█ █▀▄ █
# © Copyright 2022
# https://t.me/hikariatama
#
# 🔒 Licensed under the GNU AGPLv3
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
import json
import logging
import os
import typing
import requests
from . import utils
from .types import Module
from .tl_cache import CustomTelegramClient
from .database import Database
logger = logging.getLogger(__name__)
class Translator:
def __init__(self, client: CustomTelegramClient, db: Database):
self._client = client
self.db = db
async def init(self) -> bool:
self._data = {}
if not (lang := self.db.get(__name__, "lang", False)):
return False
for language in lang.split(" "):
if utils.check_url(language):
try:
ndata = (await utils.run_sync(requests.get, lang)).json()
except Exception:
logger.exception("Unable to decode %s", lang)
continue
data = ndata.get("data", ndata)
if any(not isinstance(i, str) for i in data.values()):
logger.exception(
"Translation pack format is not valid (typecheck failed)"
)
continue
self._data.update(data)
continue
possible_pack_path = os.path.join(
utils.get_base_dir(),
f"langpacks/{language}.json",
)
if os.path.isfile(possible_pack_path):
with open(possible_pack_path, "r") as f:
self._data.update(json.load(f))
return True
return True
def getkey(self, key: str) -> typing.Any:
return self._data.get(key, False)
def gettext(self, text: str) -> typing.Any:
return self.getkey(text) or text
class Strings:
def __init__(self, mod: Module, translator: Translator):
self._mod = mod
self._translator = translator
if not translator:
logger.debug("Module %s got empty translator %s", mod, translator)
self._base_strings = mod.strings # Back 'em up, bc they will get replaced
def __getitem__(self, key: str) -> str:
return (
self._translator.getkey(f"{self._mod.__module__}.{key}")
if self._translator is not None
else False
) or (
getattr(
self._mod,
next(
(
f"strings_{lang}"
for lang in self._translator.db.get(
__name__,
"lang",
"en",
).split(" ")
if hasattr(self._mod, f"strings_{lang}")
and isinstance(getattr(self._mod, f"strings_{lang}"), dict)
and key in getattr(self._mod, f"strings_{lang}")
),
utils.rand(32),
),
self._base_strings,
)
if self._translator is not None
else self._base_strings
).get(
key,
self._base_strings.get(key, "Unknown strings"),
)
def __call__(
self,
key: str,
_: typing.Optional[typing.Any] = None, # Compatibility tweak for FTG\GeekTG
) -> str:
return self.__getitem__(key)
def __iter__(self):
return self._base_strings.__iter__()