From 4cfe973823cf4bf2175b56f0cfedca9dd2e60f60 Mon Sep 17 00:00:00 2001 From: "hikari.ftg" Date: Mon, 21 Mar 2022 13:03:13 +0000 Subject: [PATCH] Return accidentaly ignored translations --- .gitignore | 1 - hikka/translations/core.py | 125 ++++++++++++++++++++++++++++++++++ hikka/translations/dynamic.py | 43 ++++++++++++ 3 files changed, 168 insertions(+), 1 deletion(-) create mode 100755 hikka/translations/core.py create mode 100755 hikka/translations/dynamic.py diff --git a/.gitignore b/.gitignore index fbc4a83..bb9f17b 100755 --- a/.gitignore +++ b/.gitignore @@ -141,7 +141,6 @@ database-*.json .idea/ venv/ data/ -translations/ api_token.txt .coverage .vscode/ diff --git a/hikka/translations/core.py b/hikka/translations/core.py new file mode 100755 index 0000000..3e3237c --- /dev/null +++ b/hikka/translations/core.py @@ -0,0 +1,125 @@ +# Friendly Telegram (telegram userbot) +# Copyright (C) 2018-2021 The Authors + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +# Friendly Telegram Userbot +# by GeekTG Team + +import json +import logging +import os + +import telethon +from babel import negotiate_locale +from telethon.tl.types import MessageEntityHashtag + +from .. import utils + +logger = logging.getLogger(__name__) + +MAGIC = "#ftgtrnsl1" + + +class Translator: + def __init__(self, packs, languages, data_root): + self._packs = packs + self._languages = languages + self._data_root = data_root + + async def init(self, client): + self._data = {} + if await client.is_bot(): + for pack in self._packs: + if not pack.isalnum(): + logger.warning("Pack path invalid") + continue + try: + file = open( + os.path.join( + self._data_root or os.path.dirname(utils.get_base_dir()), + "translations", + pack + ".json", + ), + "r", + ) + except FileNotFoundError: + logger.exception("Pack not found") + continue + with file: + try: + data = json.load(file) + except json.decoder.JSONDecodeError: + logger.exception("Unable to decode %s", pack) + continue + try: + self._data.setdefault(data["language"], {}).update(data["data"]) + except KeyError: + logger.exception("Translation pack follows wrong format") + else: + for pack in self._packs: + try: + [message] = await client.get_messages(pack, 1) + except (ValueError, telethon.errors.rpcerrorlist.ChannelPrivateError): + # We can't access the channel + logger.warning( + "No translation pack found for %r", pack, exc_info=True + ) + continue + if not message.document or not message.entities: + logger.info( + "Last message in translation pack %r has no document/entities", + pack, + ) + continue + found = False + for ent in filter( + lambda x: isinstance(x, MessageEntityHashtag), message.entities + ): + if ( + message.message[ent.offset : ent.offset + ent.length] == MAGIC + and message.file + ): + logger.debug("Got translation message") + found = True + break + if not found: + logger.info("Didn't find translation hashtags") + continue + try: + ndata = json.loads( + (await message.download_media(bytes)).decode("utf-8") + ) + except (json.decoder.JSONDecodeError, UnicodeDecodeError): + logger.exception("Unable to decode %s", pack) + continue + try: + self._data.setdefault(ndata["language"], {}).update(ndata["data"]) + except KeyError: + logger.exception("Translation pack follows wrong format") + + def set_preferred_languages(self, languages): + self._languages = languages + + def getkey(self, key, lang_code=None): + locales = [] + for locale, strings in self._data.items(): + if key in strings: + locales += [locale] + target_locales = [lang_code] if lang_code else self._languages + locale = negotiate_locale(target_locales, locales) + return self._data.get(locale, {}).get(key, False) + + def gettext(self, english_text): + return self.getkey(english_text) or english_text diff --git a/hikka/translations/dynamic.py b/hikka/translations/dynamic.py new file mode 100755 index 0000000..9f734bd --- /dev/null +++ b/hikka/translations/dynamic.py @@ -0,0 +1,43 @@ +# Friendly Telegram (telegram userbot) +# Copyright (C) 2018-2021 The Authors + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +# Friendly Telegram Userbot +# by GeekTG Team + + +class Strings: + def __init__(self, prefix, strings, babel): + self._prefix = prefix + self._strings = strings + self._babel = babel + + def __getitem__(self, key): + return self._babel.getkey(self._prefix + key) or self._strings[key] + + def __call__(self, key, message=None): + if isinstance(message, str): + lang_code = message + elif message is None: + lang_code = None + else: + lang_code = getattr(getattr(message, "sender", None), "lang_code", None) + return ( + self._babel.getkey(f'{self._prefix}.{key}', lang_code) + or self._strings[key] + ) + + def __iter__(self): + return self._strings.__iter__()