telegrinder 0.1.dev161__py3-none-any.whl → 0.1.dev163__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/api/api.py +4 -2
- telegrinder/api/error.py +3 -3
- telegrinder/bot/bot.py +8 -12
- telegrinder/bot/cute_types/base.py +1 -4
- telegrinder/bot/cute_types/message.py +140 -0
- telegrinder/bot/dispatch/composition.py +1 -1
- telegrinder/bot/dispatch/dispatch.py +3 -4
- telegrinder/bot/dispatch/view/box.py +6 -6
- telegrinder/bot/dispatch/waiter_machine/short_state.py +1 -1
- telegrinder/bot/rules/__init__.py +4 -0
- telegrinder/bot/rules/is_from.py +18 -3
- telegrinder/bot/scenario/checkbox.py +3 -4
- telegrinder/client/aiohttp.py +1 -2
- telegrinder/modules.py +5 -3
- telegrinder/msgspec_json.py +3 -3
- telegrinder/msgspec_utils.py +80 -38
- telegrinder/node/source.py +2 -3
- telegrinder/tools/__init__.py +6 -0
- telegrinder/tools/buttons.py +8 -13
- telegrinder/tools/error_handler/error_handler.py +2 -2
- telegrinder/tools/formatting/__init__.py +6 -0
- telegrinder/tools/formatting/html.py +10 -0
- telegrinder/tools/formatting/links.py +7 -0
- telegrinder/tools/formatting/spec_html_formats.py +27 -15
- telegrinder/tools/global_context/global_context.py +7 -5
- telegrinder/tools/keyboard.py +3 -3
- telegrinder/tools/loop_wrapper/abc.py +4 -4
- telegrinder/tools/magic.py +1 -1
- telegrinder/types/enums.py +4 -0
- telegrinder/types/methods.py +175 -41
- telegrinder/types/objects.py +442 -201
- {telegrinder-0.1.dev161.dist-info → telegrinder-0.1.dev163.dist-info}/METADATA +1 -1
- {telegrinder-0.1.dev161.dist-info → telegrinder-0.1.dev163.dist-info}/RECORD +35 -35
- {telegrinder-0.1.dev161.dist-info → telegrinder-0.1.dev163.dist-info}/WHEEL +1 -1
- {telegrinder-0.1.dev161.dist-info → telegrinder-0.1.dev163.dist-info}/LICENSE +0 -0
telegrinder/api/api.py
CHANGED
|
@@ -16,7 +16,7 @@ def compose_data(
|
|
|
16
16
|
data: dict[str, typing.Any],
|
|
17
17
|
files: dict[str, tuple[str, bytes]],
|
|
18
18
|
) -> typing.Any:
|
|
19
|
-
converter = DataConverter(files=files)
|
|
19
|
+
converter = DataConverter(files=files.copy())
|
|
20
20
|
return client.get_form(
|
|
21
21
|
data={k: converter(v) for k, v in data.items()},
|
|
22
22
|
files=converter.files,
|
|
@@ -24,6 +24,8 @@ def compose_data(
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class API(ABCAPI, APIMethods):
|
|
27
|
+
"""Bot API with available API methods."""
|
|
28
|
+
|
|
27
29
|
API_URL = "https://api.telegram.org/"
|
|
28
30
|
|
|
29
31
|
def __init__(self, token: Token, *, http: ABCClient | None = None) -> None:
|
|
@@ -60,7 +62,7 @@ class API(ABCAPI, APIMethods):
|
|
|
60
62
|
assert "result" in response
|
|
61
63
|
return Ok(response["result"])
|
|
62
64
|
return Error(APIError(
|
|
63
|
-
code=response.get("error_code",
|
|
65
|
+
code=response.get("error_code", 400),
|
|
64
66
|
error=response.get("description"),
|
|
65
67
|
))
|
|
66
68
|
|
telegrinder/api/error.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
class APIError(BaseException):
|
|
2
|
-
def __init__(self, code: int, error: str | None = None):
|
|
2
|
+
def __init__(self, code: int, error: str | None = None) -> None:
|
|
3
3
|
self.code, self.error = code, error
|
|
4
4
|
|
|
5
5
|
def __str__(self) -> str:
|
|
6
|
-
return f"[{self.code}] {self.error}"
|
|
6
|
+
return f"[{self.code}] {self.error or 'Something went wrong'}"
|
|
7
7
|
|
|
8
8
|
def __repr__(self) -> str:
|
|
9
|
-
return f"<APIError {self.__str__()}>"
|
|
9
|
+
return f"<APIError: {self.__str__()}>"
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class InvalidTokenError(BaseException):
|
telegrinder/bot/bot.py
CHANGED
|
@@ -11,11 +11,7 @@ PollingT = typing.TypeVar("PollingT", bound=ABCPolling, default=Polling)
|
|
|
11
11
|
LoopWrapperT = typing.TypeVar("LoopWrapperT", bound=ABCLoopWrapper, default=LoopWrapper)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class Telegrinder(typing.Generic[DispatchT, PollingT, LoopWrapperT]):
|
|
15
|
-
dispatch: DispatchT
|
|
16
|
-
polling: PollingT
|
|
17
|
-
loop_wrapper: LoopWrapperT
|
|
18
|
-
|
|
14
|
+
class Telegrinder(typing.Generic[DispatchT, PollingT, LoopWrapperT]):
|
|
19
15
|
def __init__(
|
|
20
16
|
self,
|
|
21
17
|
api: API,
|
|
@@ -23,11 +19,11 @@ class Telegrinder(typing.Generic[DispatchT, PollingT, LoopWrapperT]):
|
|
|
23
19
|
polling: PollingT | None = None,
|
|
24
20
|
dispatch: DispatchT | None = None,
|
|
25
21
|
loop_wrapper: LoopWrapperT | None = None,
|
|
26
|
-
):
|
|
22
|
+
) -> None:
|
|
27
23
|
self.api = api
|
|
28
|
-
self.dispatch = dispatch or Dispatch()
|
|
29
|
-
self.polling = polling or Polling(api)
|
|
30
|
-
self.loop_wrapper = loop_wrapper or LoopWrapper()
|
|
24
|
+
self.dispatch = typing.cast(DispatchT, dispatch or Dispatch())
|
|
25
|
+
self.polling = typing.cast(PollingT, polling or Polling(api))
|
|
26
|
+
self.loop_wrapper = typing.cast(LoopWrapperT, loop_wrapper or LoopWrapper())
|
|
31
27
|
|
|
32
28
|
@property
|
|
33
29
|
def on(self) -> DispatchT:
|
|
@@ -38,7 +34,7 @@ class Telegrinder(typing.Generic[DispatchT, PollingT, LoopWrapperT]):
|
|
|
38
34
|
return
|
|
39
35
|
await self.api.delete_webhook()
|
|
40
36
|
|
|
41
|
-
async def run_polling(self, offset: int = 0, skip_updates: bool = False) -> None:
|
|
37
|
+
async def run_polling(self, *, offset: int = 0, skip_updates: bool = False) -> None:
|
|
42
38
|
if skip_updates:
|
|
43
39
|
logger.debug("Dropping pending updates")
|
|
44
40
|
await self.reset_webhook()
|
|
@@ -50,9 +46,9 @@ class Telegrinder(typing.Generic[DispatchT, PollingT, LoopWrapperT]):
|
|
|
50
46
|
logger.debug("Received update (update_id={})", update.update_id)
|
|
51
47
|
self.loop_wrapper.add_task(self.dispatch.feed(update, self.api))
|
|
52
48
|
|
|
53
|
-
def run_forever(self, offset: int = 0, skip_updates: bool = False) -> None:
|
|
49
|
+
def run_forever(self, *, offset: int = 0, skip_updates: bool = False) -> None:
|
|
54
50
|
logger.debug("Running blocking polling (id={})", self.api.id)
|
|
55
|
-
self.loop_wrapper.add_task(self.run_polling(offset, skip_updates=skip_updates))
|
|
51
|
+
self.loop_wrapper.add_task(self.run_polling(offset=offset, skip_updates=skip_updates))
|
|
56
52
|
self.loop_wrapper.run_event_loop()
|
|
57
53
|
|
|
58
54
|
|
|
@@ -33,8 +33,6 @@ if typing.TYPE_CHECKING:
|
|
|
33
33
|
else:
|
|
34
34
|
|
|
35
35
|
class BaseCute(typing.Generic[UpdateT]):
|
|
36
|
-
api: ABCAPI
|
|
37
|
-
|
|
38
36
|
@classmethod
|
|
39
37
|
def from_update(cls, update, bound_api):
|
|
40
38
|
return cls(**update.to_dict(), api=bound_api)
|
|
@@ -115,8 +113,7 @@ def shortcut(
|
|
|
115
113
|
params[k] = kwargs.pop(k, p.default) if p.default is not p.empty else kwargs.pop(k)
|
|
116
114
|
|
|
117
115
|
return await executor(self, method_name, get_params(params))
|
|
118
|
-
|
|
119
|
-
func.__repr__ = lambda _: f"<Shortcut {method_name!r}@{func!r}>"
|
|
116
|
+
|
|
120
117
|
inner.__shortcut__ = Shortcut( # type: ignore
|
|
121
118
|
method_name=method_name,
|
|
122
119
|
executor=executor,
|