telegrinder 0.1.dev20__tar.gz → 0.1.dev159__tar.gz
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-0.1.dev20 → telegrinder-0.1.dev159}/LICENSE +2 -1
- telegrinder-0.1.dev159/PKG-INFO +109 -0
- telegrinder-0.1.dev159/pyproject.toml +73 -0
- telegrinder-0.1.dev159/readme.md +74 -0
- telegrinder-0.1.dev159/telegrinder/__init__.py +146 -0
- telegrinder-0.1.dev159/telegrinder/api/__init__.py +13 -0
- telegrinder-0.1.dev159/telegrinder/api/abc.py +68 -0
- telegrinder-0.1.dev159/telegrinder/api/api.py +80 -0
- telegrinder-0.1.dev159/telegrinder/api/error.py +16 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/api/response.py +11 -7
- telegrinder-0.1.dev159/telegrinder/bot/__init__.py +76 -0
- telegrinder-0.1.dev159/telegrinder/bot/bot.py +59 -0
- telegrinder-0.1.dev159/telegrinder/bot/cute_types/__init__.py +13 -0
- telegrinder-0.1.dev159/telegrinder/bot/cute_types/base.py +138 -0
- telegrinder-0.1.dev159/telegrinder/bot/cute_types/callback_query.py +471 -0
- telegrinder-0.1.dev159/telegrinder/bot/cute_types/inline_query.py +41 -0
- telegrinder-0.1.dev159/telegrinder/bot/cute_types/message.py +3005 -0
- telegrinder-0.1.dev159/telegrinder/bot/cute_types/update.py +30 -0
- telegrinder-0.1.dev159/telegrinder/bot/cute_types/utils.py +794 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/__init__.py +58 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/abc.py +21 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/composition.py +74 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/context.py +71 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/dispatch.py +124 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/handler/__init__.py +5 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/bot/dispatch/handler/abc.py +11 -5
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/handler/func.py +58 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/handler/message_reply.py +46 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/bot/dispatch/middleware/__init__.py +2 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/middleware/abc.py +18 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/process.py +83 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/return_manager/__init__.py +19 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/return_manager/abc.py +95 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/return_manager/callback_query.py +19 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/return_manager/inline_query.py +14 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/return_manager/message.py +25 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/view/__init__.py +16 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/view/abc.py +143 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/view/box.py +38 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/view/callback_query.py +20 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/view/inline_query.py +18 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/view/message.py +18 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/waiter_machine/__init__.py +9 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/waiter_machine/machine.py +116 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/waiter_machine/middleware.py +76 -0
- telegrinder-0.1.dev159/telegrinder/bot/dispatch/waiter_machine/short_state.py +37 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/bot/polling/__init__.py +2 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/bot/polling/abc.py +11 -4
- telegrinder-0.1.dev159/telegrinder/bot/polling/polling.py +120 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/__init__.py +101 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/abc.py +120 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/adapter/__init__.py +11 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/adapter/abc.py +21 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/adapter/errors.py +5 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/adapter/event.py +49 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/adapter/raw_update.py +24 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/callback_data.py +178 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/command.py +116 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/enum_text.py +28 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/func.py +26 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/fuzzy.py +27 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/inline.py +61 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/integer.py +19 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/is_from.py +152 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/markup.py +37 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/mention.py +17 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/message_entities.py +33 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/regex.py +38 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/rule_enum.py +74 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/start.py +42 -0
- telegrinder-0.1.dev159/telegrinder/bot/rules/text.py +35 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/bot/scenario/__init__.py +2 -0
- telegrinder-0.1.dev159/telegrinder/bot/scenario/abc.py +19 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/bot/scenario/checkbox.py +48 -30
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/bot/scenario/choice.py +16 -10
- telegrinder-0.1.dev159/telegrinder/client/__init__.py +4 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/client/abc.py +26 -16
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/client/aiohttp.py +54 -32
- telegrinder-0.1.dev159/telegrinder/model.py +144 -0
- telegrinder-0.1.dev159/telegrinder/modules.py +244 -0
- telegrinder-0.1.dev159/telegrinder/msgspec_json.py +14 -0
- telegrinder-0.1.dev159/telegrinder/msgspec_utils.py +227 -0
- telegrinder-0.1.dev159/telegrinder/node/__init__.py +31 -0
- telegrinder-0.1.dev159/telegrinder/node/attachment.py +71 -0
- telegrinder-0.1.dev159/telegrinder/node/base.py +93 -0
- telegrinder-0.1.dev159/telegrinder/node/composer.py +71 -0
- telegrinder-0.1.dev159/telegrinder/node/container.py +22 -0
- telegrinder-0.1.dev159/telegrinder/node/message.py +18 -0
- telegrinder-0.1.dev159/telegrinder/node/rule.py +56 -0
- telegrinder-0.1.dev159/telegrinder/node/source.py +31 -0
- telegrinder-0.1.dev159/telegrinder/node/text.py +13 -0
- telegrinder-0.1.dev159/telegrinder/node/tools/__init__.py +3 -0
- telegrinder-0.1.dev159/telegrinder/node/tools/generator.py +40 -0
- telegrinder-0.1.dev159/telegrinder/node/update.py +12 -0
- telegrinder-0.1.dev159/telegrinder/rules.py +1 -0
- telegrinder-0.1.dev159/telegrinder/tools/__init__.py +139 -0
- telegrinder-0.1.dev159/telegrinder/tools/buttons.py +89 -0
- telegrinder-0.1.dev159/telegrinder/tools/error_handler/__init__.py +8 -0
- telegrinder-0.1.dev159/telegrinder/tools/error_handler/abc.py +30 -0
- telegrinder-0.1.dev159/telegrinder/tools/error_handler/error_handler.py +156 -0
- telegrinder-0.1.dev159/telegrinder/tools/formatting/__init__.py +81 -0
- telegrinder-0.1.dev159/telegrinder/tools/formatting/html.py +304 -0
- telegrinder-0.1.dev159/telegrinder/tools/formatting/links.py +32 -0
- telegrinder-0.1.dev159/telegrinder/tools/formatting/spec_html_formats.py +121 -0
- telegrinder-0.1.dev159/telegrinder/tools/global_context/__init__.py +12 -0
- telegrinder-0.1.dev159/telegrinder/tools/global_context/abc.py +66 -0
- telegrinder-0.1.dev159/telegrinder/tools/global_context/global_context.py +451 -0
- telegrinder-0.1.dev159/telegrinder/tools/global_context/telegrinder_ctx.py +25 -0
- telegrinder-0.1.dev159/telegrinder/tools/i18n/__init__.py +12 -0
- telegrinder-0.1.dev159/telegrinder/tools/i18n/base.py +31 -0
- telegrinder-0.1.dev159/telegrinder/tools/i18n/middleware/__init__.py +3 -0
- telegrinder-0.1.dev159/telegrinder/tools/i18n/middleware/base.py +26 -0
- telegrinder-0.1.dev159/telegrinder/tools/i18n/simple.py +48 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/tools/kb_set/__init__.py +2 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/tools/kb_set/base.py +3 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/tools/kb_set/yaml.py +28 -17
- telegrinder-0.1.dev159/telegrinder/tools/keyboard.py +137 -0
- telegrinder-0.1.dev159/telegrinder/tools/loop_wrapper/__init__.py +4 -0
- telegrinder-0.1.dev159/telegrinder/tools/loop_wrapper/abc.py +18 -0
- telegrinder-0.1.dev159/telegrinder/tools/loop_wrapper/loop_wrapper.py +132 -0
- telegrinder-0.1.dev159/telegrinder/tools/magic.py +66 -0
- telegrinder-0.1.dev159/telegrinder/tools/parse_mode.py +6 -0
- {telegrinder-0.1.dev20 → telegrinder-0.1.dev159}/telegrinder/types/__init__.py +1 -0
- telegrinder-0.1.dev159/telegrinder/types/enums.py +653 -0
- telegrinder-0.1.dev159/telegrinder/types/methods.py +4247 -0
- telegrinder-0.1.dev159/telegrinder/types/objects.py +5275 -0
- telegrinder-0.1.dev20/PKG-INFO +0 -22
- telegrinder-0.1.dev20/pyproject.toml +0 -23
- telegrinder-0.1.dev20/telegrinder/__init__.py +0 -39
- telegrinder-0.1.dev20/telegrinder/api/__init__.py +0 -4
- telegrinder-0.1.dev20/telegrinder/api/abc.py +0 -52
- telegrinder-0.1.dev20/telegrinder/api/api.py +0 -61
- telegrinder-0.1.dev20/telegrinder/api/error.py +0 -6
- telegrinder-0.1.dev20/telegrinder/bot/__init__.py +0 -15
- telegrinder-0.1.dev20/telegrinder/bot/bot.py +0 -53
- telegrinder-0.1.dev20/telegrinder/bot/cute_types/__init__.py +0 -3
- telegrinder-0.1.dev20/telegrinder/bot/cute_types/callback_query.py +0 -28
- telegrinder-0.1.dev20/telegrinder/bot/cute_types/inline_query.py +0 -35
- telegrinder-0.1.dev20/telegrinder/bot/cute_types/message.py +0 -101
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/__init__.py +0 -5
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/abc.py +0 -19
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/dispatch.py +0 -87
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/handler/__init__.py +0 -2
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/handler/func.py +0 -49
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/middleware/abc.py +0 -12
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/process.py +0 -79
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/view/__init__.py +0 -4
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/view/abc.py +0 -17
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/view/callback_query.py +0 -46
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/view/inline_query.py +0 -46
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/view/message.py +0 -54
- telegrinder-0.1.dev20/telegrinder/bot/dispatch/waiter.py +0 -38
- telegrinder-0.1.dev20/telegrinder/bot/polling/polling.py +0 -71
- telegrinder-0.1.dev20/telegrinder/bot/rules/__init__.py +0 -15
- telegrinder-0.1.dev20/telegrinder/bot/rules/abc.py +0 -102
- telegrinder-0.1.dev20/telegrinder/bot/rules/callback_data.py +0 -57
- telegrinder-0.1.dev20/telegrinder/bot/rules/func.py +0 -26
- telegrinder-0.1.dev20/telegrinder/bot/rules/fuzzy.py +0 -24
- telegrinder-0.1.dev20/telegrinder/bot/rules/integer.py +0 -14
- telegrinder-0.1.dev20/telegrinder/bot/rules/is_from.py +0 -11
- telegrinder-0.1.dev20/telegrinder/bot/rules/markup.py +0 -34
- telegrinder-0.1.dev20/telegrinder/bot/rules/regex.py +0 -30
- telegrinder-0.1.dev20/telegrinder/bot/rules/start.py +0 -30
- telegrinder-0.1.dev20/telegrinder/bot/rules/text.py +0 -26
- telegrinder-0.1.dev20/telegrinder/bot/scenario/abc.py +0 -12
- telegrinder-0.1.dev20/telegrinder/client/__init__.py +0 -2
- telegrinder-0.1.dev20/telegrinder/model.py +0 -65
- telegrinder-0.1.dev20/telegrinder/modules.py +0 -76
- telegrinder-0.1.dev20/telegrinder/result.py +0 -38
- telegrinder-0.1.dev20/telegrinder/rules.py +0 -1
- telegrinder-0.1.dev20/telegrinder/tools/__init__.py +0 -5
- telegrinder-0.1.dev20/telegrinder/tools/buttons.py +0 -51
- telegrinder-0.1.dev20/telegrinder/tools/formatting/__init__.py +0 -3
- telegrinder-0.1.dev20/telegrinder/tools/formatting/abc.py +0 -52
- telegrinder-0.1.dev20/telegrinder/tools/formatting/html.py +0 -58
- telegrinder-0.1.dev20/telegrinder/tools/formatting/markdown.py +0 -57
- telegrinder-0.1.dev20/telegrinder/tools/keyboard.py +0 -115
- telegrinder-0.1.dev20/telegrinder/tools/magic.py +0 -41
- telegrinder-0.1.dev20/telegrinder/tools/parse_mode.py +0 -7
- telegrinder-0.1.dev20/telegrinder/types/methods.py +0 -1419
- telegrinder-0.1.dev20/telegrinder/types/objects.py +0 -2249
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: telegrinder
|
|
3
|
+
Version: 0.1.dev159
|
|
4
|
+
Summary: Framework for effective and reliable async telegram bot building.
|
|
5
|
+
Home-page: https://github.com/timoniq/telegrinder
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: telegram,telegram bot api framework,telegrinder,asyncio,middleware,composition,bot api,async
|
|
8
|
+
Author: timoniq
|
|
9
|
+
Author-email: tesseradecades@mail.ru
|
|
10
|
+
Maintainer: luwqz1
|
|
11
|
+
Requires-Python: >=3.11,<4.0
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Dist: PyYAML (>=6.0,<7.0)
|
|
22
|
+
Requires-Dist: aiohttp (>=3.8.1,<4.0.0)
|
|
23
|
+
Requires-Dist: certifi (>=2023.7.22,<2024.0.0)
|
|
24
|
+
Requires-Dist: choicelib (>=0.1.5,<0.2.0)
|
|
25
|
+
Requires-Dist: colorama (>=0.4.0,<0.5.0)
|
|
26
|
+
Requires-Dist: envparse (>=0.2.0,<0.3.0)
|
|
27
|
+
Requires-Dist: fntypes (>=0.1.1,<0.2.0)
|
|
28
|
+
Requires-Dist: msgspec (>=0.18.4,<0.19.0)
|
|
29
|
+
Requires-Dist: requests (>=2.28.1,<3.0.0)
|
|
30
|
+
Requires-Dist: typing-extensions (>=4.8.0,<5.0.0)
|
|
31
|
+
Requires-Dist: vbml (>=1.1.post1,<2.0)
|
|
32
|
+
Project-URL: Repository, https://github.com/timoniq/telegrinder
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# Telegrinder
|
|
36
|
+
|
|
37
|
+
Framework for effective and reliable telegram bot building.
|
|
38
|
+
|
|
39
|
+
Still in development.
|
|
40
|
+
|
|
41
|
+
* Type hinted
|
|
42
|
+
* Customizable and extensible
|
|
43
|
+
* Ready to use scenarios and rules
|
|
44
|
+
* Fast models built on msgspec
|
|
45
|
+
* Both low-level and high-level API
|
|
46
|
+
|
|
47
|
+
# Getting started
|
|
48
|
+
|
|
49
|
+
Install using pip:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
pip install telegrinder
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Using poetry:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
poetry add telegrinder
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Install from github:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
pip install -U https://github.com/timoniq/telegrinder/archive/dev.zip
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
poetry add git+https://github.com/timoniq/telegrinder.git#dev
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Basic example:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from telegrinder import API, Message, Telegrinder, Token
|
|
75
|
+
from telegrinder.modules import logger
|
|
76
|
+
from telegrinder.rules import Text
|
|
77
|
+
|
|
78
|
+
logger.set_level("INFO")
|
|
79
|
+
api = API(token=Token("123:token"))
|
|
80
|
+
bot = Telegrinder(api)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@bot.on.message(Text("/start"))
|
|
84
|
+
async def start(message: Message):
|
|
85
|
+
me = (await api.get_me()).unwrap()
|
|
86
|
+
await message.answer(
|
|
87
|
+
f"Hello, {message.from_user.full_name}! I'm {me.full_name}."
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
bot.run_forever()
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
# Documentation
|
|
95
|
+
|
|
96
|
+
[Readthedocs](https://telegrinder.readthedocs.io)
|
|
97
|
+
|
|
98
|
+
# Community
|
|
99
|
+
|
|
100
|
+
Join our [telegram forum](https://t.me/botoforum).
|
|
101
|
+
|
|
102
|
+
# [Contributing](https://github.com/timoniq/telegrinder/blob/main/contributing.md)
|
|
103
|
+
|
|
104
|
+
# License
|
|
105
|
+
|
|
106
|
+
Telegrinder is [MIT licensed](./LICENSE)
|
|
107
|
+
Copyright © 2022-2024 [timoniq](https://github.com/timoniq)\
|
|
108
|
+
Copyright © 2024 [luwqz1](https://github.com/luwqz1)
|
|
109
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "telegrinder"
|
|
3
|
+
version = "0.1.dev159"
|
|
4
|
+
description = "Framework for effective and reliable async telegram bot building."
|
|
5
|
+
authors = ["timoniq <tesseradecades@mail.ru>"]
|
|
6
|
+
maintainers = ["luwqz1"]
|
|
7
|
+
license = "MIT"
|
|
8
|
+
readme = "readme.md"
|
|
9
|
+
homepage = "https://github.com/timoniq/telegrinder"
|
|
10
|
+
repository = "https://github.com/timoniq/telegrinder"
|
|
11
|
+
keywords = [
|
|
12
|
+
"telegram",
|
|
13
|
+
"telegram bot api framework",
|
|
14
|
+
"telegrinder",
|
|
15
|
+
"asyncio",
|
|
16
|
+
"middleware",
|
|
17
|
+
"composition",
|
|
18
|
+
"bot api",
|
|
19
|
+
"async",
|
|
20
|
+
]
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Environment :: Console",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"License :: OSI Approved :: MIT License",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
27
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
28
|
+
"Typing :: Typed",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[tool.poetry.dependencies]
|
|
32
|
+
python = "^3.11"
|
|
33
|
+
aiohttp = "^3.8.1"
|
|
34
|
+
colorama = "^0.4.0"
|
|
35
|
+
vbml = "^1.1.post1"
|
|
36
|
+
choicelib = "^0.1.5"
|
|
37
|
+
envparse = "^0.2.0"
|
|
38
|
+
PyYAML = "^6.0"
|
|
39
|
+
certifi = "^2023.7.22"
|
|
40
|
+
msgspec = "^0.18.4"
|
|
41
|
+
requests = "^2.28.1"
|
|
42
|
+
typing-extensions = "^4.8.0"
|
|
43
|
+
fntypes = "^0.1.1"
|
|
44
|
+
|
|
45
|
+
[tool.poetry.group.dev.dependencies]
|
|
46
|
+
pytest = "^8.0.0"
|
|
47
|
+
pytest-asyncio = "^0.23.5"
|
|
48
|
+
pytest-cov = "^4.0.0"
|
|
49
|
+
pytest-mock = "^3.10.0"
|
|
50
|
+
|
|
51
|
+
[tool.poetry.dev-dependencies]
|
|
52
|
+
|
|
53
|
+
[build-system]
|
|
54
|
+
requires = ["poetry-core>=1.0.0"]
|
|
55
|
+
build-backend = "poetry.core.masonry.api"
|
|
56
|
+
|
|
57
|
+
[tool.ruff]
|
|
58
|
+
line-length = 100
|
|
59
|
+
target-version = "py311"
|
|
60
|
+
select = ["I", "N", "ANN", "COM", "YTT", "TCH", "SIM"]
|
|
61
|
+
ignore = [
|
|
62
|
+
"ANN001", "ANN002", "ANN003", "ANN101", "ANN102", "ANN201", "ANN202",
|
|
63
|
+
"ANN204", "ANN206", "ANN401", "COM812", "N818", "TCH001", "TCH004"
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
[tool.pytest.ini_options]
|
|
67
|
+
asyncio_mode = "auto"
|
|
68
|
+
|
|
69
|
+
[tool.ruff.per-file-ignores]
|
|
70
|
+
"__init__.py" = ["F401", "F403"]
|
|
71
|
+
|
|
72
|
+
[tool.ruff.flake8-quotes]
|
|
73
|
+
docstring-quotes = "double"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Telegrinder
|
|
2
|
+
|
|
3
|
+
Framework for effective and reliable telegram bot building.
|
|
4
|
+
|
|
5
|
+
Still in development.
|
|
6
|
+
|
|
7
|
+
* Type hinted
|
|
8
|
+
* Customizable and extensible
|
|
9
|
+
* Ready to use scenarios and rules
|
|
10
|
+
* Fast models built on msgspec
|
|
11
|
+
* Both low-level and high-level API
|
|
12
|
+
|
|
13
|
+
# Getting started
|
|
14
|
+
|
|
15
|
+
Install using pip:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
pip install telegrinder
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Using poetry:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
poetry add telegrinder
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Install from github:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
pip install -U https://github.com/timoniq/telegrinder/archive/dev.zip
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
poetry add git+https://github.com/timoniq/telegrinder.git#dev
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Basic example:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from telegrinder import API, Message, Telegrinder, Token
|
|
41
|
+
from telegrinder.modules import logger
|
|
42
|
+
from telegrinder.rules import Text
|
|
43
|
+
|
|
44
|
+
logger.set_level("INFO")
|
|
45
|
+
api = API(token=Token("123:token"))
|
|
46
|
+
bot = Telegrinder(api)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@bot.on.message(Text("/start"))
|
|
50
|
+
async def start(message: Message):
|
|
51
|
+
me = (await api.get_me()).unwrap()
|
|
52
|
+
await message.answer(
|
|
53
|
+
f"Hello, {message.from_user.full_name}! I'm {me.full_name}."
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
bot.run_forever()
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
# Documentation
|
|
61
|
+
|
|
62
|
+
[Readthedocs](https://telegrinder.readthedocs.io)
|
|
63
|
+
|
|
64
|
+
# Community
|
|
65
|
+
|
|
66
|
+
Join our [telegram forum](https://t.me/botoforum).
|
|
67
|
+
|
|
68
|
+
# [Contributing](https://github.com/timoniq/telegrinder/blob/main/contributing.md)
|
|
69
|
+
|
|
70
|
+
# License
|
|
71
|
+
|
|
72
|
+
Telegrinder is [MIT licensed](./LICENSE)
|
|
73
|
+
Copyright © 2022-2024 [timoniq](https://github.com/timoniq)\
|
|
74
|
+
Copyright © 2024 [luwqz1](https://github.com/luwqz1)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from .api import ABCAPI, API, APIError, APIResponse, Token
|
|
4
|
+
from .bot import (
|
|
5
|
+
ABCDispatch,
|
|
6
|
+
ABCHandler,
|
|
7
|
+
ABCMiddleware,
|
|
8
|
+
ABCPolling,
|
|
9
|
+
ABCReturnManager,
|
|
10
|
+
ABCRule,
|
|
11
|
+
ABCScenario,
|
|
12
|
+
ABCStateView,
|
|
13
|
+
ABCView,
|
|
14
|
+
BaseCute,
|
|
15
|
+
BaseReturnManager,
|
|
16
|
+
BaseStateView,
|
|
17
|
+
BaseView,
|
|
18
|
+
CallbackQueryCute,
|
|
19
|
+
CallbackQueryReturnManager,
|
|
20
|
+
CallbackQueryView,
|
|
21
|
+
Checkbox,
|
|
22
|
+
Dispatch,
|
|
23
|
+
FuncHandler,
|
|
24
|
+
InlineQueryCute,
|
|
25
|
+
InlineQueryReturnManager,
|
|
26
|
+
MessageCute,
|
|
27
|
+
MessageReplyHandler,
|
|
28
|
+
MessageReturnManager,
|
|
29
|
+
MessageRule,
|
|
30
|
+
MessageView,
|
|
31
|
+
Polling,
|
|
32
|
+
SingleChoice,
|
|
33
|
+
Telegrinder,
|
|
34
|
+
ViewBox,
|
|
35
|
+
WaiterMachine,
|
|
36
|
+
register_manager,
|
|
37
|
+
)
|
|
38
|
+
from .client import ABCClient, AiohttpClient
|
|
39
|
+
from .model import Model
|
|
40
|
+
from .modules import logger
|
|
41
|
+
from .tools import (
|
|
42
|
+
ABCGlobalContext,
|
|
43
|
+
ABCLoopWrapper,
|
|
44
|
+
ABCTranslator,
|
|
45
|
+
ABCTranslatorMiddleware,
|
|
46
|
+
AnyMarkup,
|
|
47
|
+
Button,
|
|
48
|
+
CtxVar,
|
|
49
|
+
DelayedTask,
|
|
50
|
+
FormatString,
|
|
51
|
+
GlobalContext,
|
|
52
|
+
HTMLFormatter,
|
|
53
|
+
I18nEnum,
|
|
54
|
+
InlineButton,
|
|
55
|
+
InlineKeyboard,
|
|
56
|
+
Keyboard,
|
|
57
|
+
KeyboardSetBase,
|
|
58
|
+
KeyboardSetYAML,
|
|
59
|
+
LoopWrapper,
|
|
60
|
+
ParseMode,
|
|
61
|
+
RowButtons,
|
|
62
|
+
SimpleI18n,
|
|
63
|
+
SimpleTranslator,
|
|
64
|
+
ctx_var,
|
|
65
|
+
keyboard_remove,
|
|
66
|
+
magic_bundle,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
Message: typing.TypeAlias = MessageCute
|
|
70
|
+
CallbackQuery: typing.TypeAlias = CallbackQueryCute
|
|
71
|
+
InlineQuery: typing.TypeAlias = InlineQueryCute
|
|
72
|
+
Bot: typing.TypeAlias = Telegrinder
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
__all__ = (
|
|
76
|
+
"ABCAPI",
|
|
77
|
+
"ABCClient",
|
|
78
|
+
"ABCDispatch",
|
|
79
|
+
"ABCGlobalContext",
|
|
80
|
+
"ABCHandler",
|
|
81
|
+
"ABCLoopWrapper",
|
|
82
|
+
"ABCMiddleware",
|
|
83
|
+
"ABCPolling",
|
|
84
|
+
"ABCReturnManager",
|
|
85
|
+
"ABCRule",
|
|
86
|
+
"ABCScenario",
|
|
87
|
+
"ABCStateView",
|
|
88
|
+
"ABCTranslator",
|
|
89
|
+
"ABCTranslatorMiddleware",
|
|
90
|
+
"ABCView",
|
|
91
|
+
"API",
|
|
92
|
+
"APIError",
|
|
93
|
+
"APIResponse",
|
|
94
|
+
"AiohttpClient",
|
|
95
|
+
"AnyMarkup",
|
|
96
|
+
"BaseCute",
|
|
97
|
+
"BaseReturnManager",
|
|
98
|
+
"BaseStateView",
|
|
99
|
+
"BaseView",
|
|
100
|
+
"Bot",
|
|
101
|
+
"Button",
|
|
102
|
+
"CallbackQuery",
|
|
103
|
+
"CallbackQueryCute",
|
|
104
|
+
"CallbackQueryReturnManager",
|
|
105
|
+
"CallbackQueryView",
|
|
106
|
+
"Checkbox",
|
|
107
|
+
"CtxVar",
|
|
108
|
+
"DelayedTask",
|
|
109
|
+
"Dispatch",
|
|
110
|
+
"FormatString",
|
|
111
|
+
"FuncHandler",
|
|
112
|
+
"GlobalContext",
|
|
113
|
+
"HTMLFormatter",
|
|
114
|
+
"I18nEnum",
|
|
115
|
+
"InlineButton",
|
|
116
|
+
"InlineKeyboard",
|
|
117
|
+
"InlineQuery",
|
|
118
|
+
"InlineQueryCute",
|
|
119
|
+
"InlineQueryReturnManager",
|
|
120
|
+
"Keyboard",
|
|
121
|
+
"KeyboardSetBase",
|
|
122
|
+
"KeyboardSetYAML",
|
|
123
|
+
"LoopWrapper",
|
|
124
|
+
"Message",
|
|
125
|
+
"MessageCute",
|
|
126
|
+
"MessageReplyHandler",
|
|
127
|
+
"MessageReturnManager",
|
|
128
|
+
"MessageRule",
|
|
129
|
+
"MessageView",
|
|
130
|
+
"Model",
|
|
131
|
+
"ParseMode",
|
|
132
|
+
"Polling",
|
|
133
|
+
"RowButtons",
|
|
134
|
+
"SimpleI18n",
|
|
135
|
+
"SimpleTranslator",
|
|
136
|
+
"SingleChoice",
|
|
137
|
+
"Telegrinder",
|
|
138
|
+
"Token",
|
|
139
|
+
"ViewBox",
|
|
140
|
+
"WaiterMachine",
|
|
141
|
+
"ctx_var",
|
|
142
|
+
"keyboard_remove",
|
|
143
|
+
"logger",
|
|
144
|
+
"magic_bundle",
|
|
145
|
+
"register_manager",
|
|
146
|
+
)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import pathlib
|
|
2
|
+
import typing
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
import msgspec
|
|
6
|
+
from envparse import env
|
|
7
|
+
from fntypes.result import Result
|
|
8
|
+
|
|
9
|
+
from telegrinder.api.error import APIError
|
|
10
|
+
from telegrinder.client import ABCClient
|
|
11
|
+
|
|
12
|
+
from .error import InvalidTokenError
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Token(str):
|
|
16
|
+
def __new__(cls, token: str) -> typing.Self:
|
|
17
|
+
if token.count(":") != 1 or not token.split(":")[0].isdigit():
|
|
18
|
+
raise InvalidTokenError("Invalid token, it should look like this '123:ABC'.")
|
|
19
|
+
return super().__new__(cls, token)
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def from_env(
|
|
23
|
+
cls,
|
|
24
|
+
var_name: str = "BOT_TOKEN",
|
|
25
|
+
*,
|
|
26
|
+
is_read: bool = False,
|
|
27
|
+
path_to_envfile: str | pathlib.Path | None = None,
|
|
28
|
+
) -> typing.Self:
|
|
29
|
+
if not is_read:
|
|
30
|
+
env.read_envfile(path_to_envfile)
|
|
31
|
+
return cls(env.str(var_name))
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def bot_id(self) -> int:
|
|
35
|
+
return int(self.split(":")[0])
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ABCAPI(ABC):
|
|
39
|
+
http: ABCClient
|
|
40
|
+
|
|
41
|
+
@abstractmethod
|
|
42
|
+
async def request(
|
|
43
|
+
self,
|
|
44
|
+
method: str,
|
|
45
|
+
data: dict[str, typing.Any] | None = None,
|
|
46
|
+
) -> Result[list[typing.Any] | dict[str, typing.Any] | bool, APIError]:
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
@abstractmethod
|
|
50
|
+
async def request_raw(
|
|
51
|
+
self,
|
|
52
|
+
method: str,
|
|
53
|
+
data: dict[str, typing.Any] | None = None,
|
|
54
|
+
) -> Result[msgspec.Raw, APIError]:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
@abstractmethod
|
|
59
|
+
def request_url(self) -> str:
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
@abstractmethod
|
|
64
|
+
def id(self) -> int:
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
__all__ = ("ABCAPI", "Token")
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
import msgspec
|
|
4
|
+
from fntypes.result import Error, Ok, Result
|
|
5
|
+
|
|
6
|
+
from telegrinder.api.response import APIResponse
|
|
7
|
+
from telegrinder.client import ABCClient, AiohttpClient
|
|
8
|
+
from telegrinder.model import DataConverter, decoder
|
|
9
|
+
from telegrinder.types.methods import APIMethods
|
|
10
|
+
|
|
11
|
+
from .abc import ABCAPI, APIError, Token
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def compose_data(
|
|
15
|
+
client: ABCClient,
|
|
16
|
+
data: dict[str, typing.Any],
|
|
17
|
+
files: dict[str, tuple[str, bytes]],
|
|
18
|
+
) -> typing.Any:
|
|
19
|
+
converter = DataConverter(files=files)
|
|
20
|
+
return client.get_form(
|
|
21
|
+
data={k: converter.convert(v) for k, v in data.items()},
|
|
22
|
+
files=converter.files,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class API(ABCAPI, APIMethods):
|
|
27
|
+
API_URL: typing.ClassVar[str] = "https://api.telegram.org/"
|
|
28
|
+
|
|
29
|
+
def __init__(self, token: Token, *, http: ABCClient | None = None) -> None:
|
|
30
|
+
self.token = token
|
|
31
|
+
self.http = http or AiohttpClient()
|
|
32
|
+
super().__init__(self)
|
|
33
|
+
|
|
34
|
+
def __repr__(self) -> str:
|
|
35
|
+
return "<{}: id={}, http={!r}>".format(
|
|
36
|
+
self.__class__.__name__,
|
|
37
|
+
self.id,
|
|
38
|
+
self.http,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def id(self) -> int:
|
|
43
|
+
return self.token.bot_id
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def request_url(self) -> str:
|
|
47
|
+
return self.API_URL + f"bot{self.token}/"
|
|
48
|
+
|
|
49
|
+
async def request(
|
|
50
|
+
self,
|
|
51
|
+
method: str,
|
|
52
|
+
data: dict[str, typing.Any] | None = None,
|
|
53
|
+
files: dict[str, tuple[str, bytes]] | None = None,
|
|
54
|
+
) -> Result[dict[str, typing.Any] | list[typing.Any] | bool, APIError]:
|
|
55
|
+
response = await self.http.request_json(
|
|
56
|
+
url=self.request_url + method,
|
|
57
|
+
data=compose_data(self.http, data or {}, files or {})
|
|
58
|
+
)
|
|
59
|
+
if response.get("ok"):
|
|
60
|
+
assert "result" in response
|
|
61
|
+
return Ok(response["result"])
|
|
62
|
+
return Error(APIError(
|
|
63
|
+
code=response.get("error_code", 0),
|
|
64
|
+
error=response.get("description"),
|
|
65
|
+
))
|
|
66
|
+
|
|
67
|
+
async def request_raw(
|
|
68
|
+
self,
|
|
69
|
+
method: str,
|
|
70
|
+
data: dict[str, typing.Any] | None = None,
|
|
71
|
+
files: dict[str, tuple[str, bytes]] | None = None,
|
|
72
|
+
) -> Result[msgspec.Raw, APIError]:
|
|
73
|
+
response_bytes = await self.http.request_bytes(
|
|
74
|
+
url=self.request_url + method,
|
|
75
|
+
data=compose_data(self.http, data or {}, files or {}),
|
|
76
|
+
)
|
|
77
|
+
return decoder.decode(response_bytes, type=APIResponse).to_result()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
__all__ = ("API",)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class APIError(BaseException):
|
|
2
|
+
def __init__(self, code: int, error: str | None = None):
|
|
3
|
+
self.code, self.error = code, error
|
|
4
|
+
|
|
5
|
+
def __str__(self) -> str:
|
|
6
|
+
return f"[{self.code}] {self.error}"
|
|
7
|
+
|
|
8
|
+
def __repr__(self) -> str:
|
|
9
|
+
return f"<APIError {self.__str__()}>"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class InvalidTokenError(BaseException):
|
|
13
|
+
...
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = ("APIError", "InvalidTokenError")
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
from telegrinder.model import Model
|
|
2
|
-
from telegrinder.result import Result
|
|
3
|
-
from telegrinder.api.error import APIError
|
|
4
1
|
import msgspec
|
|
2
|
+
from fntypes.result import Error, Ok, Result
|
|
3
|
+
|
|
4
|
+
from telegrinder.api.error import APIError
|
|
5
|
+
from telegrinder.model import Model
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class APIResponse(Model):
|
|
8
|
-
ok: bool
|
|
9
|
-
result: msgspec.Raw = b""
|
|
9
|
+
ok: bool = False
|
|
10
|
+
result: msgspec.Raw = msgspec.Raw(b"")
|
|
10
11
|
error_code: int = 0
|
|
11
12
|
description: str = ""
|
|
12
13
|
|
|
13
14
|
def to_result(self) -> Result[msgspec.Raw, APIError]:
|
|
14
15
|
if self.ok:
|
|
15
|
-
return
|
|
16
|
-
return
|
|
16
|
+
return Ok(self.result)
|
|
17
|
+
return Error(APIError(self.error_code, self.description))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = ("APIResponse",)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from .bot import Telegrinder
|
|
2
|
+
from .cute_types import (
|
|
3
|
+
BaseCute,
|
|
4
|
+
CallbackQueryCute,
|
|
5
|
+
InlineQueryCute,
|
|
6
|
+
MessageCute,
|
|
7
|
+
UpdateCute,
|
|
8
|
+
)
|
|
9
|
+
from .dispatch import (
|
|
10
|
+
ABCDispatch,
|
|
11
|
+
ABCHandler,
|
|
12
|
+
ABCMiddleware,
|
|
13
|
+
ABCReturnManager,
|
|
14
|
+
ABCStateView,
|
|
15
|
+
ABCView,
|
|
16
|
+
BaseReturnManager,
|
|
17
|
+
BaseStateView,
|
|
18
|
+
BaseView,
|
|
19
|
+
CallbackQueryReturnManager,
|
|
20
|
+
CallbackQueryView,
|
|
21
|
+
CompositionDispatch,
|
|
22
|
+
Context,
|
|
23
|
+
Dispatch,
|
|
24
|
+
FuncHandler,
|
|
25
|
+
InlineQueryReturnManager,
|
|
26
|
+
Manager,
|
|
27
|
+
MessageReplyHandler,
|
|
28
|
+
MessageReturnManager,
|
|
29
|
+
MessageView,
|
|
30
|
+
ViewBox,
|
|
31
|
+
WaiterMachine,
|
|
32
|
+
register_manager,
|
|
33
|
+
)
|
|
34
|
+
from .polling import ABCPolling, Polling
|
|
35
|
+
from .rules import ABCRule, CallbackQueryRule, MessageRule
|
|
36
|
+
from .scenario import ABCScenario, Checkbox, SingleChoice
|
|
37
|
+
|
|
38
|
+
__all__ = (
|
|
39
|
+
"ABCDispatch",
|
|
40
|
+
"ABCHandler",
|
|
41
|
+
"ABCMiddleware",
|
|
42
|
+
"ABCPolling",
|
|
43
|
+
"ABCReturnManager",
|
|
44
|
+
"ABCRule",
|
|
45
|
+
"ABCScenario",
|
|
46
|
+
"ABCStateView",
|
|
47
|
+
"ABCView",
|
|
48
|
+
"BaseCute",
|
|
49
|
+
"BaseReturnManager",
|
|
50
|
+
"BaseStateView",
|
|
51
|
+
"BaseView",
|
|
52
|
+
"CallbackQueryCute",
|
|
53
|
+
"CallbackQueryReturnManager",
|
|
54
|
+
"CallbackQueryRule",
|
|
55
|
+
"CallbackQueryView",
|
|
56
|
+
"Checkbox",
|
|
57
|
+
"CompositionDispatch",
|
|
58
|
+
"Context",
|
|
59
|
+
"Dispatch",
|
|
60
|
+
"FuncHandler",
|
|
61
|
+
"InlineQueryCute",
|
|
62
|
+
"InlineQueryReturnManager",
|
|
63
|
+
"Manager",
|
|
64
|
+
"MessageCute",
|
|
65
|
+
"MessageReplyHandler",
|
|
66
|
+
"MessageReturnManager",
|
|
67
|
+
"MessageRule",
|
|
68
|
+
"MessageView",
|
|
69
|
+
"Polling",
|
|
70
|
+
"SingleChoice",
|
|
71
|
+
"Telegrinder",
|
|
72
|
+
"UpdateCute",
|
|
73
|
+
"ViewBox",
|
|
74
|
+
"WaiterMachine",
|
|
75
|
+
"register_manager",
|
|
76
|
+
)
|