Skip to content

Commit 12f841e

Browse files
committed
Lots of improvements
1 parent 2b8d82b commit 12f841e

File tree

13 files changed

+474
-232
lines changed

13 files changed

+474
-232
lines changed

src/telegrambots/custom/contexts/_contexts/callback_query_context.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional, final, TYPE_CHECKING
1+
from typing import Any, Optional, final, TYPE_CHECKING
22

33
from telegrambots.wrapper.types.objects import (
44
CallbackQuery,
@@ -15,13 +15,14 @@
1515

1616
class CallbackQueryContext(GenericContext[CallbackQuery]):
1717
def __init__(
18-
self,
19-
dp: "Dispatcher",
20-
update: Update,
21-
handler_tag: str,
18+
self, dp: "Dispatcher", update: Update, handler_tag: str, **kwargs: Any
2219
) -> None:
2320
super().__init__(
24-
dp, update=update, update_type=CallbackQuery, handler_tag=handler_tag
21+
dp,
22+
update=update,
23+
update_type=CallbackQuery,
24+
handler_tag=handler_tag,
25+
**kwargs
2526
)
2627

2728
@final

src/telegrambots/custom/contexts/_contexts/context_template.py

+27-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Any,
44
Callable,
55
Generic,
6+
Mapping,
67
Optional,
78
final,
89
TYPE_CHECKING,
@@ -21,7 +22,11 @@
2122

2223
class ContextTemplate(metaclass=ABCMeta):
2324
def __init__(
24-
self, dp: "Dispatcher", update: Update, update_type: type[Any], handler_tag: str
25+
self,
26+
dp: "Dispatcher",
27+
update: Update,
28+
update_type: type[Any],
29+
handler_tag: str,
2530
):
2631
self.__dp = dp
2732
self.__update = update
@@ -78,11 +83,28 @@ def continue_with(self) -> ContinueWithExtensions:
7883
return self.__continue_with
7984

8085

81-
class GenericContext(Generic[TUpdate], Exctractable[TUpdate], ABC, ContextTemplate):
86+
class GenericContext(
87+
Generic[TUpdate], Exctractable[TUpdate], Mapping[str, Any], ContextTemplate, ABC
88+
):
8289
def __init__(
83-
self, dp: "Dispatcher", update: Update, update_type: type[Any], handler_tag: str
90+
self,
91+
dp: "Dispatcher",
92+
update: Update,
93+
update_type: type[Any],
94+
handler_tag: str,
95+
**kwargs: Any,
8496
) -> None:
8597
super().__init__(dp, update, update_type, handler_tag)
98+
self._metadata: dict[str, Any] = kwargs
99+
100+
def __getitem__(self, name: str):
101+
return self._metadata[name]
102+
103+
def __iter__(self):
104+
return iter(self._metadata)
105+
106+
def __len__(self) -> int:
107+
return len(self._metadata)
86108

87109
@final
88110
@property
@@ -102,8 +124,9 @@ def __init__(
102124
update: Update,
103125
update_type: type[Any],
104126
handler_tag: str,
127+
**kwargs: Any,
105128
) -> None:
106-
super().__init__(dp, update, update_type, handler_tag)
129+
super().__init__(dp, update, update_type, handler_tag, **kwargs)
107130
self.__extractor = _exctractor
108131

109132
@final

src/telegrambots/custom/contexts/_contexts/message_context.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional, final, TYPE_CHECKING
1+
from typing import Any, Optional, final, TYPE_CHECKING
22

33
from telegrambots.wrapper.types.objects import (
44
Message,
@@ -17,9 +17,11 @@
1717

1818

1919
class MessageContext(GenericContext[Message]):
20-
def __init__(self, dp: "Dispatcher", update: Update, handler_tag: str) -> None:
20+
def __init__(
21+
self, dp: "Dispatcher", update: Update, handler_tag: str, **kwargs: Any
22+
) -> None:
2123
super().__init__(
22-
dp, update=update, update_type=Message, handler_tag=handler_tag
24+
dp, update=update, update_type=Message, handler_tag=handler_tag, **kwargs
2325
)
2426

2527
@final

src/telegrambots/custom/dispatcher.py

+24-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Any,
55
Callable,
66
Coroutine,
7+
Mapping,
78
Optional,
89
cast,
910
final,
@@ -158,8 +159,9 @@ def add_continuously_handler(
158159
self._continuously_handlers.append((continuously_handler,))
159160

160161
async def _unlimited(self, *allowed_updates: str):
161-
async for update in self.bot.stream_updates(list(allowed_updates)):
162-
await self.feed_update(update)
162+
async with self.bot:
163+
async for update in self.bot.stream_updates(list(allowed_updates)):
164+
await self.feed_update(update)
163165

164166
async def _process_update(self, update: Update):
165167
update_type = update.update_type
@@ -173,7 +175,8 @@ async def _process_update(self, update: Update):
173175
if c.check_keys(update):
174176
handler = self._handlers[update_type][c.target_tag]
175177

176-
if not handler.should_process(update):
178+
result = handler.should_process(update)
179+
if not result.result:
177180
continue
178181

179182
if handler.continue_after is not None:
@@ -184,7 +187,12 @@ async def _process_update(self, update: Update):
184187
f"Processing continuously handler {c.update_type.__name__}:{c.target_tag}"
185188
)
186189
await self._do_handling(
187-
handler, update, c.target_tag, *c.args, **c.kwargs
190+
handler,
191+
update,
192+
c.target_tag,
193+
result.metadata,
194+
*c.args,
195+
**c.kwargs,
188196
)
189197
self._continuously_handlers.remove(batch)
190198
return # Don't process the update anymore
@@ -201,8 +209,11 @@ async def _process_update(self, update: Update):
201209
)
202210
if not h.continue_after
203211
):
204-
if handler.should_process(update):
205-
handling_result = await self._do_handling(handler, update, k)
212+
result = handler.should_process(update)
213+
if result.result:
214+
handling_result = await self._do_handling(
215+
handler, update, k, result.metadata
216+
)
206217
if handling_result is not None:
207218
if handling_result:
208219
continue
@@ -214,12 +225,18 @@ async def _do_handling(
214225
handler: HandlerTemplate,
215226
update: Update,
216227
handler_tag: str,
228+
filter_data: Mapping[str, Any],
217229
*args: Any,
218230
**kwargs: Any,
219231
):
220232
try:
221233
await handler.process(
222-
self, update, handler.update_type, handler_tag, *args, **kwargs
234+
self,
235+
update,
236+
handler_tag,
237+
filter_data,
238+
*args,
239+
**kwargs,
223240
)
224241
except ContinuePropagation:
225242
return True # -> continue to next handler

src/telegrambots/custom/extensions/context.py

+104-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
from ..exceptions.propagations import BreakPropagation, ContinuePropagation
2020
from ..general import TUpdate
2121
from ..key_resolvers.key_resolver import AbstractKeyResolver
22+
from ..key_resolvers import (
23+
MessageSenderId,
24+
CallbackQueryMessageId,
25+
CallbackQuerySenderId,
26+
)
2227
from ..filters import Filter
2328

2429
if TYPE_CHECKING:
@@ -67,12 +72,85 @@ def decorator(
6772
_tag = tag or _function.__name__
6873
if not self._context.dp.handler_tag_exists(_tag, CallbackQuery):
6974
self._context.dp.add.handlers.callback_query(
70-
_tag, _function, filter, [self.handler_tag] # type: ignore
75+
_tag, _function, filter, [self._context.handler_tag]
7176
)
7277
self._context.continue_with.callback_query(_tag, keys, *args, **kwargs)
7378

7479
return decorator
7580

81+
def callback_query_form(
82+
self,
83+
user_id: int,
84+
filter: Filter[CallbackQuery],
85+
tag: Optional[str] = None,
86+
*args: Any,
87+
**kwargs: Any,
88+
):
89+
def decorator(
90+
_function: Callable[["CallbackQueryContext"], Coroutine[Any, Any, None]]
91+
):
92+
_tag = tag or _function.__name__
93+
if not self._context.dp.handler_tag_exists(_tag, CallbackQuery):
94+
self._context.dp.add.handlers.callback_query(
95+
_tag, _function, filter, [self._context.handler_tag]
96+
)
97+
self._context.continue_with.callback_query(
98+
_tag, [CallbackQuerySenderId(user_id)], *args, **kwargs
99+
)
100+
101+
return decorator
102+
103+
def callback_query_same_message_form(
104+
self,
105+
message_id: int,
106+
user_id: int,
107+
filter: Filter[CallbackQuery],
108+
tag: Optional[str] = None,
109+
*args: Any,
110+
**kwargs: Any,
111+
):
112+
def decorator(
113+
_function: Callable[["CallbackQueryContext"], Coroutine[Any, Any, None]]
114+
):
115+
_tag = tag or _function.__name__
116+
if not self._context.dp.handler_tag_exists(_tag, CallbackQuery):
117+
self._context.dp.add.handlers.callback_query(
118+
_tag, _function, filter, [self._context.handler_tag]
119+
)
120+
self._context.continue_with.callback_query(
121+
_tag,
122+
[CallbackQuerySenderId(user_id), CallbackQueryMessageId(message_id)],
123+
*args,
124+
**kwargs,
125+
)
126+
127+
return decorator
128+
129+
def callback_query_same_message(
130+
self,
131+
message_id: int,
132+
filter: Filter[CallbackQuery],
133+
tag: Optional[str] = None,
134+
*args: Any,
135+
**kwargs: Any,
136+
):
137+
def decorator(
138+
_function: Callable[["CallbackQueryContext"], Coroutine[Any, Any, None]]
139+
):
140+
_tag = tag or _function.__name__
141+
if not self._context.dp.handler_tag_exists(_tag, CallbackQuery):
142+
self._context.dp.add.handlers.callback_query(
143+
_tag, _function, filter, [self._context.handler_tag]
144+
)
145+
self._context.continue_with.callback_query(
146+
_tag,
147+
[CallbackQueryMessageId(message_id)],
148+
*args,
149+
**kwargs,
150+
)
151+
152+
return decorator
153+
76154
def message(
77155
self,
78156
keys: list[AbstractKeyResolver[Message, Any]],
@@ -86,11 +164,35 @@ def decorator(
86164
):
87165
_tag = tag or _function.__name__
88166
if not self._context.dp.handler_tag_exists(_tag, Message):
89-
self._context.dp.add.handlers.message(_tag, _function, filter, [self.handler_tag]) # type: ignore
167+
self._context.dp.add.handlers.message(
168+
_tag, _function, filter, [self._context.handler_tag]
169+
)
90170
self._context.continue_with.message(_tag, keys, *args, **kwargs)
91171

92172
return decorator
93173

174+
def message_from(
175+
self,
176+
user_id: int,
177+
filter: "Filter[Message]",
178+
tag: Optional[str] = None,
179+
*args: Any,
180+
**kwargs: Any,
181+
):
182+
def decorator(
183+
_function: Callable[["MessageContext"], Coroutine[Any, Any, None]]
184+
):
185+
_tag = tag or _function.__name__
186+
if not self._context.dp.handler_tag_exists(_tag, Message):
187+
self._context.dp.add.handlers.message(
188+
_tag, _function, filter, [self._context.handler_tag]
189+
)
190+
self._context.continue_with.message(
191+
_tag, [MessageSenderId(user_id)], *args, **kwargs
192+
)
193+
194+
return decorator
195+
94196

95197
class ContinueWithExtensions(ContextExtensions):
96198
def __init__(self, context: "ContextTemplate") -> None:

0 commit comments

Comments
 (0)