telegrinder 0.3.0.post2__py3-none-any.whl → 0.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of telegrinder might be problematic. Click here for more details.
- telegrinder/__init__.py +144 -144
- telegrinder/api/__init__.py +8 -8
- telegrinder/api/api.py +93 -93
- telegrinder/api/error.py +16 -16
- telegrinder/api/response.py +20 -20
- telegrinder/api/token.py +36 -36
- telegrinder/bot/__init__.py +66 -66
- telegrinder/bot/bot.py +76 -76
- telegrinder/bot/cute_types/__init__.py +11 -11
- telegrinder/bot/cute_types/base.py +258 -234
- telegrinder/bot/cute_types/callback_query.py +382 -382
- telegrinder/bot/cute_types/chat_join_request.py +61 -61
- telegrinder/bot/cute_types/chat_member_updated.py +160 -160
- telegrinder/bot/cute_types/inline_query.py +53 -53
- telegrinder/bot/cute_types/message.py +2631 -2631
- telegrinder/bot/cute_types/update.py +75 -75
- telegrinder/bot/cute_types/utils.py +92 -92
- telegrinder/bot/dispatch/__init__.py +55 -55
- telegrinder/bot/dispatch/abc.py +77 -77
- telegrinder/bot/dispatch/context.py +92 -92
- telegrinder/bot/dispatch/dispatch.py +202 -201
- telegrinder/bot/dispatch/handler/__init__.py +13 -13
- telegrinder/bot/dispatch/handler/abc.py +24 -24
- telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
- telegrinder/bot/dispatch/handler/base.py +57 -57
- telegrinder/bot/dispatch/handler/document_reply.py +44 -44
- telegrinder/bot/dispatch/handler/func.py +128 -123
- telegrinder/bot/dispatch/handler/media_group_reply.py +43 -43
- telegrinder/bot/dispatch/handler/message_reply.py +36 -36
- telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
- telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
- telegrinder/bot/dispatch/handler/video_reply.py +44 -44
- telegrinder/bot/dispatch/middleware/__init__.py +3 -3
- telegrinder/bot/dispatch/middleware/abc.py +16 -16
- telegrinder/bot/dispatch/process.py +132 -132
- telegrinder/bot/dispatch/return_manager/__init__.py +13 -13
- telegrinder/bot/dispatch/return_manager/abc.py +108 -108
- telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
- telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
- telegrinder/bot/dispatch/return_manager/message.py +36 -36
- telegrinder/bot/dispatch/view/__init__.py +13 -13
- telegrinder/bot/dispatch/view/abc.py +41 -41
- telegrinder/bot/dispatch/view/base.py +200 -211
- telegrinder/bot/dispatch/view/box.py +129 -129
- telegrinder/bot/dispatch/view/callback_query.py +17 -17
- telegrinder/bot/dispatch/view/chat_join_request.py +16 -16
- telegrinder/bot/dispatch/view/chat_member.py +39 -39
- telegrinder/bot/dispatch/view/inline_query.py +17 -17
- telegrinder/bot/dispatch/view/message.py +44 -44
- telegrinder/bot/dispatch/view/raw.py +114 -118
- telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
- telegrinder/bot/dispatch/waiter_machine/actions.py +13 -13
- telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
- telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +57 -57
- telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +57 -57
- telegrinder/bot/dispatch/waiter_machine/hasher/message.py +53 -53
- telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -19
- telegrinder/bot/dispatch/waiter_machine/machine.py +168 -170
- telegrinder/bot/dispatch/waiter_machine/middleware.py +89 -89
- telegrinder/bot/dispatch/waiter_machine/short_state.py +65 -65
- telegrinder/bot/polling/__init__.py +4 -4
- telegrinder/bot/polling/abc.py +25 -25
- telegrinder/bot/polling/polling.py +131 -131
- telegrinder/bot/rules/__init__.py +62 -62
- telegrinder/bot/rules/abc.py +238 -233
- telegrinder/bot/rules/adapter/__init__.py +9 -9
- telegrinder/bot/rules/adapter/abc.py +29 -29
- telegrinder/bot/rules/adapter/errors.py +5 -5
- telegrinder/bot/rules/adapter/event.py +76 -76
- telegrinder/bot/rules/adapter/node.py +48 -48
- telegrinder/bot/rules/adapter/raw_update.py +30 -30
- telegrinder/bot/rules/callback_data.py +171 -171
- telegrinder/bot/rules/chat_join.py +48 -48
- telegrinder/bot/rules/command.py +126 -126
- telegrinder/bot/rules/enum_text.py +36 -33
- telegrinder/bot/rules/func.py +26 -26
- telegrinder/bot/rules/fuzzy.py +24 -24
- telegrinder/bot/rules/inline.py +60 -60
- telegrinder/bot/rules/integer.py +20 -20
- telegrinder/bot/rules/is_from.py +146 -146
- telegrinder/bot/rules/markup.py +43 -43
- telegrinder/bot/rules/mention.py +14 -14
- telegrinder/bot/rules/message.py +17 -17
- telegrinder/bot/rules/message_entities.py +35 -35
- telegrinder/bot/rules/node.py +27 -27
- telegrinder/bot/rules/regex.py +37 -37
- telegrinder/bot/rules/rule_enum.py +72 -72
- telegrinder/bot/rules/start.py +42 -42
- telegrinder/bot/rules/state.py +37 -37
- telegrinder/bot/rules/text.py +33 -33
- telegrinder/bot/rules/update.py +15 -15
- telegrinder/bot/scenario/__init__.py +5 -5
- telegrinder/bot/scenario/abc.py +19 -19
- telegrinder/bot/scenario/checkbox.py +167 -139
- telegrinder/bot/scenario/choice.py +46 -44
- telegrinder/client/__init__.py +4 -4
- telegrinder/client/abc.py +75 -75
- telegrinder/client/aiohttp.py +130 -130
- telegrinder/model.py +244 -244
- telegrinder/modules.py +237 -237
- telegrinder/msgspec_json.py +14 -14
- telegrinder/msgspec_utils.py +410 -410
- telegrinder/node/__init__.py +20 -20
- telegrinder/node/attachment.py +92 -92
- telegrinder/node/base.py +143 -144
- telegrinder/node/callback_query.py +14 -14
- telegrinder/node/command.py +33 -33
- telegrinder/node/composer.py +196 -184
- telegrinder/node/container.py +27 -27
- telegrinder/node/event.py +71 -73
- telegrinder/node/me.py +16 -16
- telegrinder/node/message.py +14 -14
- telegrinder/node/polymorphic.py +48 -52
- telegrinder/node/rule.py +76 -76
- telegrinder/node/scope.py +38 -38
- telegrinder/node/source.py +71 -71
- telegrinder/node/text.py +21 -21
- telegrinder/node/tools/__init__.py +3 -3
- telegrinder/node/tools/generator.py +40 -40
- telegrinder/node/update.py +15 -15
- telegrinder/rules.py +0 -0
- telegrinder/tools/__init__.py +74 -74
- telegrinder/tools/buttons.py +79 -79
- telegrinder/tools/error_handler/__init__.py +7 -7
- telegrinder/tools/error_handler/abc.py +33 -33
- telegrinder/tools/error_handler/error.py +9 -9
- telegrinder/tools/error_handler/error_handler.py +193 -193
- telegrinder/tools/formatting/__init__.py +46 -46
- telegrinder/tools/formatting/html.py +308 -308
- telegrinder/tools/formatting/links.py +33 -33
- telegrinder/tools/formatting/spec_html_formats.py +111 -111
- telegrinder/tools/functional.py +12 -12
- telegrinder/tools/global_context/__init__.py +7 -7
- telegrinder/tools/global_context/abc.py +63 -63
- telegrinder/tools/global_context/global_context.py +412 -412
- telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
- telegrinder/tools/i18n/__init__.py +12 -12
- telegrinder/tools/i18n/abc.py +32 -32
- telegrinder/tools/i18n/middleware/__init__.py +3 -3
- telegrinder/tools/i18n/middleware/abc.py +25 -25
- telegrinder/tools/i18n/simple.py +43 -43
- telegrinder/tools/kb_set/__init__.py +4 -4
- telegrinder/tools/kb_set/base.py +15 -15
- telegrinder/tools/kb_set/yaml.py +63 -63
- telegrinder/tools/keyboard.py +128 -128
- telegrinder/tools/limited_dict.py +37 -37
- telegrinder/tools/loop_wrapper/__init__.py +4 -4
- telegrinder/tools/loop_wrapper/abc.py +15 -15
- telegrinder/tools/loop_wrapper/loop_wrapper.py +216 -216
- telegrinder/tools/magic.py +168 -164
- telegrinder/tools/parse_mode.py +6 -6
- telegrinder/tools/state_storage/__init__.py +4 -4
- telegrinder/tools/state_storage/abc.py +35 -35
- telegrinder/tools/state_storage/memory.py +25 -25
- telegrinder/types/__init__.py +6 -6
- telegrinder/types/enums.py +672 -672
- telegrinder/types/methods.py +4633 -4633
- telegrinder/types/objects.py +6317 -6317
- telegrinder/verification_utils.py +32 -32
- {telegrinder-0.3.0.post2.dist-info → telegrinder-0.3.2.dist-info}/LICENSE +22 -22
- {telegrinder-0.3.0.post2.dist-info → telegrinder-0.3.2.dist-info}/METADATA +1 -1
- telegrinder-0.3.2.dist-info/RECORD +164 -0
- telegrinder-0.3.0.post2.dist-info/RECORD +0 -164
- {telegrinder-0.3.0.post2.dist-info → telegrinder-0.3.2.dist-info}/WHEEL +0 -0
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import re
|
|
2
|
-
import typing
|
|
3
|
-
|
|
4
|
-
import vbml
|
|
5
|
-
|
|
6
|
-
from telegrinder.tools.global_context import GlobalContext, ctx_var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TelegrinderContext(GlobalContext):
|
|
10
|
-
"""Basic type-hinted telegrinder context with context name `"telegrinder"`.
|
|
11
|
-
|
|
12
|
-
You can use this class or GlobalContext:
|
|
13
|
-
```
|
|
14
|
-
from telegrinder.tools.global_context import GlobalContext, TelegrinderContext
|
|
15
|
-
|
|
16
|
-
ctx1 = TelegrinderContext()
|
|
17
|
-
ctx2 = GlobalContext("telegrinder") # same, but without the type-hints
|
|
18
|
-
assert ctx1 == ctx2 # ok
|
|
19
|
-
```"""
|
|
20
|
-
|
|
21
|
-
__ctx_name__ = "telegrinder"
|
|
22
|
-
|
|
23
|
-
vbml_pattern_flags: re.RegexFlag | None = None
|
|
24
|
-
vbml_patcher: typing.ClassVar[vbml.Patcher] = ctx_var(vbml.Patcher(), const=True)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
__all__ = ("TelegrinderContext",)
|
|
1
|
+
import re
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
import vbml
|
|
5
|
+
|
|
6
|
+
from telegrinder.tools.global_context import GlobalContext, ctx_var
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TelegrinderContext(GlobalContext):
|
|
10
|
+
"""Basic type-hinted telegrinder context with context name `"telegrinder"`.
|
|
11
|
+
|
|
12
|
+
You can use this class or GlobalContext:
|
|
13
|
+
```
|
|
14
|
+
from telegrinder.tools.global_context import GlobalContext, TelegrinderContext
|
|
15
|
+
|
|
16
|
+
ctx1 = TelegrinderContext()
|
|
17
|
+
ctx2 = GlobalContext("telegrinder") # same, but without the type-hints
|
|
18
|
+
assert ctx1 == ctx2 # ok
|
|
19
|
+
```"""
|
|
20
|
+
|
|
21
|
+
__ctx_name__ = "telegrinder"
|
|
22
|
+
|
|
23
|
+
vbml_pattern_flags: re.RegexFlag | None = None
|
|
24
|
+
vbml_patcher: typing.ClassVar[vbml.Patcher] = ctx_var(vbml.Patcher(), const=True)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
__all__ = ("TelegrinderContext",)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
from .abc import ABCI18n, ABCTranslator, I18nEnum
|
|
2
|
-
from .middleware import ABCTranslatorMiddleware
|
|
3
|
-
from .simple import SimpleI18n, SimpleTranslator
|
|
4
|
-
|
|
5
|
-
__all__ = (
|
|
6
|
-
"ABCI18n",
|
|
7
|
-
"ABCTranslator",
|
|
8
|
-
"ABCTranslatorMiddleware",
|
|
9
|
-
"I18nEnum",
|
|
10
|
-
"SimpleI18n",
|
|
11
|
-
"SimpleTranslator",
|
|
12
|
-
)
|
|
1
|
+
from .abc import ABCI18n, ABCTranslator, I18nEnum
|
|
2
|
+
from .middleware import ABCTranslatorMiddleware
|
|
3
|
+
from .simple import SimpleI18n, SimpleTranslator
|
|
4
|
+
|
|
5
|
+
__all__ = (
|
|
6
|
+
"ABCI18n",
|
|
7
|
+
"ABCTranslator",
|
|
8
|
+
"ABCTranslatorMiddleware",
|
|
9
|
+
"I18nEnum",
|
|
10
|
+
"SimpleI18n",
|
|
11
|
+
"SimpleTranslator",
|
|
12
|
+
)
|
telegrinder/tools/i18n/abc.py
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
import typing
|
|
3
|
-
from abc import ABC, abstractmethod
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ABCI18n(ABC):
|
|
7
|
-
@abstractmethod
|
|
8
|
-
def get_translator_by_locale(self, locale: str) -> "ABCTranslator":
|
|
9
|
-
pass
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ABCTranslator(ABC):
|
|
13
|
-
def __init__(self, locale: str, **kwargs: typing.Any) -> None:
|
|
14
|
-
self.locale = locale
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
def get(self, __key: str, *args: typing.Any, **kwargs: typing.Any) -> str:
|
|
18
|
-
"""This translates a key to actual human-readable string"""
|
|
19
|
-
|
|
20
|
-
def __call__(self, __key: str, *args: typing.Any, **kwargs: typing.Any) -> str:
|
|
21
|
-
return self.get(__key, *args, **kwargs)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class I18nEnum(enum.Enum):
|
|
25
|
-
I18N = "_"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
__all__ = (
|
|
29
|
-
"ABCI18n",
|
|
30
|
-
"ABCTranslator",
|
|
31
|
-
"I18nEnum",
|
|
32
|
-
)
|
|
1
|
+
import enum
|
|
2
|
+
import typing
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ABCI18n(ABC):
|
|
7
|
+
@abstractmethod
|
|
8
|
+
def get_translator_by_locale(self, locale: str) -> "ABCTranslator":
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ABCTranslator(ABC):
|
|
13
|
+
def __init__(self, locale: str, **kwargs: typing.Any) -> None:
|
|
14
|
+
self.locale = locale
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def get(self, __key: str, *args: typing.Any, **kwargs: typing.Any) -> str:
|
|
18
|
+
"""This translates a key to actual human-readable string"""
|
|
19
|
+
|
|
20
|
+
def __call__(self, __key: str, *args: typing.Any, **kwargs: typing.Any) -> str:
|
|
21
|
+
return self.get(__key, *args, **kwargs)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class I18nEnum(enum.Enum):
|
|
25
|
+
I18N = "_"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
__all__ = (
|
|
29
|
+
"ABCI18n",
|
|
30
|
+
"ABCTranslator",
|
|
31
|
+
"I18nEnum",
|
|
32
|
+
)
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from .abc import ABCTranslatorMiddleware
|
|
2
|
-
|
|
3
|
-
__all__ = ("ABCTranslatorMiddleware",)
|
|
1
|
+
from .abc import ABCTranslatorMiddleware
|
|
2
|
+
|
|
3
|
+
__all__ = ("ABCTranslatorMiddleware",)
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
from abc import abstractmethod
|
|
3
|
-
|
|
4
|
-
from telegrinder.bot.cute_types.base import BaseCute
|
|
5
|
-
from telegrinder.bot.dispatch.context import Context
|
|
6
|
-
from telegrinder.bot.dispatch.middleware import ABCMiddleware
|
|
7
|
-
from telegrinder.tools.i18n import ABCI18n, I18nEnum
|
|
8
|
-
|
|
9
|
-
T = typing.TypeVar("T", bound=BaseCute)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class ABCTranslatorMiddleware(ABCMiddleware[T]):
|
|
13
|
-
def __init__(self, i18n: ABCI18n) -> None:
|
|
14
|
-
self.i18n = i18n
|
|
15
|
-
|
|
16
|
-
@abstractmethod
|
|
17
|
-
async def get_locale(self, event: T) -> str:
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
async def pre(self, event: T, ctx: Context) -> bool:
|
|
21
|
-
ctx[I18nEnum.I18N] = self.i18n.get_translator_by_locale(await self.get_locale(event))
|
|
22
|
-
return True
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
__all__ = ("ABCTranslatorMiddleware",)
|
|
1
|
+
import typing
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
|
|
4
|
+
from telegrinder.bot.cute_types.base import BaseCute
|
|
5
|
+
from telegrinder.bot.dispatch.context import Context
|
|
6
|
+
from telegrinder.bot.dispatch.middleware import ABCMiddleware
|
|
7
|
+
from telegrinder.tools.i18n import ABCI18n, I18nEnum
|
|
8
|
+
|
|
9
|
+
T = typing.TypeVar("T", bound=BaseCute)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ABCTranslatorMiddleware(ABCMiddleware[T]):
|
|
13
|
+
def __init__(self, i18n: ABCI18n) -> None:
|
|
14
|
+
self.i18n = i18n
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
async def get_locale(self, event: T) -> str:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
async def pre(self, event: T, ctx: Context) -> bool:
|
|
21
|
+
ctx[I18nEnum.I18N] = self.i18n.get_translator_by_locale(await self.get_locale(event))
|
|
22
|
+
return True
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = ("ABCTranslatorMiddleware",)
|
telegrinder/tools/i18n/simple.py
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
"""This is an implementation of GNU gettext (pyBabel)."""
|
|
2
|
-
|
|
3
|
-
import gettext
|
|
4
|
-
import os
|
|
5
|
-
|
|
6
|
-
from telegrinder.tools.i18n.abc import ABCI18n, ABCTranslator
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class SimpleTranslator(ABCTranslator):
|
|
10
|
-
def __init__(self, locale: str, g: gettext.GNUTranslations) -> None:
|
|
11
|
-
self.g = g
|
|
12
|
-
super().__init__(locale)
|
|
13
|
-
|
|
14
|
-
def get(self, __key: str, *args: object, **kwargs: object) -> str:
|
|
15
|
-
return self.g.gettext(__key).format(*args, **kwargs)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class SimpleI18n(ABCI18n):
|
|
19
|
-
def __init__(self, folder: str, domain: str, default_locale: str) -> None:
|
|
20
|
-
self.folder = folder
|
|
21
|
-
self.domain = domain
|
|
22
|
-
self.default_locale = default_locale
|
|
23
|
-
self.translators = self._load_translators()
|
|
24
|
-
|
|
25
|
-
def _load_translators(self) -> dict[str, gettext.GNUTranslations]:
|
|
26
|
-
result = {}
|
|
27
|
-
for name in os.listdir(self.folder):
|
|
28
|
-
if not os.path.isdir(os.path.join(self.folder, name)):
|
|
29
|
-
continue
|
|
30
|
-
|
|
31
|
-
mo_path = os.path.join(self.folder, name, "LC_MESSAGES", f"{self.domain}.mo")
|
|
32
|
-
if os.path.exists(mo_path):
|
|
33
|
-
with open(mo_path, "rb") as f:
|
|
34
|
-
result[name] = gettext.GNUTranslations(f)
|
|
35
|
-
elif os.path.exists(mo_path[:-2] + "po"):
|
|
36
|
-
raise FileNotFoundError(".po files should be compiled first")
|
|
37
|
-
return result
|
|
38
|
-
|
|
39
|
-
def get_translator_by_locale(self, locale: str) -> "SimpleTranslator":
|
|
40
|
-
return SimpleTranslator(locale, self.translators.get(locale, self.translators[self.default_locale]))
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
__all__ = ("SimpleI18n", "SimpleTranslator")
|
|
1
|
+
"""This is an implementation of GNU gettext (pyBabel)."""
|
|
2
|
+
|
|
3
|
+
import gettext
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
from telegrinder.tools.i18n.abc import ABCI18n, ABCTranslator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SimpleTranslator(ABCTranslator):
|
|
10
|
+
def __init__(self, locale: str, g: gettext.GNUTranslations) -> None:
|
|
11
|
+
self.g = g
|
|
12
|
+
super().__init__(locale)
|
|
13
|
+
|
|
14
|
+
def get(self, __key: str, *args: object, **kwargs: object) -> str:
|
|
15
|
+
return self.g.gettext(__key).format(*args, **kwargs)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SimpleI18n(ABCI18n):
|
|
19
|
+
def __init__(self, folder: str, domain: str, default_locale: str) -> None:
|
|
20
|
+
self.folder = folder
|
|
21
|
+
self.domain = domain
|
|
22
|
+
self.default_locale = default_locale
|
|
23
|
+
self.translators = self._load_translators()
|
|
24
|
+
|
|
25
|
+
def _load_translators(self) -> dict[str, gettext.GNUTranslations]:
|
|
26
|
+
result = {}
|
|
27
|
+
for name in os.listdir(self.folder):
|
|
28
|
+
if not os.path.isdir(os.path.join(self.folder, name)):
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
mo_path = os.path.join(self.folder, name, "LC_MESSAGES", f"{self.domain}.mo")
|
|
32
|
+
if os.path.exists(mo_path):
|
|
33
|
+
with open(mo_path, "rb") as f:
|
|
34
|
+
result[name] = gettext.GNUTranslations(f)
|
|
35
|
+
elif os.path.exists(mo_path[:-2] + "po"):
|
|
36
|
+
raise FileNotFoundError(".po files should be compiled first")
|
|
37
|
+
return result
|
|
38
|
+
|
|
39
|
+
def get_translator_by_locale(self, locale: str) -> "SimpleTranslator":
|
|
40
|
+
return SimpleTranslator(locale, self.translators.get(locale, self.translators[self.default_locale]))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
__all__ = ("SimpleI18n", "SimpleTranslator")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .base import KeyboardSetBase, KeyboardSetError
|
|
2
|
-
from .yaml import KeyboardSetYAML
|
|
3
|
-
|
|
4
|
-
__all__ = ("KeyboardSetBase", "KeyboardSetError", "KeyboardSetYAML")
|
|
1
|
+
from .base import KeyboardSetBase, KeyboardSetError
|
|
2
|
+
from .yaml import KeyboardSetYAML
|
|
3
|
+
|
|
4
|
+
__all__ = ("KeyboardSetBase", "KeyboardSetError", "KeyboardSetYAML")
|
telegrinder/tools/kb_set/base.py
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class KeyboardSetError(LookupError):
|
|
5
|
-
pass
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class KeyboardSetBase(ABC):
|
|
9
|
-
@classmethod
|
|
10
|
-
@abstractmethod
|
|
11
|
-
def load(cls) -> None:
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
__all__ = ("KeyboardSetBase", "KeyboardSetError")
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class KeyboardSetError(LookupError):
|
|
5
|
+
pass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class KeyboardSetBase(ABC):
|
|
9
|
+
@classmethod
|
|
10
|
+
@abstractmethod
|
|
11
|
+
def load(cls) -> None:
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
__all__ = ("KeyboardSetBase", "KeyboardSetError")
|
telegrinder/tools/kb_set/yaml.py
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import re
|
|
3
|
-
import typing
|
|
4
|
-
|
|
5
|
-
import yaml
|
|
6
|
-
|
|
7
|
-
from telegrinder.tools.keyboard import InlineKeyboard, Keyboard
|
|
8
|
-
|
|
9
|
-
from .base import KeyboardSetBase, KeyboardSetError
|
|
10
|
-
|
|
11
|
-
PathLike: typing.TypeAlias = str | os.PathLike[str]
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class KeyboardSetYAML(KeyboardSetBase):
|
|
15
|
-
__config__: PathLike
|
|
16
|
-
|
|
17
|
-
@classmethod
|
|
18
|
-
def load(cls) -> None:
|
|
19
|
-
config_path = getattr(cls, "__config__", "keyboards.yaml")
|
|
20
|
-
if not os.path.exists(config_path):
|
|
21
|
-
raise FileNotFoundError(f"Config file for {cls.__name__!r} is undefined.")
|
|
22
|
-
|
|
23
|
-
config = yaml.load(
|
|
24
|
-
open( # noqa: SIM115
|
|
25
|
-
str(config_path),
|
|
26
|
-
mode="r",
|
|
27
|
-
encoding="UTF-8",
|
|
28
|
-
),
|
|
29
|
-
yaml.Loader,
|
|
30
|
-
)
|
|
31
|
-
for name, hint in typing.get_type_hints(cls).items():
|
|
32
|
-
g = re.match(r"(?:kb_|keyboard_)(.+)", name.lower())
|
|
33
|
-
if not g:
|
|
34
|
-
continue
|
|
35
|
-
|
|
36
|
-
short_name = g.group(1)
|
|
37
|
-
if short_name not in config:
|
|
38
|
-
raise KeyboardSetError(f"Keyboard {short_name!r} is undefined in config.")
|
|
39
|
-
|
|
40
|
-
kb_config = config[short_name]
|
|
41
|
-
if (
|
|
42
|
-
not isinstance(kb_config, dict)
|
|
43
|
-
or "buttons" not in kb_config
|
|
44
|
-
or not isinstance(kb_config["buttons"], list)
|
|
45
|
-
):
|
|
46
|
-
raise KeyboardSetError(
|
|
47
|
-
"Keyboard should be dict with field buttons which must be a list, " "check documentation."
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
buttons = kb_config.pop("buttons")
|
|
51
|
-
new_keyboard: Keyboard | InlineKeyboard = hint(**kb_config)
|
|
52
|
-
for button in buttons:
|
|
53
|
-
if not button:
|
|
54
|
-
new_keyboard.row()
|
|
55
|
-
continue
|
|
56
|
-
if "text" not in button:
|
|
57
|
-
raise KeyboardSetError("Text is required in button.")
|
|
58
|
-
new_keyboard.add(new_keyboard.BUTTON(**button)) # type: ignore
|
|
59
|
-
|
|
60
|
-
setattr(cls, name, new_keyboard)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
__all__ = ("KeyboardSetYAML",)
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
|
|
7
|
+
from telegrinder.tools.keyboard import InlineKeyboard, Keyboard
|
|
8
|
+
|
|
9
|
+
from .base import KeyboardSetBase, KeyboardSetError
|
|
10
|
+
|
|
11
|
+
PathLike: typing.TypeAlias = str | os.PathLike[str]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class KeyboardSetYAML(KeyboardSetBase):
|
|
15
|
+
__config__: PathLike
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def load(cls) -> None:
|
|
19
|
+
config_path = getattr(cls, "__config__", "keyboards.yaml")
|
|
20
|
+
if not os.path.exists(config_path):
|
|
21
|
+
raise FileNotFoundError(f"Config file for {cls.__name__!r} is undefined.")
|
|
22
|
+
|
|
23
|
+
config = yaml.load(
|
|
24
|
+
open( # noqa: SIM115
|
|
25
|
+
str(config_path),
|
|
26
|
+
mode="r",
|
|
27
|
+
encoding="UTF-8",
|
|
28
|
+
),
|
|
29
|
+
yaml.Loader,
|
|
30
|
+
)
|
|
31
|
+
for name, hint in typing.get_type_hints(cls).items():
|
|
32
|
+
g = re.match(r"(?:kb_|keyboard_)(.+)", name.lower())
|
|
33
|
+
if not g:
|
|
34
|
+
continue
|
|
35
|
+
|
|
36
|
+
short_name = g.group(1)
|
|
37
|
+
if short_name not in config:
|
|
38
|
+
raise KeyboardSetError(f"Keyboard {short_name!r} is undefined in config.")
|
|
39
|
+
|
|
40
|
+
kb_config = config[short_name]
|
|
41
|
+
if (
|
|
42
|
+
not isinstance(kb_config, dict)
|
|
43
|
+
or "buttons" not in kb_config
|
|
44
|
+
or not isinstance(kb_config["buttons"], list)
|
|
45
|
+
):
|
|
46
|
+
raise KeyboardSetError(
|
|
47
|
+
"Keyboard should be dict with field buttons which must be a list, " "check documentation."
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
buttons = kb_config.pop("buttons")
|
|
51
|
+
new_keyboard: Keyboard | InlineKeyboard = hint(**kb_config)
|
|
52
|
+
for button in buttons:
|
|
53
|
+
if not button:
|
|
54
|
+
new_keyboard.row()
|
|
55
|
+
continue
|
|
56
|
+
if "text" not in button:
|
|
57
|
+
raise KeyboardSetError("Text is required in button.")
|
|
58
|
+
new_keyboard.add(new_keyboard.BUTTON(**button)) # type: ignore
|
|
59
|
+
|
|
60
|
+
setattr(cls, name, new_keyboard)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
__all__ = ("KeyboardSetYAML",)
|