telegrinder 0.2.2__py3-none-any.whl → 0.3.0__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.

Files changed (31) hide show
  1. telegrinder/__init__.py +24 -2
  2. telegrinder/bot/__init__.py +16 -0
  3. telegrinder/bot/cute_types/callback_query.py +60 -146
  4. telegrinder/bot/cute_types/chat_join_request.py +12 -16
  5. telegrinder/bot/cute_types/chat_member_updated.py +14 -104
  6. telegrinder/bot/cute_types/inline_query.py +5 -14
  7. telegrinder/bot/cute_types/message.py +605 -1227
  8. telegrinder/bot/dispatch/__init__.py +22 -1
  9. telegrinder/bot/dispatch/abc.py +7 -0
  10. telegrinder/bot/dispatch/dispatch.py +7 -0
  11. telegrinder/bot/dispatch/waiter_machine/__init__.py +18 -0
  12. telegrinder/bot/dispatch/waiter_machine/actions.py +10 -0
  13. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +15 -0
  14. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +60 -0
  15. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +49 -0
  16. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +54 -0
  17. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -0
  18. telegrinder/bot/dispatch/waiter_machine/machine.py +87 -99
  19. telegrinder/bot/dispatch/waiter_machine/middleware.py +23 -35
  20. telegrinder/bot/dispatch/waiter_machine/short_state.py +9 -9
  21. telegrinder/bot/scenario/checkbox.py +2 -2
  22. telegrinder/model.py +6 -4
  23. telegrinder/msgspec_json.py +1 -1
  24. telegrinder/msgspec_utils.py +51 -0
  25. telegrinder/node/event.py +2 -0
  26. telegrinder/tools/functional.py +9 -0
  27. telegrinder/tools/state_storage/memory.py +3 -3
  28. {telegrinder-0.2.2.dist-info → telegrinder-0.3.0.dist-info}/METADATA +2 -2
  29. {telegrinder-0.2.2.dist-info → telegrinder-0.3.0.dist-info}/RECORD +31 -24
  30. {telegrinder-0.2.2.dist-info → telegrinder-0.3.0.dist-info}/LICENSE +0 -0
  31. {telegrinder-0.2.2.dist-info → telegrinder-0.3.0.dist-info}/WHEEL +0 -0
@@ -5,8 +5,11 @@ from telegrinder.bot.cute_types.base import BaseCute
5
5
  from telegrinder.bot.dispatch.context import Context
6
6
  from telegrinder.bot.dispatch.handler.func import FuncHandler
7
7
  from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
8
- from telegrinder.bot.dispatch.view.abc import ABCStateView
8
+ from telegrinder.bot.dispatch.process import check_rule
9
9
  from telegrinder.bot.dispatch.waiter_machine.short_state import ShortStateContext
10
+ from telegrinder.modules import logger
11
+
12
+ from .hasher import Hasher
10
13
 
11
14
  if typing.TYPE_CHECKING:
12
15
  from .machine import WaiterMachine
@@ -19,21 +22,21 @@ class WaiterMiddleware(ABCMiddleware[EventType]):
19
22
  def __init__(
20
23
  self,
21
24
  machine: "WaiterMachine",
22
- view: ABCStateView[EventType],
25
+ hasher: Hasher,
23
26
  ) -> None:
24
27
  self.machine = machine
25
- self.view = view
28
+ self.hasher = hasher
26
29
 
27
30
  async def pre(self, event: EventType, ctx: Context) -> bool:
28
- view_name = self.view.__class__.__name__
29
- if view_name not in self.machine.storage:
31
+ if self.hasher not in self.machine.storage:
30
32
  return True
31
33
 
32
- key = self.view.get_state_key(event)
34
+ key = self.hasher.get_hash_from_data_from_event(event)
33
35
  if key is None:
34
- raise RuntimeError("Unable to get state key.")
36
+ logger.info(f"Unable to get hash from event with hasher {self.hasher}")
37
+ return True
35
38
 
36
- short_state: "ShortState[EventType] | None" = self.machine.storage[view_name].get(key)
39
+ short_state: "ShortState[EventType] | None" = self.machine.storage[self.hasher].get(key.unwrap())
37
40
  if not short_state:
38
41
  return True
39
42
 
@@ -41,35 +44,24 @@ class WaiterMiddleware(ABCMiddleware[EventType]):
41
44
  if short_state.context is not None:
42
45
  preset_context.update(short_state.context.context)
43
46
 
44
- if short_state.expiration_date is not None and datetime.datetime.now() >= short_state.expiration_date:
45
- await self.machine.drop(
46
- self.view,
47
- short_state.key,
48
- event,
49
- ctx.raw_update,
50
- **preset_context.copy(),
51
- )
47
+ # Run filter rule
48
+ if short_state.filter and not await check_rule(
49
+ event.ctx_api, short_state.filter, ctx.raw_update, preset_context
50
+ ):
51
+ logger.debug("Filter rule {!r} failed", short_state.filter)
52
52
  return True
53
53
 
54
- # before running the handler we check if the user wants to exit waiting
55
- if short_state.exit_behaviour is not None and await self.machine.call_behaviour(
56
- event,
57
- ctx.raw_update,
58
- behaviour=short_state.exit_behaviour,
59
- **preset_context,
60
- ):
54
+ if short_state.expiration_date is not None and datetime.datetime.now() >= short_state.expiration_date:
61
55
  await self.machine.drop(
62
- self.view,
63
- short_state.key,
64
- event,
65
- ctx.raw_update,
56
+ self.hasher,
57
+ self.hasher.get_data_from_event(event).unwrap(),
66
58
  **preset_context.copy(),
67
59
  )
68
60
  return True
69
61
 
70
62
  handler = FuncHandler(
71
63
  self.pass_runtime,
72
- list(short_state.rules),
64
+ [short_state.release] if short_state.release else [],
73
65
  dataclass=None,
74
66
  preset_context=preset_context,
75
67
  )
@@ -78,13 +70,9 @@ class WaiterMiddleware(ABCMiddleware[EventType]):
78
70
  if result is True:
79
71
  await handler.run(event.api, event, ctx)
80
72
 
81
- elif short_state.default_behaviour is not None:
82
- await self.machine.call_behaviour(
83
- event,
84
- ctx.raw_update,
85
- behaviour=short_state.default_behaviour,
86
- **handler.preset_context,
87
- )
73
+ elif on_miss := short_state.actions.get("on_miss"): # noqa: SIM102
74
+ if await on_miss.check(event.ctx_api, ctx.raw_update, ctx):
75
+ await on_miss.run(event.ctx_api, event, ctx)
88
76
 
89
77
  return False
90
78
 
@@ -3,7 +3,6 @@ import dataclasses
3
3
  import datetime
4
4
  import typing
5
5
 
6
- from telegrinder.api.api import API
7
6
  from telegrinder.bot.cute_types import BaseCute
8
7
  from telegrinder.bot.dispatch.context import Context
9
8
  from telegrinder.bot.dispatch.handler.abc import ABCHandler
@@ -11,7 +10,8 @@ from telegrinder.bot.rules.abc import ABCRule
11
10
  from telegrinder.model import Model
12
11
 
13
12
  if typing.TYPE_CHECKING:
14
- from .machine import Identificator
13
+ from .actions import WaiterActions
14
+
15
15
 
16
16
  T = typing.TypeVar("T", bound=Model)
17
17
  EventModel = typing.TypeVar("EventModel", bound=BaseCute)
@@ -26,19 +26,19 @@ class ShortStateContext(typing.Generic[EventModel], typing.NamedTuple):
26
26
 
27
27
  @dataclasses.dataclass(slots=True)
28
28
  class ShortState(typing.Generic[EventModel]):
29
- key: "Identificator"
30
- ctx_api: API
31
29
  event: asyncio.Event
32
- rules: tuple[ABCRule, ...]
33
- expiration: dataclasses.InitVar[datetime.timedelta | None] = dataclasses.field(
30
+ actions: "WaiterActions"
31
+
32
+ release: ABCRule | None = None
33
+ filter: ABCRule | None = None
34
+ lifetime: dataclasses.InitVar[datetime.timedelta | None] = dataclasses.field(
34
35
  default=None,
35
36
  kw_only=True,
36
37
  )
37
- default_behaviour: Behaviour[EventModel] | None = dataclasses.field(default=None, kw_only=True)
38
- on_drop_behaviour: Behaviour[EventModel] | None = dataclasses.field(default=None, kw_only=True)
39
- exit_behaviour: Behaviour[EventModel] | None = dataclasses.field(default=None, kw_only=True)
38
+
40
39
  expiration_date: datetime.datetime | None = dataclasses.field(init=False, kw_only=True)
41
40
  creation_date: datetime.datetime = dataclasses.field(init=False)
41
+
42
42
  context: ShortStateContext[EventModel] | None = dataclasses.field(default=None, init=False, kw_only=True)
43
43
 
44
44
  def __post_init__(self, expiration: datetime.timedelta | None = None) -> None:
@@ -3,7 +3,7 @@ import secrets
3
3
  import typing
4
4
 
5
5
  from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
6
- from telegrinder.bot.dispatch.waiter_machine import WaiterMachine
6
+ from telegrinder.bot.dispatch.waiter_machine import StateViewHasher, WaiterMachine
7
7
  from telegrinder.bot.scenario.abc import ABCScenario
8
8
  from telegrinder.tools.keyboard import InlineButton, InlineKeyboard
9
9
  from telegrinder.tools.parse_mode import ParseMode
@@ -124,7 +124,7 @@ class Checkbox(ABCScenario[CallbackQueryCute]):
124
124
  ).unwrap()
125
125
 
126
126
  while True:
127
- q, _ = await self.waiter_machine.wait(view, (api, message.message_id))
127
+ q, _ = await self.waiter_machine.wait(StateViewHasher(view.__class__), message.message_id)
128
128
  should_continue = await self.handle(q)
129
129
  await q.answer(self.CALLBACK_ANSWER)
130
130
  if not should_continue:
telegrinder/model.py CHANGED
@@ -16,6 +16,8 @@ if typing.TYPE_CHECKING:
16
16
 
17
17
  T = typing.TypeVar("T")
18
18
 
19
+ UnionType: typing.TypeAlias = typing.Annotated[tuple[T, ...], ...]
20
+
19
21
  MODEL_CONFIG: typing.Final[dict[str, typing.Any]] = {
20
22
  "omit_defaults": True,
21
23
  "dict": True,
@@ -33,15 +35,15 @@ def full_result(
33
35
  @typing.overload
34
36
  def full_result(
35
37
  result: Result[msgspec.Raw, "APIError"],
36
- full_t: tuple[type[T], ...],
38
+ full_t: UnionType[T],
37
39
  ) -> Result[T, "APIError"]: ...
38
40
 
39
41
 
40
42
  def full_result(
41
43
  result: Result[msgspec.Raw, "APIError"],
42
- full_t: type[T] | tuple[type[T], ...],
43
- ) -> Result[T, "APIError"]:
44
- return result.map(lambda v: decoder.decode(v, type=full_t)) # type: ignore
44
+ full_t: typing.Any,
45
+ ) -> Result[typing.Any, "APIError"]:
46
+ return result.map(lambda v: decoder.decode(v, type=full_t))
45
47
 
46
48
 
47
49
  def get_params(params: dict[str, typing.Any]) -> dict[str, typing.Any]:
@@ -1,6 +1,6 @@
1
1
  import typing
2
2
 
3
- from .msgspec_utils import decoder, encoder
3
+ from telegrinder.msgspec_utils import decoder, encoder
4
4
 
5
5
 
6
6
  def loads(s: str | bytes) -> typing.Any:
@@ -1,5 +1,6 @@
1
1
  import dataclasses
2
2
  import typing
3
+ from contextlib import contextmanager
3
4
 
4
5
  import fntypes.option
5
6
  import fntypes.result
@@ -201,6 +202,31 @@ class Decoder:
201
202
  self.dec_hooks,
202
203
  )
203
204
 
205
+ @typing.overload
206
+ def __call__(self, type: type[T]) -> typing.ContextManager[msgspec.json.Decoder[T]]: ...
207
+
208
+ @typing.overload
209
+ def __call__(self, type: typing.Any) -> typing.ContextManager[msgspec.json.Decoder[typing.Any]]: ...
210
+
211
+ @typing.overload
212
+ def __call__(
213
+ self, type: type[T], *, strict: bool = True
214
+ ) -> typing.ContextManager[msgspec.json.Decoder[T]]: ...
215
+
216
+ @typing.overload
217
+ def __call__(
218
+ self, type: typing.Any, *, strict: bool = True
219
+ ) -> typing.ContextManager[msgspec.json.Decoder[typing.Any]]: ...
220
+
221
+ @contextmanager
222
+ def __call__(self, type=object, *, strict=True):
223
+ """Context manager returns the `msgspec.json.Decoder` object with the `dec_hook`."""
224
+
225
+ dec_obj = msgspec.json.Decoder(
226
+ type=typing.Any if type is object else type, strict=strict, dec_hook=self.dec_hook
227
+ )
228
+ yield dec_obj
229
+
204
230
  def add_dec_hook(self, t: T): # type: ignore
205
231
  def decorator(func: DecHook[T]) -> DecHook[T]:
206
232
  return self.dec_hooks.setdefault(get_origin(t), func) # type: ignore
@@ -241,6 +267,9 @@ class Decoder:
241
267
  @typing.overload
242
268
  def decode(self, buf: str | bytes, *, type: type[T]) -> T: ...
243
269
 
270
+ @typing.overload
271
+ def decode(self, buf: str | bytes, *, type: typing.Any) -> typing.Any: ...
272
+
244
273
  @typing.overload
245
274
  def decode(
246
275
  self,
@@ -250,6 +279,15 @@ class Decoder:
250
279
  strict: bool = True,
251
280
  ) -> T: ...
252
281
 
282
+ @typing.overload
283
+ def decode(
284
+ self,
285
+ buf: str | bytes,
286
+ *,
287
+ type: typing.Any,
288
+ strict: bool = True,
289
+ ) -> typing.Any: ...
290
+
253
291
  def decode(self, buf, *, type=object, strict=True):
254
292
  return msgspec.json.decode(
255
293
  buf,
@@ -287,6 +325,19 @@ class Encoder:
287
325
  self.enc_hooks,
288
326
  )
289
327
 
328
+ @contextmanager
329
+ def __call__(
330
+ self,
331
+ *,
332
+ decimal_format: typing.Literal["string", "number"] = "string",
333
+ uuid_format: typing.Literal["canonical", "hex"] = "canonical",
334
+ order: typing.Literal[None, "deterministic", "sorted"] = None,
335
+ ) -> typing.Generator[msgspec.json.Encoder, typing.Any, None]:
336
+ """Context manager returns the `msgspec.json.Encoder` object with the `enc_hook`."""
337
+
338
+ enc_obj = msgspec.json.Encoder(enc_hook=self.enc_hook)
339
+ yield enc_obj
340
+
290
341
  def add_dec_hook(self, t: type[T]):
291
342
  def decorator(func: EncHook[T]) -> EncHook[T]:
292
343
  encode_hook = self.enc_hooks.setdefault(get_origin(t), func)
telegrinder/node/event.py CHANGED
@@ -65,7 +65,9 @@ if typing.TYPE_CHECKING:
65
65
  EventNode: typing.TypeAlias = typing.Annotated["Dataclass", ...]
66
66
 
67
67
  else:
68
+
68
69
  class EventNode(_EventNode):
69
70
  pass
70
71
 
72
+
71
73
  __all__ = ("EventNode",)
@@ -0,0 +1,9 @@
1
+ import typing
2
+
3
+ from fntypes import Nothing, Option, Some
4
+
5
+ T = typing.TypeVar("T")
6
+
7
+
8
+ def from_optional(value: T | None) -> Option[T]:
9
+ return Some(value) if value is not None else Nothing()
@@ -1,7 +1,8 @@
1
1
  import typing
2
2
 
3
- from fntypes import Nothing, Option, Some
3
+ from fntypes.option import Option
4
4
 
5
+ from telegrinder.tools.functional import from_optional
5
6
  from telegrinder.tools.state_storage.abc import ABCStateStorage, StateData
6
7
 
7
8
  Payload: typing.TypeAlias = dict[str, typing.Any]
@@ -12,8 +13,7 @@ class MemoryStateStorage(ABCStateStorage[Payload]):
12
13
  self.storage: dict[int, StateData[Payload]] = {}
13
14
 
14
15
  async def get(self, user_id: int) -> Option[StateData[Payload]]:
15
- state = self.storage.get(user_id)
16
- return Some(state) if state is not None else Nothing()
16
+ return from_optional(self.storage.get(user_id))
17
17
 
18
18
  async def set(self, user_id: int, key: str, payload: Payload) -> None:
19
19
  self.storage[user_id] = StateData(key, payload)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: telegrinder
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Modern visionary telegram bot framework.
5
5
  Home-page: https://github.com/timoniq/telegrinder
6
6
  License: MIT
@@ -43,7 +43,7 @@ Still in development.
43
43
  * Type hinted
44
44
  * Customizable and extensible
45
45
  * Ready to use scenarios and rules
46
- * Fast models built on msgspec
46
+ * Fast models built on [msgspec](https://github.com/jcrist/msgspec)
47
47
  * Both low-level and high-level API
48
48
  * Support [optional dependecies](https://github.com/timoniq/telegrinder/blob/dev/docs/guide/optional_dependencies.md)
49
49
 
@@ -1,24 +1,24 @@
1
- telegrinder/__init__.py,sha256=-ugeakMlK1z4q-JLjsa8OFVq6s27BdVat1nFB8wSiok,4798
1
+ telegrinder/__init__.py,sha256=b3mjSnDAgD28pyv7tS-cqlAPjZeYkFeTSJ6TIvoNDxw,5407
2
2
  telegrinder/api/__init__.py,sha256=AFZ07UvdL4rhq9lZpB-j9JuGOONmfkvt8RfdG71ND38,226
3
3
  telegrinder/api/api.py,sha256=OSwm2_mgHS9jCsKy_vdOJzVtH-j6v68ypkdtvKFlQ3w,2877
4
4
  telegrinder/api/error.py,sha256=6_KBR819Tg9mLI7w5aHHYnrS8VSDYNkWIrHCnfgCFKk,422
5
5
  telegrinder/api/response.py,sha256=d7Oxd5kOdbZNJiALkzkecHl8Y3K_BzCmsRq2Sn3otqA,491
6
6
  telegrinder/api/token.py,sha256=wBnMHOgZZuQctsqPKT-u5GVdrj5vJ6u5zpJJOGS8or8,945
7
- telegrinder/bot/__init__.py,sha256=ieBoMw1L-GQZDP-quE-5HHZrSdpvyiTb4XXiKvSdJ-k,2341
7
+ telegrinder/bot/__init__.py,sha256=8Ft0wFT2n-l-DkImsGcxxbt3zgJumMwUIEGTfn0k8XU,2777
8
8
  telegrinder/bot/bot.py,sha256=qrB7GHglZG1wuXdPrAQ7kFzcuOT1og_ybwuem_feL-U,2780
9
9
  telegrinder/bot/cute_types/__init__.py,sha256=moe1mSKesNqUBf8m11s2wiL0fJIa8JOEHRqDr2Tira8,639
10
10
  telegrinder/bot/cute_types/base.py,sha256=EmQH0UZSzVdaMNT_9ExbN9-YUdngIUory97aDj_-rIM,8084
11
- telegrinder/bot/cute_types/callback_query.py,sha256=nXFFnKHD4qJFpuzxySRRESloThWUGHdJRN8PshFfPY8,20885
12
- telegrinder/bot/cute_types/chat_join_request.py,sha256=xL0DG-7XSbbKpYOeOuNFCg-wWMkO0uCPygUvV4G23mg,2305
13
- telegrinder/bot/cute_types/chat_member_updated.py,sha256=Jm0W8oQvK0b1XbEaK4Y9AjmGMWgWCIIU3zDbbEP9m34,10904
14
- telegrinder/bot/cute_types/inline_query.py,sha256=M9h4wNpFArKgoLPOO6H1AAl6jovuY9BnGwEmqfjp7bo,2493
15
- telegrinder/bot/cute_types/message.py,sha256=E0h86WoiWygrK2lfCT_DaevUu8mSh7O1B5MXK_92-OA,151057
11
+ telegrinder/bot/cute_types/callback_query.py,sha256=Mn2T5-ImUHXX6Wxx6y0KE_e_uSv6kDKLLMI9R_oWpUg,18941
12
+ telegrinder/bot/cute_types/chat_join_request.py,sha256=6Omx8j5iKazo28pYgIS28iM7IaRQetWjl80UeB896JA,2017
13
+ telegrinder/bot/cute_types/chat_member_updated.py,sha256=h-bqVkSlZk_AcEV8MT8gLXgwTDGVs-pRGYbqpN8frIQ,6371
14
+ telegrinder/bot/cute_types/inline_query.py,sha256=51a9i3iIwvppY1z0uEPx4UUsPmxMl02bQnAopNC3dpE,2400
15
+ telegrinder/bot/cute_types/message.py,sha256=fT7Lmi7nhE7PuFEx0xAIwo3-YYT84uW65LIVT2uq1Ko,139029
16
16
  telegrinder/bot/cute_types/update.py,sha256=ArUnqgvzUgQvXpHYhokAXB-ReSmbxzb4w9G2I-D7Jv4,3175
17
17
  telegrinder/bot/cute_types/utils.py,sha256=oJWRS7TCkvDhckwhc8yxw3Qn1NKvqDtEGTZ745qEbMg,2530
18
- telegrinder/bot/dispatch/__init__.py,sha256=94Y27ruqBu4ovzP9pbNt460f-PRp0Tkaqd-LBCESTzA,1993
19
- telegrinder/bot/dispatch/abc.py,sha256=YPE06H_NBDgK6MxtEFmX_qNWSdztTDtA3H78U57Z2ZM,654
18
+ telegrinder/bot/dispatch/__init__.py,sha256=UzU0PM22YKtM6J2aVuGRx7NEFUGnbUZlmReCFSTCNek,2477
19
+ telegrinder/bot/dispatch/abc.py,sha256=_fmiHO9V44m0sFgWRw_3CoV0f37Iz-DkTmSx09TLtTo,787
20
20
  telegrinder/bot/dispatch/context.py,sha256=vt_kGYhyc0RKQ2GKsbi-ewAwy2OTqaho6H3wVf8c-2g,2607
21
- telegrinder/bot/dispatch/dispatch.py,sha256=R8v5YfRB0Ccy5MbpTd_BCCk6hVpHnSXpwSNNqZgqMPE,6085
21
+ telegrinder/bot/dispatch/dispatch.py,sha256=G8FU_6l5p2KldVyTtW2WNIpA5EC6TA9iXl1IdWJ2MlQ,6331
22
22
  telegrinder/bot/dispatch/handler/__init__.py,sha256=PL17gyh9u9fHHz1yTglyBpRGoioqdMD5UxFAtmTidC0,911
23
23
  telegrinder/bot/dispatch/handler/abc.py,sha256=FB2Xkiy-ZFsX2pEHfM7tCIXXjgWSouu07JYosICS9UA,578
24
24
  telegrinder/bot/dispatch/handler/audio_reply.py,sha256=eNj9sO1auG8_HwZ3RGiegh7crqIQRcXuLeZ9Zfwc4vg,1358
@@ -48,10 +48,16 @@ telegrinder/bot/dispatch/view/chat_member.py,sha256=ZDZOxxD-YJZWuX82CCZ2WkGGYKKb
48
48
  telegrinder/bot/dispatch/view/inline_query.py,sha256=Zy9YmDLKOjwgDxPykvskMTTOzGCPlOel-mX3edmlu-k,573
49
49
  telegrinder/bot/dispatch/view/message.py,sha256=dI_iL5ASVe36S7Ahrk36RVuMy0Xceb8kx5osgmhoe8M,1416
50
50
  telegrinder/bot/dispatch/view/raw.py,sha256=5U5okyT6tJM3Sxnr42S00GA9ulc28m351B4Er9-9QhU,3593
51
- telegrinder/bot/dispatch/waiter_machine/__init__.py,sha256=IeoNZIxAut4QZCqiQrA6g_BcSFyUdA-oFgfBhsG6ipA,363
52
- telegrinder/bot/dispatch/waiter_machine/machine.py,sha256=HXhkGGlYLJ1PDNWydm7vyE4OdARFYLPNXuqHoXl6y7I,6472
53
- telegrinder/bot/dispatch/waiter_machine/middleware.py,sha256=Cvak_6bNsJAgSNMjHPY0lwJ0vH8EV4M7KzP1cCJpEHo,3217
54
- telegrinder/bot/dispatch/waiter_machine/short_state.py,sha256=aPMW5tsLiwTnhjvuP94XpzaPzaWfGZoGkKEZ_Ot5UZo,2120
51
+ telegrinder/bot/dispatch/waiter_machine/__init__.py,sha256=2I3MQpTAVFCHoHJUxAPCWUyasGOkdGSBKRETiTLgBpg,862
52
+ telegrinder/bot/dispatch/waiter_machine/actions.py,sha256=_GjHGbqA264MtwSp8o3hLEqPJ8_ol9sxEj_C5gwRgSw,330
53
+ telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py,sha256=nu0WhOWmGkhybOP-faiAFEx1nlYo_N_LW2AuAmbC_Z0,497
54
+ telegrinder/bot/dispatch/waiter_machine/hasher/callback.py,sha256=L8VAMaDPMUkE7yOOzX8xKC7LPGF6at3l5Z1e8PW0Urg,1519
55
+ telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py,sha256=ZOMFkGWi1noBmXpxLwGmuP6IA6G2c_AB1KYMqE6C6c8,1603
56
+ telegrinder/bot/dispatch/waiter_machine/hasher/message.py,sha256=YRewb3bxGeL58TkLyU9HBGjiXM9Bwj-VpmElSAHxBqo,1183
57
+ telegrinder/bot/dispatch/waiter_machine/hasher/state.py,sha256=GOOI7pjOaXDiFlwI40h79Nq6jbCSVT-p_IYw2tmOka0,523
58
+ telegrinder/bot/dispatch/waiter_machine/machine.py,sha256=Yvx4dEcX7fKTryGxdbdu1b-17AYSsYJBBtBkRNJdZ2M,5795
59
+ telegrinder/bot/dispatch/waiter_machine/middleware.py,sha256=6cXjKASm1I3QPW_FaNU62c1mOleRt9OsuwWY1_zyhwQ,2976
60
+ telegrinder/bot/dispatch/waiter_machine/short_state.py,sha256=7oIXEEiaMpE6PpoZyR08SCltW_L4gBhHKS9ghhLga4o,1814
55
61
  telegrinder/bot/polling/__init__.py,sha256=OqfIFPS_V6UrCg-vCv9pkMFzTKdNbDP2faBfATs_TGg,94
56
62
  telegrinder/bot/polling/abc.py,sha256=qFiKzWTWENK-sSuShC5cPlM-JS4In2c8-1_ARdwdTms,442
57
63
  telegrinder/bot/polling/polling.py,sha256=SOcVfmMS20M2O6ilXxvu507H7S8iNawebclfmwWJe3U,4765
@@ -85,15 +91,15 @@ telegrinder/bot/rules/text.py,sha256=h8SBiqF3_kkITDRCeDDanmNG80NRoSgj_dutjoV-26Y
85
91
  telegrinder/bot/rules/update.py,sha256=k73pZzlzhw77gHAmeIsqehy0-EI2ec8wVGxGRIF_8ao,398
86
92
  telegrinder/bot/scenario/__init__.py,sha256=nnPjdxdvjoEYYMRUEfWvIhZStiY1C984x1azdRRP9II,136
87
93
  telegrinder/bot/scenario/abc.py,sha256=3UwnA9Nt6CETKm2YclD0gVbn-483fTSBriZADd3p-bM,468
88
- telegrinder/bot/scenario/checkbox.py,sha256=72dLzFX1pNEcsXA8-gLaQxEBibaTnB-yKWjaiDrZWyM,4212
94
+ telegrinder/bot/scenario/checkbox.py,sha256=rZxYJjju7_UvcCCedYk8ZNi6yA3aMgbGnWzOMwVHnrg,4249
89
95
  telegrinder/bot/scenario/choice.py,sha256=9BiLViO7MEblBcYqlAkW_L3Nfa6NWcF3sj3X1GyIyBc,1480
90
96
  telegrinder/client/__init__.py,sha256=ZiS1Wb_l_kv3FHzEEi1oXtFLwlA_HXmWOzeN0xA3E7Y,104
91
97
  telegrinder/client/abc.py,sha256=OxsTX_PLYBEeFT9zpidFUzAbQL9BM7rQqru7zdn5DiQ,1611
92
98
  telegrinder/client/aiohttp.py,sha256=gVYHhhfqdsC1OJ0x6AhK2V1x0yjeXe1PwDC0I3T6UPg,3903
93
- telegrinder/model.py,sha256=R9QBk0GROfRZMmeh1aDOOsuDr9ecbYeiJNCzciiir-A,7228
99
+ telegrinder/model.py,sha256=2s5UomOJiT97sxAlUc-ySDRWTq1Sx_6vs3jLrlVExM8,7263
94
100
  telegrinder/modules.py,sha256=0EDTJsFhM6sa9P34gHOvrsMIV-uouq80iBraFvCbOA8,7743
95
- telegrinder/msgspec_json.py,sha256=phfyhUvYYZUGEcI6RAyRx9lnARPK_Fqtw3Q0MEJnuUk,226
96
- telegrinder/msgspec_utils.py,sha256=ft6wDjxUEgfdsZ6FYIxV-XqOZFPgWyV692BQDXrjr-U,10531
101
+ telegrinder/msgspec_json.py,sha256=eDuRTP_bFYWtNPDINuzY2OGKXbdleaKyXh2mQgfJdMk,237
102
+ telegrinder/msgspec_utils.py,sha256=o2jqgORB7MT7R9idgJ88kkAJLXPXkzBxbQLQPpVR-XE,12257
97
103
  telegrinder/node/__init__.py,sha256=f4rkFvg0TeAjZehHd6qloxHZectsFsTWPh6opdekhSY,1376
98
104
  telegrinder/node/attachment.py,sha256=n79uAt1ixgnr8qjBMNstu36qe4Fli63kSvpgW1WO7S8,3061
99
105
  telegrinder/node/base.py,sha256=Wjfm4JvExaM9NSpSQmUtt7Z-r42wU5rl-asCoJ2-NC8,3741
@@ -101,7 +107,7 @@ telegrinder/node/callback_query.py,sha256=aDXnDGQb6H7im5J8A-M3vfZHczg0PrFAjUexIK
101
107
  telegrinder/node/command.py,sha256=q2J4t85XpLOd8GtoLZ_xO9yW7dKDd2-6r1-W7QatC2k,913
102
108
  telegrinder/node/composer.py,sha256=5BVj8ro8KCMpOCbPmGFloXys_aitdGRdq6zluBzuEjU,6230
103
109
  telegrinder/node/container.py,sha256=dg-QKCMmme_-vZFIBq_o0AnLsF6pABmEcWIA7fBGgOI,841
104
- telegrinder/node/event.py,sha256=oK4NJtsOIp81EDfEpP1_npxWbk834lX89Tjosn19bxc,2525
110
+ telegrinder/node/event.py,sha256=T3zweqQvzqwZn5P6KeoLOhd3ixWvNogQZ5cVfUqnrY4,2527
105
111
  telegrinder/node/me.py,sha256=jLAkRbcIijiN7UXZ62Q5F7VgCsmlgBLiU1reffnESQc,417
106
112
  telegrinder/node/message.py,sha256=TbT2zeR9kVR-QAqVkRAmtse4U0BHoWfQ4esKMKLzm7A,449
107
113
  telegrinder/node/polymorphic.py,sha256=zNgC8vjRDKFpW9SClVLEvgpvqRGFi_ku1S7PhE9A2x8,2063
@@ -124,6 +130,7 @@ telegrinder/tools/formatting/__init__.py,sha256=1tFuJjMpDphCIOR4uXQhptyLHuAZ26mY
124
130
  telegrinder/tools/formatting/html.py,sha256=h8hyN6t6cJfMBjMf-XWZixVnweoAuLUIJ1xjg9JOJDw,8736
125
131
  telegrinder/tools/formatting/links.py,sha256=dYJy2qPxa4YGHYqSSCTv-6hXz0Aa0AGuzsLXwbxPZ9A,1112
126
132
  telegrinder/tools/formatting/spec_html_formats.py,sha256=I-OULqlof8NOeSNGBddKkudqMLjsMAQ02Pc6qH_fNRQ,2617
133
+ telegrinder/tools/functional.py,sha256=tOTFesmvXHyz3tUlrP9FLG4XYa-xKzqdp4I-upOFl9w,192
127
134
  telegrinder/tools/global_context/__init__.py,sha256=5pF9growKd28WO739wk_DZUqCDw5hxs6eUcDtxTosX8,290
128
135
  telegrinder/tools/global_context/abc.py,sha256=twwAmbTk49KGl_POImr4yj6POr-zdx8mz74McuphZH0,1644
129
136
  telegrinder/tools/global_context/global_context.py,sha256=U-rdGgPJ5Cde4FuV6IP6jQWxlrvDaH6YYuBSA6RFWHU,13679
@@ -145,13 +152,13 @@ telegrinder/tools/magic.py,sha256=BltMDQ_CEEu_b63dvxdKmzMUJRAFdaboGZjAPqITrSk,45
145
152
  telegrinder/tools/parse_mode.py,sha256=JyQ-x9YAMPLhIIiUX01acyKkpWgs5TBA07W-iUyPHpE,92
146
153
  telegrinder/tools/state_storage/__init__.py,sha256=G2EK2HwS0NbRQIu0OotVlgEYtO_GuzN1aJOIxmDEtz4,211
147
154
  telegrinder/tools/state_storage/abc.py,sha256=9-UOmov9b7bQpeD0JukVsayU2FHmW45FeCnlPdayLhM,958
148
- telegrinder/tools/state_storage/memory.py,sha256=FNRV2J5PDsxLq5vN7OPmUK9yIKKX6LFWKG0s88Ep5t0,755
155
+ telegrinder/tools/state_storage/memory.py,sha256=p5ffTYIpliIFgn4OzA33n_qbdt-aeC5cbBh1ELTIK5s,753
149
156
  telegrinder/types/__init__.py,sha256=vxR7J8Ql4LLGcJy6fZlLCwXA8iyLa8hOFMdE6YDhW3k,6638
150
157
  telegrinder/types/enums.py,sha256=q9URlXZvrjOUQKpLfV6v9uspBcLrdW0gtU-m8YDnj7w,19017
151
158
  telegrinder/types/methods.py,sha256=gIqcFHVogw8bbYO7C7tf1xdzE-m5EiKe998NW-IS2fI,201311
152
159
  telegrinder/types/objects.py,sha256=tfQuJKWYH8l3vmvx65gg2yGh7kpfueU9wPMFsPZIu9k,246627
153
160
  telegrinder/verification_utils.py,sha256=X7N0mHoOzbcYeKa5XxI_EFhmEGX5XNU3qqgbV8YRRa4,987
154
- telegrinder-0.2.2.dist-info/LICENSE,sha256=Q0tKgU8mPOCQAkc6m__BrNIpRge8mPBQJDd59s21NZo,1095
155
- telegrinder-0.2.2.dist-info/METADATA,sha256=gFWErYk3oVBKiPNpyVYCI4stmoCUtZnBSkRuyOiDAdc,3106
156
- telegrinder-0.2.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
157
- telegrinder-0.2.2.dist-info/RECORD,,
161
+ telegrinder-0.3.0.dist-info/LICENSE,sha256=Q0tKgU8mPOCQAkc6m__BrNIpRge8mPBQJDd59s21NZo,1095
162
+ telegrinder-0.3.0.dist-info/METADATA,sha256=-80YtRRDKCHK9IyQ_Nee6d46wUqyPK1q5OEG0GUMo4Y,3143
163
+ telegrinder-0.3.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
164
+ telegrinder-0.3.0.dist-info/RECORD,,