|
44 | 44 | BadRequest, |
45 | 45 | CDNFileHashMismatch, |
46 | 46 | ChannelPrivate, |
47 | | - ListenerStopped, |
48 | | - ListenerTimeout, |
49 | 47 | SessionPasswordNeeded, |
50 | 48 | VolumeLocNotFound, |
51 | 49 | ) |
52 | 50 | from hydrogram.handlers.handler import Handler |
53 | 51 | from hydrogram.methods import Methods |
54 | 52 | from hydrogram.session import Auth, Session |
55 | 53 | from hydrogram.storage import BaseStorage, SQLiteStorage |
56 | | -from hydrogram.types import Identifier, Listener, ListenerTypes, TermsOfService, User |
57 | | -from hydrogram.utils import PyromodConfig, ainput |
| 54 | +from hydrogram.types import ListenerTypes, TermsOfService, User |
| 55 | +from hydrogram.utils import ainput |
58 | 56 |
|
59 | 57 | from .dispatcher import Dispatcher |
60 | 58 | from .file_id import FileId, FileType, ThumbnailSource |
61 | | -from .filters import Filter |
62 | 59 | from .mime_types import mime_types |
63 | 60 | from .parser import Parser |
64 | 61 | from .session.internals import MsgId |
@@ -345,307 +342,6 @@ async def updates_watchdog(self): |
345 | 342 | ): |
346 | 343 | await self.invoke(raw.functions.updates.GetState()) |
347 | 344 |
|
348 | | - async def listen( |
349 | | - self, |
350 | | - filters: Optional[Filter] = None, |
351 | | - listener_type: ListenerTypes = ListenerTypes.MESSAGE, |
352 | | - timeout: Optional[int] = None, |
353 | | - unallowed_click_alert: bool = True, |
354 | | - chat_id: Optional[Union[Union[int, str], list[Union[int, str]]]] = None, |
355 | | - user_id: Optional[Union[Union[int, str], list[Union[int, str]]]] = None, |
356 | | - message_id: Optional[Union[int, list[int]]] = None, |
357 | | - inline_message_id: Optional[Union[str, list[str]]] = None, |
358 | | - ): |
359 | | - """ |
360 | | - Creates a listener and waits for it to be fulfilled. |
361 | | -
|
362 | | - :param filters: A filter to check if the listener should be fulfilled. |
363 | | - :param listener_type: The type of listener to create. Defaults to :attr:`pyromod.types.ListenerTypes.MESSAGE`. |
364 | | - :param timeout: The maximum amount of time to wait for the listener to be fulfilled. Defaults to ``None``. |
365 | | - :param unallowed_click_alert: Whether to alert the user if they click on a button that is not intended for them. Defaults to ``True``. |
366 | | - :param chat_id: The chat ID(s) to listen for. Defaults to ``None``. |
367 | | - :param user_id: The user ID(s) to listen for. Defaults to ``None``. |
368 | | - :param message_id: The message ID(s) to listen for. Defaults to ``None``. |
369 | | - :param inline_message_id: The inline message ID(s) to listen for. Defaults to ``None``. |
370 | | - :return: The Message or CallbackQuery that fulfilled the listener. |
371 | | - """ |
372 | | - pattern = Identifier( |
373 | | - from_user_id=user_id, |
374 | | - chat_id=chat_id, |
375 | | - message_id=message_id, |
376 | | - inline_message_id=inline_message_id, |
377 | | - ) |
378 | | - |
379 | | - loop = asyncio.get_event_loop() |
380 | | - future = loop.create_future() |
381 | | - |
382 | | - listener = Listener( |
383 | | - future=future, |
384 | | - filters=filters, |
385 | | - unallowed_click_alert=unallowed_click_alert, |
386 | | - identifier=pattern, |
387 | | - listener_type=listener_type, |
388 | | - ) |
389 | | - |
390 | | - future.add_done_callback(lambda _future: self.remove_listener(listener)) |
391 | | - |
392 | | - self.listeners[listener_type].append(listener) |
393 | | - |
394 | | - try: |
395 | | - return await asyncio.wait_for(future, timeout) |
396 | | - except asyncio.exceptions.TimeoutError: |
397 | | - if callable(PyromodConfig.timeout_handler): |
398 | | - if inspect.iscoroutinefunction(PyromodConfig.timeout_handler.__call__): |
399 | | - await PyromodConfig.timeout_handler(pattern, listener, timeout) |
400 | | - else: |
401 | | - await self.loop.run_in_executor( |
402 | | - None, PyromodConfig.timeout_handler, pattern, listener, timeout |
403 | | - ) |
404 | | - elif PyromodConfig.throw_exceptions: |
405 | | - raise ListenerTimeout(timeout) |
406 | | - |
407 | | - async def ask( |
408 | | - self, |
409 | | - chat_id: Union[Union[int, str], list[Union[int, str]]], |
410 | | - text: str, |
411 | | - filters: Optional[Filter] = None, |
412 | | - listener_type: ListenerTypes = ListenerTypes.MESSAGE, |
413 | | - timeout: Optional[int] = None, |
414 | | - unallowed_click_alert: bool = True, |
415 | | - user_id: Optional[Union[Union[int, str], list[Union[int, str]]]] = None, |
416 | | - message_id: Optional[Union[int, list[int]]] = None, |
417 | | - inline_message_id: Optional[Union[str, list[str]]] = None, |
418 | | - *args, |
419 | | - **kwargs, |
420 | | - ): |
421 | | - """ |
422 | | - Sends a message and waits for a response. |
423 | | -
|
424 | | - :param chat_id: The chat ID(s) to wait for a message from. The first chat ID will be used to send the message. |
425 | | - :param text: The text to send. |
426 | | - :param filters: Same as :meth:`pyromod.types.Client.listen`. |
427 | | - :param listener_type: Same as :meth:`pyromod.types.Client.listen`. |
428 | | - :param timeout: Same as :meth:`pyromod.types.Client.listen`. |
429 | | - :param unallowed_click_alert: Same as :meth:`pyromod.types.Client.listen`. |
430 | | - :param user_id: Same as :meth:`pyromod.types.Client.listen`. |
431 | | - :param message_id: Same as :meth:`pyromod.types.Client.listen`. |
432 | | - :param inline_message_id: Same as :meth:`pyromod.types.Client.listen`. |
433 | | - :param args: Additional arguments to pass to :meth:`hydrogram.Client.send_message`. |
434 | | - :param kwargs: Additional keyword arguments to pass to :meth:`hydrogram.Client.send_message`. |
435 | | - :return: |
436 | | - Same as :meth:`pyromod.types.Client.listen`. The sent message is returned as the attribute ``sent_message``. |
437 | | - """ |
438 | | - sent_message = None |
439 | | - if text.strip() != "": |
440 | | - chat_to_ask = chat_id[0] if isinstance(chat_id, list) else chat_id |
441 | | - sent_message = await self.send_message(chat_to_ask, text, *args, **kwargs) |
442 | | - |
443 | | - response = await self.listen( |
444 | | - filters=filters, |
445 | | - listener_type=listener_type, |
446 | | - timeout=timeout, |
447 | | - unallowed_click_alert=unallowed_click_alert, |
448 | | - chat_id=chat_id, |
449 | | - user_id=user_id, |
450 | | - message_id=message_id, |
451 | | - inline_message_id=inline_message_id, |
452 | | - ) |
453 | | - if response: |
454 | | - response.sent_message = sent_message |
455 | | - |
456 | | - return response |
457 | | - |
458 | | - def remove_listener(self, listener: Listener): |
459 | | - """ |
460 | | - Removes a listener from the :meth:`pyromod.types.Client.listeners` dictionary. |
461 | | -
|
462 | | - :param listener: The listener to remove. |
463 | | - :return: ``void`` |
464 | | - """ |
465 | | - with contextlib.suppress(ValueError): |
466 | | - self.listeners[listener.listener_type].remove(listener) |
467 | | - |
468 | | - def get_listener_matching_with_data( |
469 | | - self, data: Identifier, listener_type: ListenerTypes |
470 | | - ) -> Optional[Listener]: |
471 | | - """ |
472 | | - Gets a listener that matches the given data. |
473 | | -
|
474 | | - :param data: A :class:`pyromod.types.Identifier` to match against. |
475 | | - :param listener_type: The type of listener to get. Must be a value from :class:`pyromod.types.ListenerTypes`. |
476 | | - :return: The listener that matches the given data or ``None`` if no listener matches. |
477 | | - """ |
478 | | - matching = [ |
479 | | - listener |
480 | | - for listener in self.listeners[listener_type] |
481 | | - if listener.identifier.matches(data) |
482 | | - ] |
483 | | - |
484 | | - # in case of multiple matching listeners, the most specific should be returned |
485 | | - def count_populated_attributes(listener_item: Listener): |
486 | | - return listener_item.identifier.count_populated() |
487 | | - |
488 | | - return max(matching, key=count_populated_attributes, default=None) |
489 | | - |
490 | | - def get_listener_matching_with_identifier_pattern( |
491 | | - self, pattern: Identifier, listener_type: ListenerTypes |
492 | | - ) -> Optional[Listener]: |
493 | | - """ |
494 | | - Gets a listener that matches the given identifier pattern. |
495 | | -
|
496 | | - The difference from :meth:`pyromod.types.Client.get_listener_matching_with_data` is that this method |
497 | | - intends to get a listener by passing partial info of the listener identifier, while the other method |
498 | | - intends to get a listener by passing the full info of the update data, which the listener should match with. |
499 | | -
|
500 | | - :param pattern: A :class:`pyromod.types.Identifier` to match against. |
501 | | - :param listener_type: The type of listener to get. Must be a value from :class:`pyromod.types.ListenerTypes`. |
502 | | - :return: The listener that matches the given identifier pattern or ``None`` if no listener matches. |
503 | | - """ |
504 | | - matching = [ |
505 | | - listener |
506 | | - for listener in self.listeners[listener_type] |
507 | | - if pattern.matches(listener.identifier) |
508 | | - ] |
509 | | - |
510 | | - # in case of multiple matching listeners, the most specific should be returned |
511 | | - |
512 | | - def count_populated_attributes(listener_item: Listener): |
513 | | - return listener_item.identifier.count_populated() |
514 | | - |
515 | | - return max(matching, key=count_populated_attributes, default=None) |
516 | | - |
517 | | - def get_many_listeners_matching_with_data( |
518 | | - self, |
519 | | - data: Identifier, |
520 | | - listener_type: ListenerTypes, |
521 | | - ) -> list[Listener]: |
522 | | - """ |
523 | | - Same of :meth:`pyromod.types.Client.get_listener_matching_with_data` but returns a list of listeners instead of one. |
524 | | -
|
525 | | - :param data: Same as :meth:`pyromod.types.Client.get_listener_matching_with_data`. |
526 | | - :param listener_type: Same as :meth:`pyromod.types.Client.get_listener_matching_with_data`. |
527 | | - :return: A list of listeners that match the given data. |
528 | | - """ |
529 | | - return [ |
530 | | - listener |
531 | | - for listener in self.listeners[listener_type] |
532 | | - if listener.identifier.matches(data) |
533 | | - ] |
534 | | - |
535 | | - def get_many_listeners_matching_with_identifier_pattern( |
536 | | - self, |
537 | | - pattern: Identifier, |
538 | | - listener_type: ListenerTypes, |
539 | | - ) -> list[Listener]: |
540 | | - """ |
541 | | - Same of :meth:`pyromod.types.Client.get_listener_matching_with_identifier_pattern` but returns a list of listeners instead of one. |
542 | | -
|
543 | | - :param pattern: Same as :meth:`pyromod.types.Client.get_listener_matching_with_identifier_pattern`. |
544 | | - :param listener_type: Same as :meth:`pyromod.types.Client.get_listener_matching_with_identifier_pattern`. |
545 | | - :return: A list of listeners that match the given identifier pattern. |
546 | | - """ |
547 | | - return [ |
548 | | - listener |
549 | | - for listener in self.listeners[listener_type] |
550 | | - if pattern.matches(listener.identifier) |
551 | | - ] |
552 | | - |
553 | | - async def stop_listening( |
554 | | - self, |
555 | | - listener_type: ListenerTypes = ListenerTypes.MESSAGE, |
556 | | - chat_id: Optional[Union[Union[int, str], list[Union[int, str]]]] = None, |
557 | | - user_id: Optional[Union[Union[int, str], list[Union[int, str]]]] = None, |
558 | | - message_id: Optional[Union[int, list[int]]] = None, |
559 | | - inline_message_id: Optional[Union[str, list[str]]] = None, |
560 | | - ): |
561 | | - """ |
562 | | - Stops all listeners that match the given identifier pattern. |
563 | | - Uses :meth:`pyromod.types.Client.get_many_listeners_matching_with_identifier_pattern`. |
564 | | -
|
565 | | - :param listener_type: The type of listener to stop. Must be a value from :class:`pyromod.types.ListenerTypes`. |
566 | | - :param chat_id: The chat_id to match against. |
567 | | - :param user_id: The user_id to match against. |
568 | | - :param message_id: The message_id to match against. |
569 | | - :param inline_message_id: The inline_message_id to match against. |
570 | | - :return: ``void`` |
571 | | - """ |
572 | | - pattern = Identifier( |
573 | | - from_user_id=user_id, |
574 | | - chat_id=chat_id, |
575 | | - message_id=message_id, |
576 | | - inline_message_id=inline_message_id, |
577 | | - ) |
578 | | - listeners = self.get_many_listeners_matching_with_identifier_pattern( |
579 | | - pattern, listener_type |
580 | | - ) |
581 | | - |
582 | | - for listener in listeners: |
583 | | - await self.stop_listener(listener) |
584 | | - |
585 | | - async def stop_listener(self, listener: Listener): |
586 | | - """ |
587 | | - Stops a listener, calling stopped_handler if applicable or raising ListenerStopped if throw_exceptions is True. |
588 | | -
|
589 | | - :param listener: The :class:`pyromod.types.Listener` to stop. |
590 | | - :return: ``void`` |
591 | | - :raises ListenerStopped: If throw_exceptions is True. |
592 | | - """ |
593 | | - self.remove_listener(listener) |
594 | | - |
595 | | - if listener.future.done(): |
596 | | - return |
597 | | - |
598 | | - if callable(PyromodConfig.stopped_handler): |
599 | | - if inspect.iscoroutinefunction(PyromodConfig.stopped_handler.__call__): |
600 | | - await PyromodConfig.stopped_handler(None, listener) |
601 | | - else: |
602 | | - await self.loop.run_in_executor( |
603 | | - None, PyromodConfig.stopped_handler, None, listener |
604 | | - ) |
605 | | - elif PyromodConfig.throw_exceptions: |
606 | | - listener.future.set_exception(ListenerStopped()) |
607 | | - |
608 | | - def register_next_step_handler( |
609 | | - self, |
610 | | - callback: Callable, |
611 | | - filters: Optional[Filter] = None, |
612 | | - listener_type: ListenerTypes = ListenerTypes.MESSAGE, |
613 | | - unallowed_click_alert: bool = True, |
614 | | - chat_id: Optional[Union[Union[int, str], list[Union[int, str]]]] = None, |
615 | | - user_id: Optional[Union[Union[int, str], list[Union[int, str]]]] = None, |
616 | | - message_id: Optional[Union[int, list[int]]] = None, |
617 | | - inline_message_id: Optional[Union[str, list[str]]] = None, |
618 | | - ): |
619 | | - """ |
620 | | - Registers a listener with a callback to be called when the listener is fulfilled. |
621 | | -
|
622 | | - :param callback: The callback to call when the listener is fulfilled. |
623 | | - :param filters: Same as :meth:`pyromod.types.Client.listen`. |
624 | | - :param listener_type: Same as :meth:`pyromod.types.Client.listen`. |
625 | | - :param unallowed_click_alert: Same as :meth:`pyromod.types.Client.listen`. |
626 | | - :param chat_id: Same as :meth:`pyromod.types.Client.listen`. |
627 | | - :param user_id: Same as :meth:`pyromod.types.Client.listen`. |
628 | | - :param message_id: Same as :meth:`pyromod.types.Client.listen`. |
629 | | - :param inline_message_id: Same as :meth:`pyromod.types.Client.listen`. |
630 | | - :return: ``void`` |
631 | | - """ |
632 | | - pattern = Identifier( |
633 | | - from_user_id=user_id, |
634 | | - chat_id=chat_id, |
635 | | - message_id=message_id, |
636 | | - inline_message_id=inline_message_id, |
637 | | - ) |
638 | | - |
639 | | - listener = Listener( |
640 | | - callback=callback, |
641 | | - filters=filters, |
642 | | - unallowed_click_alert=unallowed_click_alert, |
643 | | - identifier=pattern, |
644 | | - listener_type=listener_type, |
645 | | - ) |
646 | | - |
647 | | - self.listeners[listener_type].append(listener) |
648 | | - |
649 | 345 | async def authorize(self) -> User: |
650 | 346 | if self.bot_token: |
651 | 347 | return await self.sign_in_bot(self.bot_token) |
|
0 commit comments