telegrinder 0.1.dev169__tar.gz → 0.1.dev171__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.dev169 → telegrinder-0.1.dev171}/PKG-INFO +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/pyproject.toml +13 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/api/abc.py +7 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/api/api.py +12 -3
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/api/error.py +2 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/bot.py +6 -1
- telegrinder-0.1.dev171/telegrinder/bot/cute_types/base.py +260 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/cute_types/callback_query.py +6 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/cute_types/chat_member_updated.py +1 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/cute_types/message.py +23 -11
- telegrinder-0.1.dev171/telegrinder/bot/cute_types/update.py +75 -0
- telegrinder-0.1.dev171/telegrinder/bot/cute_types/utils.py +95 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/__init__.py +2 -3
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/abc.py +6 -3
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/context.py +6 -6
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/dispatch.py +61 -23
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/handler/abc.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/handler/func.py +36 -17
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/handler/message_reply.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/middleware/abc.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/process.py +10 -10
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/return_manager/abc.py +3 -3
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/view/abc.py +12 -15
- telegrinder-0.1.dev171/telegrinder/bot/dispatch/view/box.py +129 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/view/message.py +11 -3
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/view/raw.py +3 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/waiter_machine/machine.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/waiter_machine/middleware.py +1 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/waiter_machine/short_state.py +2 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/polling/polling.py +3 -3
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/abc.py +11 -7
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/adapter/event.py +7 -4
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/adapter/node.py +1 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/command.py +5 -7
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/func.py +1 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/fuzzy.py +1 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/integer.py +1 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/markup.py +3 -3
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/message_entities.py +1 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/node.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/regex.py +1 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/rule_enum.py +1 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/scenario/checkbox.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/model.py +87 -47
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/modules.py +3 -3
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/msgspec_utils.py +94 -13
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/__init__.py +20 -11
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/attachment.py +19 -16
- telegrinder-0.1.dev171/telegrinder/node/base.py +203 -0
- telegrinder-0.1.dev171/telegrinder/node/callback_query.py +14 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/command.py +6 -2
- telegrinder-0.1.dev171/telegrinder/node/composer.py +188 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/container.py +4 -4
- telegrinder-0.1.dev171/telegrinder/node/event.py +59 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/me.py +3 -0
- telegrinder-0.1.dev171/telegrinder/node/message.py +14 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/polymorphic.py +11 -12
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/rule.py +27 -5
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/source.py +10 -11
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/text.py +4 -4
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/update.py +1 -2
- telegrinder-0.1.dev171/telegrinder/py.typed +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/__init__.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/buttons.py +5 -10
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/error_handler/error.py +2 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/error_handler/error_handler.py +1 -1
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/formatting/spec_html_formats.py +10 -10
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/global_context/__init__.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/global_context/global_context.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/global_context/telegrinder_ctx.py +4 -4
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/keyboard.py +2 -2
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/loop_wrapper/loop_wrapper.py +39 -5
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/magic.py +48 -15
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/types/enums.py +1 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/types/methods.py +14 -5
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/types/objects.py +3 -0
- telegrinder-0.1.dev169/telegrinder/bot/cute_types/base.py +0 -133
- telegrinder-0.1.dev169/telegrinder/bot/cute_types/update.py +0 -27
- telegrinder-0.1.dev169/telegrinder/bot/cute_types/utils.py +0 -558
- telegrinder-0.1.dev169/telegrinder/bot/dispatch/view/box.py +0 -118
- telegrinder-0.1.dev169/telegrinder/node/base.py +0 -107
- telegrinder-0.1.dev169/telegrinder/node/callback_query.py +0 -18
- telegrinder-0.1.dev169/telegrinder/node/composer.py +0 -160
- telegrinder-0.1.dev169/telegrinder/node/message.py +0 -18
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/LICENSE +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/readme.md +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/api/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/api/response.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/cute_types/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/cute_types/chat_join_request.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/cute_types/inline_query.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/handler/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/middleware/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/return_manager/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/return_manager/callback_query.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/return_manager/inline_query.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/return_manager/message.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/view/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/view/callback_query.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/view/chat_join_request.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/view/chat_member.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/view/inline_query.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/dispatch/waiter_machine/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/polling/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/polling/abc.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/adapter/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/adapter/abc.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/adapter/errors.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/adapter/raw_update.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/callback_data.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/chat_join.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/enum_text.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/inline.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/is_from.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/mention.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/message.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/start.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/text.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/rules/update.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/scenario/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/scenario/abc.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/scenario/choice.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/client/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/client/abc.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/client/aiohttp.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/msgspec_json.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/scope.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/tools/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/node/tools/generator.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/rules.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/error_handler/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/error_handler/abc.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/formatting/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/formatting/html.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/formatting/links.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/global_context/abc.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/i18n/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/i18n/base.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/i18n/middleware/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/i18n/middleware/base.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/i18n/simple.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/kb_set/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/kb_set/base.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/kb_set/yaml.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/limited_dict.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/loop_wrapper/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/loop_wrapper/abc.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/tools/parse_mode.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/types/__init__.py +0 -0
- {telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/verification_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: telegrinder
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.dev171
|
|
4
4
|
Summary: Modern visionary telegram bot framework.
|
|
5
5
|
Home-page: https://github.com/timoniq/telegrinder
|
|
6
6
|
License: MIT
|
|
@@ -25,7 +25,7 @@ Requires-Dist: certifi (>=2024.2.2,<2025.0.0)
|
|
|
25
25
|
Requires-Dist: choicelib (>=0.1.5,<0.2.0)
|
|
26
26
|
Requires-Dist: colorama (>=0.4.0,<0.5.0)
|
|
27
27
|
Requires-Dist: envparse (>=0.2.0,<0.3.0)
|
|
28
|
-
Requires-Dist: fntypes (>=0.1.
|
|
28
|
+
Requires-Dist: fntypes (>=0.1.3,<0.2.0)
|
|
29
29
|
Requires-Dist: msgspec (>=0.18.6,<0.19.0)
|
|
30
30
|
Requires-Dist: requests (>=2.28.1,<3.0.0)
|
|
31
31
|
Requires-Dist: typing-extensions (>=4.10.0,<5.0.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "telegrinder"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.dev171"
|
|
4
4
|
description = "Modern visionary telegram bot framework."
|
|
5
5
|
authors = ["timoniq <tesseradecades@mail.ru>"]
|
|
6
6
|
maintainers = ["luwqz1 <howluwqz1@gmail.com>"]
|
|
@@ -29,6 +29,7 @@ classifiers = [
|
|
|
29
29
|
"Intended Audience :: Developers",
|
|
30
30
|
"License :: OSI Approved :: MIT License",
|
|
31
31
|
"Programming Language :: Python :: 3.11",
|
|
32
|
+
"Programming Language :: Python :: 3.12",
|
|
32
33
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
33
34
|
"Topic :: Software Development :: Quality Assurance",
|
|
34
35
|
"Typing :: Typed",
|
|
@@ -49,9 +50,10 @@ certifi = "^2024.2.2"
|
|
|
49
50
|
msgspec = "^0.18.6"
|
|
50
51
|
requests = "^2.28.1"
|
|
51
52
|
typing-extensions = "^4.10.0"
|
|
52
|
-
fntypes = "^0.1.
|
|
53
|
+
fntypes = "^0.1.3"
|
|
53
54
|
|
|
54
55
|
[tool.poetry.group.dev.dependencies]
|
|
56
|
+
pre-commit = "^3.8.0"
|
|
55
57
|
ruff = "^0.5.0"
|
|
56
58
|
basedpyright = "^1.12.1"
|
|
57
59
|
sort-all = "1.2.0"
|
|
@@ -84,4 +86,13 @@ asyncio_mode = "auto"
|
|
|
84
86
|
docstring-quotes = "double"
|
|
85
87
|
|
|
86
88
|
[tool.pyright]
|
|
89
|
+
exclude = [
|
|
90
|
+
"**/__pycache__",
|
|
91
|
+
"docs",
|
|
92
|
+
"local",
|
|
93
|
+
]
|
|
87
94
|
typeCheckingMode = "basic"
|
|
95
|
+
pythonPlatform = "All"
|
|
96
|
+
pythonVersion = "3.11"
|
|
97
|
+
reportMissingImports = true
|
|
98
|
+
reportMissingTypeStubs = false
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import pathlib
|
|
2
2
|
import typing
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
+
from functools import cached_property
|
|
4
5
|
|
|
5
6
|
import msgspec
|
|
6
7
|
from envparse import env
|
|
@@ -33,7 +34,7 @@ class Token(str):
|
|
|
33
34
|
env.read_envfile(path_to_envfile)
|
|
34
35
|
return cls(env.str(var_name))
|
|
35
36
|
|
|
36
|
-
@
|
|
37
|
+
@cached_property
|
|
37
38
|
def bot_id(self) -> int:
|
|
38
39
|
return int(self.split(":")[0])
|
|
39
40
|
|
|
@@ -64,6 +65,11 @@ class ABCAPI(ABC):
|
|
|
64
65
|
def request_url(self) -> str:
|
|
65
66
|
pass
|
|
66
67
|
|
|
68
|
+
@property
|
|
69
|
+
@abstractmethod
|
|
70
|
+
def request_file_url(self) -> str:
|
|
71
|
+
pass
|
|
72
|
+
|
|
67
73
|
@property
|
|
68
74
|
@abstractmethod
|
|
69
75
|
def id(self) -> int:
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import typing
|
|
2
|
+
from functools import cached_property
|
|
2
3
|
|
|
3
4
|
import msgspec
|
|
4
5
|
from fntypes.result import Error, Ok, Result
|
|
@@ -16,7 +17,7 @@ def compose_data(
|
|
|
16
17
|
data: dict[str, typing.Any],
|
|
17
18
|
files: dict[str, tuple[str, bytes]],
|
|
18
19
|
) -> typing.Any:
|
|
19
|
-
converter = DataConverter(
|
|
20
|
+
converter = DataConverter(_files=files.copy())
|
|
20
21
|
return client.get_form(
|
|
21
22
|
data={k: converter(v) for k, v in data.items()},
|
|
22
23
|
files=converter.files,
|
|
@@ -24,9 +25,10 @@ def compose_data(
|
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class API(ABCAPI, APIMethods):
|
|
27
|
-
"""Bot API with available API methods."""
|
|
28
|
+
"""Bot API with available API methods and http client."""
|
|
28
29
|
|
|
29
30
|
API_URL = "https://api.telegram.org/"
|
|
31
|
+
API_FILE_URL = "https://api.telegram.org/file/"
|
|
30
32
|
|
|
31
33
|
def __init__(self, token: Token, *, http: ABCClient | None = None) -> None:
|
|
32
34
|
self.token = token
|
|
@@ -40,7 +42,7 @@ class API(ABCAPI, APIMethods):
|
|
|
40
42
|
self.http,
|
|
41
43
|
)
|
|
42
44
|
|
|
43
|
-
@
|
|
45
|
+
@cached_property
|
|
44
46
|
def id(self) -> int:
|
|
45
47
|
return self.token.bot_id
|
|
46
48
|
|
|
@@ -48,6 +50,13 @@ class API(ABCAPI, APIMethods):
|
|
|
48
50
|
def request_url(self) -> str:
|
|
49
51
|
return self.API_URL + f"bot{self.token}/"
|
|
50
52
|
|
|
53
|
+
@property
|
|
54
|
+
def request_file_url(self) -> str:
|
|
55
|
+
return self.API_FILE_URL + f"bot{self.token}/"
|
|
56
|
+
|
|
57
|
+
async def download_file(self, file_path: str) -> bytes:
|
|
58
|
+
return await self.http.request_content(f"{self.request_file_url}/{file_path}")
|
|
59
|
+
|
|
51
60
|
async def request(
|
|
52
61
|
self,
|
|
53
62
|
method: str,
|
|
@@ -43,7 +43,12 @@ class Telegrinder(typing.Generic[DispatchT, PollingT, LoopWrapperT]):
|
|
|
43
43
|
return
|
|
44
44
|
await self.api.delete_webhook()
|
|
45
45
|
|
|
46
|
-
async def run_polling(
|
|
46
|
+
async def run_polling(
|
|
47
|
+
self,
|
|
48
|
+
*,
|
|
49
|
+
offset: int = 0,
|
|
50
|
+
skip_updates: bool = False,
|
|
51
|
+
) -> None:
|
|
47
52
|
if skip_updates:
|
|
48
53
|
logger.debug("Dropping pending updates")
|
|
49
54
|
await self.reset_webhook()
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import inspect
|
|
3
|
+
import typing
|
|
4
|
+
from functools import wraps
|
|
5
|
+
|
|
6
|
+
import typing_extensions
|
|
7
|
+
from fntypes.result import Result
|
|
8
|
+
|
|
9
|
+
from telegrinder.api import ABCAPI, API
|
|
10
|
+
from telegrinder.model import Model, get_params
|
|
11
|
+
|
|
12
|
+
F = typing.TypeVar("F", bound=typing.Callable[..., typing.Any])
|
|
13
|
+
Cute = typing.TypeVar("Cute", bound="BaseCute")
|
|
14
|
+
Update = typing_extensions.TypeVar("Update", bound=Model)
|
|
15
|
+
CtxAPI = typing_extensions.TypeVar("CtxAPI", bound=ABCAPI, default=API)
|
|
16
|
+
|
|
17
|
+
Executor: typing.TypeAlias = typing.Callable[
|
|
18
|
+
[Cute, str, dict[str, typing.Any]],
|
|
19
|
+
typing.Awaitable[Result[typing.Any, typing.Any]],
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
if typing.TYPE_CHECKING:
|
|
23
|
+
|
|
24
|
+
class BaseCute(Model, typing.Generic[Update, CtxAPI]):
|
|
25
|
+
api: ABCAPI
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def from_update(cls, update: Update, bound_api: ABCAPI) -> typing.Self: ...
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def ctx_api(self) -> CtxAPI: ...
|
|
32
|
+
|
|
33
|
+
def to_dict(
|
|
34
|
+
self,
|
|
35
|
+
*,
|
|
36
|
+
exclude_fields: set[str] | None = None,
|
|
37
|
+
) -> dict[str, typing.Any]:
|
|
38
|
+
"""
|
|
39
|
+
:param exclude_fields: Cute model field names to exclude from the dictionary representation of this cute model.
|
|
40
|
+
:return: A dictionary representation of this cute model.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
def to_full_dict(
|
|
46
|
+
self,
|
|
47
|
+
*,
|
|
48
|
+
exclude_fields: set[str] | None = None,
|
|
49
|
+
) -> dict[str, typing.Any]:
|
|
50
|
+
"""
|
|
51
|
+
:param exclude_fields: Cute model field names to exclude from the dictionary representation of this cute model.
|
|
52
|
+
:return: A dictionary representation of this model including all models, structs, custom types.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
...
|
|
56
|
+
|
|
57
|
+
else:
|
|
58
|
+
from fntypes.co import Nothing, Some, Variative
|
|
59
|
+
from msgspec._utils import get_class_annotations as _get_class_annotations
|
|
60
|
+
|
|
61
|
+
from telegrinder.msgspec_utils import Option, decoder
|
|
62
|
+
|
|
63
|
+
_DEFAULT_API_CLASS = API
|
|
64
|
+
|
|
65
|
+
def _get_ctx_api_class(cute_class):
|
|
66
|
+
if hasattr(cute_class, "__ctx_api_class__"):
|
|
67
|
+
return cute_class.__ctx_api_class__
|
|
68
|
+
|
|
69
|
+
ctx_api_class = _DEFAULT_API_CLASS
|
|
70
|
+
for base in cute_class.__dict__.get("__orig_bases__", ()):
|
|
71
|
+
if ctx_api_class is not _DEFAULT_API_CLASS:
|
|
72
|
+
break
|
|
73
|
+
if issubclass(typing.get_origin(base) or base, BaseCute):
|
|
74
|
+
for generic_type in typing.get_args(base):
|
|
75
|
+
if issubclass(typing.get_origin(generic_type) or generic_type, ABCAPI):
|
|
76
|
+
ctx_api_class = generic_type
|
|
77
|
+
break
|
|
78
|
+
|
|
79
|
+
cute_class.__ctx_api_class__ = ctx_api_class
|
|
80
|
+
return ctx_api_class
|
|
81
|
+
|
|
82
|
+
def _get_cute_from_args(args):
|
|
83
|
+
for hint in args:
|
|
84
|
+
if not isinstance(hint, type):
|
|
85
|
+
hint = typing.get_origin(hint) or hint
|
|
86
|
+
if not isinstance(hint, type):
|
|
87
|
+
continue
|
|
88
|
+
|
|
89
|
+
if hint is Variative or issubclass(hint, Option) or issubclass(hint, Some | Nothing):
|
|
90
|
+
return _get_cute_from_args(typing.get_args(hint))
|
|
91
|
+
|
|
92
|
+
if issubclass(hint, BaseCute):
|
|
93
|
+
return hint
|
|
94
|
+
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
def _get_cute_annotations(annotations):
|
|
98
|
+
cute_annotations = {}
|
|
99
|
+
|
|
100
|
+
for key, hint in annotations.items():
|
|
101
|
+
if not isinstance(hint, type):
|
|
102
|
+
if (val := _get_cute_from_args(typing.get_args(hint))) is not None:
|
|
103
|
+
cute_annotations[key] = val
|
|
104
|
+
|
|
105
|
+
elif issubclass(hint, BaseCute):
|
|
106
|
+
cute_annotations[key] = hint
|
|
107
|
+
|
|
108
|
+
return cute_annotations
|
|
109
|
+
|
|
110
|
+
def _get_value(value):
|
|
111
|
+
while isinstance(value, Variative | Some):
|
|
112
|
+
if isinstance(value, Variative):
|
|
113
|
+
value = value.v
|
|
114
|
+
if isinstance(value, Some):
|
|
115
|
+
value = value.value
|
|
116
|
+
return value
|
|
117
|
+
|
|
118
|
+
class BaseCute(typing.Generic[Update, CtxAPI]):
|
|
119
|
+
def __init_subclass__(cls, *args, **kwargs):
|
|
120
|
+
super().__init_subclass__(*args, **kwargs)
|
|
121
|
+
|
|
122
|
+
if not cls.__bases__ or not issubclass(cls.__bases__[0], BaseCute):
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
cls.__is_solved_annotations__ = False
|
|
126
|
+
cls.__cute_annotations__ = None
|
|
127
|
+
|
|
128
|
+
@classmethod
|
|
129
|
+
def from_update(cls, update, bound_api):
|
|
130
|
+
if not cls.__is_solved_annotations__:
|
|
131
|
+
cls.__is_solved_annotations__ = True
|
|
132
|
+
cls.__annotations__ = _get_class_annotations(cls)
|
|
133
|
+
|
|
134
|
+
if cls.__cute_annotations__ is None:
|
|
135
|
+
cls.__cute_annotations__ = _get_cute_annotations(cls.__annotations__)
|
|
136
|
+
|
|
137
|
+
return cls(
|
|
138
|
+
**{
|
|
139
|
+
field: decoder.convert(
|
|
140
|
+
cls.__cute_annotations__[field].from_update(_get_value(value), bound_api=bound_api),
|
|
141
|
+
type=cls.__annotations__[field],
|
|
142
|
+
)
|
|
143
|
+
if field in cls.__cute_annotations__ and value
|
|
144
|
+
else value
|
|
145
|
+
for field, value in update.to_dict().items()
|
|
146
|
+
},
|
|
147
|
+
api=bound_api,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def ctx_api(self):
|
|
152
|
+
ctx_api_class = _get_ctx_api_class(self.__class__)
|
|
153
|
+
assert isinstance(
|
|
154
|
+
self.api,
|
|
155
|
+
ctx_api_class,
|
|
156
|
+
), f"Bound API of type {self.api.__class__.__name__!r} is incompatible with {ctx_api_class.__name__!r}."
|
|
157
|
+
return self.api
|
|
158
|
+
|
|
159
|
+
def to_dict(self, *, exclude_fields=None):
|
|
160
|
+
exclude_fields = exclude_fields or set()
|
|
161
|
+
return super().to_dict(exclude_fields={"api"} | exclude_fields)
|
|
162
|
+
|
|
163
|
+
def to_full_dict(self, *, exclude_fields=None):
|
|
164
|
+
exclude_fields = exclude_fields or set()
|
|
165
|
+
return super().to_full_dict(exclude_fields={"api"} | exclude_fields)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def compose_method_params(
|
|
169
|
+
params: dict[str, typing.Any],
|
|
170
|
+
update: Cute,
|
|
171
|
+
*,
|
|
172
|
+
default_params: set[str | tuple[str, str]] | None = None,
|
|
173
|
+
validators: dict[str, typing.Callable[[Cute], bool]] | None = None,
|
|
174
|
+
) -> dict[str, typing.Any]:
|
|
175
|
+
"""Compose method `params` from `update` by `default_params` and `validators`.
|
|
176
|
+
|
|
177
|
+
:param params: Method params.
|
|
178
|
+
:param update: Update object.
|
|
179
|
+
:param default_params: Default params. \
|
|
180
|
+
(`str`) - Attribute name to be get from `update` if param is undefined. \
|
|
181
|
+
(`tuple[str, str]`): tuple[0] - Parameter name to be set in `params`, \
|
|
182
|
+
tuple[1] - attribute name to be get from `update`.
|
|
183
|
+
:param validators: Validators mapping (`str, Callable`), key - `Parameter name` \
|
|
184
|
+
for which the validator will be applied, value - `Validator`, if returned `True` \
|
|
185
|
+
parameter will be set, otherwise will not.
|
|
186
|
+
:return: Composed params.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
default_params = default_params or set()
|
|
190
|
+
validators = validators or {}
|
|
191
|
+
|
|
192
|
+
for param in default_params:
|
|
193
|
+
param_name = param if isinstance(param, str) else param[0]
|
|
194
|
+
if param_name not in params:
|
|
195
|
+
if param_name in validators and not validators[param_name](update):
|
|
196
|
+
continue
|
|
197
|
+
params[param_name] = getattr(update, param if isinstance(param, str) else param[1])
|
|
198
|
+
|
|
199
|
+
return params
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def shortcut(
|
|
203
|
+
method_name: str,
|
|
204
|
+
*,
|
|
205
|
+
executor: Executor[Cute] | None = None,
|
|
206
|
+
custom_params: set[str] | None = None,
|
|
207
|
+
):
|
|
208
|
+
def wrapper(func: F) -> F:
|
|
209
|
+
@wraps(func)
|
|
210
|
+
async def inner(
|
|
211
|
+
self: Cute,
|
|
212
|
+
*args: typing.Any,
|
|
213
|
+
**kwargs: typing.Any,
|
|
214
|
+
) -> typing.Any:
|
|
215
|
+
if executor is None:
|
|
216
|
+
return await func(self, *args, **kwargs)
|
|
217
|
+
|
|
218
|
+
if not hasattr(func, "_signature_params"):
|
|
219
|
+
setattr(
|
|
220
|
+
func,
|
|
221
|
+
"_signature_params",
|
|
222
|
+
{k: p for k, p in inspect.signature(func).parameters.items() if k != "self"},
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
signature_params: dict[str, inspect.Parameter] = getattr(func, "_signature_params")
|
|
226
|
+
params: dict[str, typing.Any] = {}
|
|
227
|
+
index = 0
|
|
228
|
+
|
|
229
|
+
for k, p in signature_params.items():
|
|
230
|
+
if p.kind in (p.POSITIONAL_OR_KEYWORD, p.POSITIONAL_ONLY) and len(args) > index:
|
|
231
|
+
params[k] = args[index]
|
|
232
|
+
index += 1
|
|
233
|
+
continue
|
|
234
|
+
|
|
235
|
+
if p.kind in (p.VAR_KEYWORD, p.VAR_POSITIONAL):
|
|
236
|
+
params[k] = kwargs.copy() if p.kind is p.VAR_KEYWORD else args[index:]
|
|
237
|
+
continue
|
|
238
|
+
|
|
239
|
+
params[k] = kwargs.pop(k, p.default) if p.default is not p.empty else kwargs.pop(k)
|
|
240
|
+
|
|
241
|
+
return await executor(self, method_name, get_params(params))
|
|
242
|
+
|
|
243
|
+
inner.__shortcut__ = Shortcut( # type: ignore
|
|
244
|
+
method_name=method_name,
|
|
245
|
+
executor=executor,
|
|
246
|
+
custom_params=custom_params or set(),
|
|
247
|
+
)
|
|
248
|
+
return inner # type: ignore
|
|
249
|
+
|
|
250
|
+
return wrapper
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
@dataclasses.dataclass(slots=True, frozen=True)
|
|
254
|
+
class Shortcut:
|
|
255
|
+
method_name: str
|
|
256
|
+
executor: Executor | None = dataclasses.field(default=None, kw_only=True)
|
|
257
|
+
custom_params: set[str] = dataclasses.field(default_factory=lambda: set(), kw_only=True)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
__all__ = ("BaseCute", "Shortcut", "compose_method_params", "shortcut")
|
{telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/cute_types/callback_query.py
RENAMED
|
@@ -7,9 +7,10 @@ from fntypes.co import Nothing, Result, Some, Variative, unwrapping
|
|
|
7
7
|
from telegrinder.api import ABCAPI, APIError
|
|
8
8
|
from telegrinder.model import get_params
|
|
9
9
|
from telegrinder.msgspec_utils import Option, decoder
|
|
10
|
-
from telegrinder.types import (
|
|
10
|
+
from telegrinder.types.objects import (
|
|
11
11
|
CallbackQuery,
|
|
12
12
|
Chat,
|
|
13
|
+
InaccessibleMessage,
|
|
13
14
|
InlineKeyboardMarkup,
|
|
14
15
|
InputFile,
|
|
15
16
|
InputMedia,
|
|
@@ -27,6 +28,10 @@ from .message import MediaType, MessageCute, ReplyMarkup, execute_method_edit
|
|
|
27
28
|
class CallbackQueryCute(BaseCute[CallbackQuery], CallbackQuery, kw_only=True, dict=True):
|
|
28
29
|
api: ABCAPI
|
|
29
30
|
|
|
31
|
+
message: Option[Variative[MessageCute, InaccessibleMessage]] = Nothing()
|
|
32
|
+
"""Optional. Message sent by the bot with the callback button that originated
|
|
33
|
+
the query."""
|
|
34
|
+
|
|
30
35
|
@property
|
|
31
36
|
def from_user(self) -> User:
|
|
32
37
|
return self.from_
|
{telegrinder-0.1.dev169 → telegrinder-0.1.dev171}/telegrinder/bot/cute_types/chat_member_updated.py
RENAMED
|
@@ -8,7 +8,6 @@ from telegrinder.model import get_params
|
|
|
8
8
|
from telegrinder.types.objects import ChatMemberUpdated, ChatPermissions, User
|
|
9
9
|
|
|
10
10
|
from .base import BaseCute, compose_method_params, shortcut
|
|
11
|
-
from .utils import compose_chat_permissions
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
async def chat_member_interaction(
|
|
@@ -17,7 +16,7 @@ async def chat_member_interaction(
|
|
|
17
16
|
params: dict[str, typing.Any],
|
|
18
17
|
) -> Result[typing.Any, APIError]:
|
|
19
18
|
if isinstance(params.get("permissions"), dict):
|
|
20
|
-
params["permissions"] =
|
|
19
|
+
params["permissions"] = ChatPermissions(**params["permissions"])
|
|
21
20
|
params = compose_method_params(
|
|
22
21
|
get_params(locals()),
|
|
23
22
|
update,
|
|
@@ -2,15 +2,17 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import typing
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import fntypes.option
|
|
6
|
+
from fntypes.co import Result, Some, Variative
|
|
6
7
|
|
|
7
8
|
from telegrinder.api import ABCAPI, APIError
|
|
8
9
|
from telegrinder.model import get_params
|
|
9
|
-
from telegrinder.msgspec_utils import Nothing
|
|
10
|
-
from telegrinder.types import (
|
|
10
|
+
from telegrinder.msgspec_utils import Nothing, Option
|
|
11
|
+
from telegrinder.types.objects import (
|
|
11
12
|
ChatAction,
|
|
12
13
|
DiceEmoji,
|
|
13
14
|
ForceReply,
|
|
15
|
+
InaccessibleMessage,
|
|
14
16
|
InlineKeyboardMarkup,
|
|
15
17
|
InputFile,
|
|
16
18
|
InputMedia,
|
|
@@ -127,7 +129,7 @@ async def execute_method_edit(
|
|
|
127
129
|
|
|
128
130
|
result = await getattr(update.ctx_api, method_name)(**params)
|
|
129
131
|
return result.map(
|
|
130
|
-
lambda v: Variative[
|
|
132
|
+
lambda v: Variative[MessageCute, bool](
|
|
131
133
|
v.only()
|
|
132
134
|
.map(
|
|
133
135
|
lambda x: MessageCute.from_update(x, bound_api=update.api),
|
|
@@ -139,9 +141,9 @@ async def execute_method_edit(
|
|
|
139
141
|
|
|
140
142
|
def get_entity_value(
|
|
141
143
|
entity_value: typing.Literal["user", "url", "custom_emoji_id", "language"],
|
|
142
|
-
entities: Option[list[MessageEntity]] = Nothing,
|
|
143
|
-
caption_entities: Option[list[MessageEntity]] = Nothing,
|
|
144
|
-
) -> Option[typing.Any]:
|
|
144
|
+
entities: fntypes.option.Option[list[MessageEntity]] = Nothing,
|
|
145
|
+
caption_entities: fntypes.option.Option[list[MessageEntity]] = Nothing,
|
|
146
|
+
) -> fntypes.option.Option[typing.Any]:
|
|
145
147
|
ents = entities.unwrap_or(caption_entities.unwrap_or_none())
|
|
146
148
|
if not ents:
|
|
147
149
|
return Nothing
|
|
@@ -154,26 +156,36 @@ def get_entity_value(
|
|
|
154
156
|
class MessageCute(BaseCute[Message], Message, kw_only=True):
|
|
155
157
|
api: ABCAPI
|
|
156
158
|
|
|
159
|
+
reply_to_message: Option[MessageCute] = Nothing
|
|
160
|
+
"""Optional. For replies in the same chat and message thread, the original
|
|
161
|
+
message. Note that the Message object in this field will not contain further
|
|
162
|
+
reply_to_message fields even if it itself is a reply."""
|
|
163
|
+
|
|
164
|
+
pinned_message: Option[Variative[MessageCute, InaccessibleMessage]] = Nothing
|
|
165
|
+
"""Optional. Specified message was pinned. Note that the Message object in
|
|
166
|
+
this field will not contain further reply_to_message fields even if it
|
|
167
|
+
itself is a reply."""
|
|
168
|
+
|
|
157
169
|
@property
|
|
158
|
-
def mentioned_user(self) -> Option[User]:
|
|
170
|
+
def mentioned_user(self) -> fntypes.option.Option[User]:
|
|
159
171
|
"""Mentioned user without username."""
|
|
160
172
|
|
|
161
173
|
return get_entity_value("user", self.entities, self.caption_entities)
|
|
162
174
|
|
|
163
175
|
@property
|
|
164
|
-
def url(self) -> Option[str]:
|
|
176
|
+
def url(self) -> fntypes.option.Option[str]:
|
|
165
177
|
"""Clickable text URL."""
|
|
166
178
|
|
|
167
179
|
return get_entity_value("url", self.entities, self.caption_entities)
|
|
168
180
|
|
|
169
181
|
@property
|
|
170
|
-
def programming_language(self) -> Option[str]:
|
|
182
|
+
def programming_language(self) -> fntypes.option.Option[str]:
|
|
171
183
|
"""The programming language of the entity text."""
|
|
172
184
|
|
|
173
185
|
return get_entity_value("language", self.entities, self.caption_entities)
|
|
174
186
|
|
|
175
187
|
@property
|
|
176
|
-
def custom_emoji_id(self) -> Option[str]:
|
|
188
|
+
def custom_emoji_id(self) -> fntypes.option.Option[str]:
|
|
177
189
|
"""Unique identifier of the custom emoji."""
|
|
178
190
|
|
|
179
191
|
return get_entity_value("custom_emoji_id", self.entities, self.caption_entities)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from fntypes.co import Nothing, Some
|
|
4
|
+
|
|
5
|
+
from telegrinder.api import ABCAPI
|
|
6
|
+
from telegrinder.msgspec_utils import Option
|
|
7
|
+
from telegrinder.types import Model, Update
|
|
8
|
+
|
|
9
|
+
from .base import BaseCute
|
|
10
|
+
from .callback_query import CallbackQueryCute
|
|
11
|
+
from .chat_join_request import ChatJoinRequestCute
|
|
12
|
+
from .chat_member_updated import ChatMemberUpdatedCute
|
|
13
|
+
from .inline_query import InlineQueryCute
|
|
14
|
+
from .message import MessageCute
|
|
15
|
+
|
|
16
|
+
ModelT = typing.TypeVar("ModelT", bound=Model)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class UpdateCute(BaseCute[Update], Update, kw_only=True):
|
|
20
|
+
api: ABCAPI
|
|
21
|
+
|
|
22
|
+
message: Option[MessageCute] = Nothing()
|
|
23
|
+
"""Optional. New incoming message of any kind - text, photo, sticker, etc."""
|
|
24
|
+
|
|
25
|
+
edited_message: Option[MessageCute] = Nothing()
|
|
26
|
+
"""Optional. New version of a message that is known to the bot and was edited.
|
|
27
|
+
This update may at times be triggered by changes to message fields that are
|
|
28
|
+
either unavailable or not actively used by your bot."""
|
|
29
|
+
|
|
30
|
+
channel_post: Option[MessageCute] = Nothing()
|
|
31
|
+
"""Optional. New incoming channel post of any kind - text, photo, sticker,
|
|
32
|
+
etc."""
|
|
33
|
+
|
|
34
|
+
edited_channel_post: Option[MessageCute] = Nothing()
|
|
35
|
+
"""Optional. New version of a channel post that is known to the bot and was edited.
|
|
36
|
+
This update may at times be triggered by changes to message fields that are
|
|
37
|
+
either unavailable or not actively used by your bot."""
|
|
38
|
+
|
|
39
|
+
business_message: Option[MessageCute] = Nothing()
|
|
40
|
+
"""Optional. New message from a connected business account."""
|
|
41
|
+
|
|
42
|
+
edited_business_message: Option[MessageCute] = Nothing()
|
|
43
|
+
"""Optional. New version of a message from a connected business account."""
|
|
44
|
+
|
|
45
|
+
inline_query: Option[InlineQueryCute] = Nothing()
|
|
46
|
+
"""Optional. New incoming inline query."""
|
|
47
|
+
|
|
48
|
+
callback_query: Option[CallbackQueryCute] = Nothing()
|
|
49
|
+
"""Optional. New incoming callback query."""
|
|
50
|
+
|
|
51
|
+
my_chat_member: Option[ChatMemberUpdatedCute] = Nothing()
|
|
52
|
+
"""Optional. The bot's chat member status was updated in a chat. For private
|
|
53
|
+
chats, this update is received only when the bot is blocked or unblocked
|
|
54
|
+
by the user."""
|
|
55
|
+
|
|
56
|
+
chat_member: Option[ChatMemberUpdatedCute] = Nothing()
|
|
57
|
+
"""Optional. A chat member's status was updated in a chat. The bot must be an
|
|
58
|
+
administrator in the chat and must explicitly specify `chat_member` in
|
|
59
|
+
the list of allowed_updates to receive these updates."""
|
|
60
|
+
|
|
61
|
+
chat_join_request: Option[ChatJoinRequestCute] = Nothing()
|
|
62
|
+
"""Optional. A request to join the chat has been sent. The bot must have the can_invite_users
|
|
63
|
+
administrator right in the chat to receive these updates."""
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def incoming_update(self) -> Model:
|
|
67
|
+
return getattr(self, self.update_type.value).unwrap()
|
|
68
|
+
|
|
69
|
+
def get_event(self, event_model: type[ModelT]) -> Option[ModelT]:
|
|
70
|
+
if isinstance(self.incoming_update, event_model):
|
|
71
|
+
return Some(self.incoming_update)
|
|
72
|
+
return Nothing()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
__all__ = ("UpdateCute",)
|