mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-06-02 04:33:24 +03:00
Support exclusive conversations by default
This commit is contained in:
parent
cf6686ff42
commit
0094eb391e
|
@ -160,7 +160,7 @@ class DialogMethods(UserMethods):
|
||||||
def conversation(
|
def conversation(
|
||||||
self, entity,
|
self, entity,
|
||||||
*, timeout=None, total_timeout=60, max_messages=100,
|
*, timeout=None, total_timeout=60, max_messages=100,
|
||||||
replies_are_responses=True):
|
exclusive=True, replies_are_responses=True):
|
||||||
"""
|
"""
|
||||||
Creates a `Conversation <telethon.tl.custom.conversation.Conversation>`
|
Creates a `Conversation <telethon.tl.custom.conversation.Conversation>`
|
||||||
with the given entity so you can easily send messages and await for
|
with the given entity so you can easily send messages and await for
|
||||||
|
@ -187,6 +187,16 @@ class DialogMethods(UserMethods):
|
||||||
specified chat, subsequent actions will result in
|
specified chat, subsequent actions will result in
|
||||||
``ValueError``.
|
``ValueError``.
|
||||||
|
|
||||||
|
exclusive (`bool`, optional):
|
||||||
|
By default, conversations are exclusive within a single
|
||||||
|
chat. That means that while a conversation is open in a
|
||||||
|
chat, you can't open another one in the same chat, unless
|
||||||
|
you disable this flag.
|
||||||
|
|
||||||
|
If you try opening an exclusive conversation for
|
||||||
|
a chat where it's already open, it will raise
|
||||||
|
``AlreadyInConversationError``.
|
||||||
|
|
||||||
replies_are_responses (`bool`, optional):
|
replies_are_responses (`bool`, optional):
|
||||||
Whether replies should be treated as responses or not.
|
Whether replies should be treated as responses or not.
|
||||||
|
|
||||||
|
@ -229,6 +239,7 @@ class DialogMethods(UserMethods):
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
total_timeout=total_timeout,
|
total_timeout=total_timeout,
|
||||||
max_messages=max_messages,
|
max_messages=max_messages,
|
||||||
|
exclusive=exclusive,
|
||||||
replies_are_responses=replies_are_responses
|
replies_are_responses=replies_are_responses
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -272,6 +272,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
# Some further state for subclasses
|
# Some further state for subclasses
|
||||||
self._event_builders = []
|
self._event_builders = []
|
||||||
self._conversations = {}
|
self._conversations = {}
|
||||||
|
self._ids_in_conversations = {} # chat_id: count
|
||||||
|
|
||||||
# Default parse mode
|
# Default parse mode
|
||||||
self._parse_mode = markdown
|
self._parse_mode = markdown
|
||||||
|
|
|
@ -283,6 +283,10 @@ class UpdateMethods(UserMethods):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await callback(event)
|
await callback(event)
|
||||||
|
except errors.AlreadyInConversationError:
|
||||||
|
name = getattr(callback, '__name__', repr(callback))
|
||||||
|
__log__.debug('Event handler "%s" already has an open '
|
||||||
|
'conversation, ignoring new one', name)
|
||||||
except events.StopPropagation:
|
except events.StopPropagation:
|
||||||
name = getattr(callback, '__name__', repr(callback))
|
name = getattr(callback, '__name__', repr(callback))
|
||||||
__log__.debug(
|
__log__.debug(
|
||||||
|
|
|
@ -8,7 +8,8 @@ from threading import Thread
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
ReadCancelledError, TypeNotFoundError, InvalidChecksumError,
|
ReadCancelledError, TypeNotFoundError, InvalidChecksumError,
|
||||||
InvalidBufferError, SecurityError, CdnFileTamperedError, MultiError
|
InvalidBufferError, SecurityError, CdnFileTamperedError,
|
||||||
|
AlreadyInConversationError, MultiError
|
||||||
)
|
)
|
||||||
|
|
||||||
# This imports the base errors too, as they're imported there
|
# This imports the base errors too, as they're imported there
|
||||||
|
|
|
@ -79,6 +79,17 @@ class CdnFileTamperedError(SecurityError):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AlreadyInConversationError(Exception):
|
||||||
|
"""
|
||||||
|
Occurs when another exclusive conversation is opened in the same chat.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(
|
||||||
|
'Cannot open exclusive conversation in a '
|
||||||
|
'chat that already has one open conversation'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MultiError(Exception):
|
class MultiError(Exception):
|
||||||
"""Exception container for multiple `TLRequest`'s."""
|
"""Exception container for multiple `TLRequest`'s."""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import itertools
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from .chatgetter import ChatGetter
|
from .chatgetter import ChatGetter
|
||||||
from ... import utils
|
from ... import utils, errors
|
||||||
|
|
||||||
|
|
||||||
class Conversation(ChatGetter):
|
class Conversation(ChatGetter):
|
||||||
|
@ -23,7 +23,7 @@ class Conversation(ChatGetter):
|
||||||
|
|
||||||
def __init__(self, client, input_chat,
|
def __init__(self, client, input_chat,
|
||||||
*, timeout, total_timeout, max_messages,
|
*, timeout, total_timeout, max_messages,
|
||||||
replies_are_responses):
|
exclusive, replies_are_responses):
|
||||||
self._id = Conversation._id_counter
|
self._id = Conversation._id_counter
|
||||||
Conversation._id_counter += 1
|
Conversation._id_counter += 1
|
||||||
|
|
||||||
|
@ -50,6 +50,8 @@ class Conversation(ChatGetter):
|
||||||
self._pending_edits = {}
|
self._pending_edits = {}
|
||||||
self._pending_reads = {}
|
self._pending_reads = {}
|
||||||
|
|
||||||
|
self._exclusive = exclusive
|
||||||
|
|
||||||
# The user is able to expect two responses for the same message.
|
# The user is able to expect two responses for the same message.
|
||||||
# {desired message ID: next incoming index}
|
# {desired message ID: next incoming index}
|
||||||
self._response_indices = {}
|
self._response_indices = {}
|
||||||
|
@ -380,11 +382,20 @@ class Conversation(ChatGetter):
|
||||||
return self._client.loop.run_until_complete(self.__aenter__())
|
return self._client.loop.run_until_complete(self.__aenter__())
|
||||||
|
|
||||||
async def __aenter__(self):
|
async def __aenter__(self):
|
||||||
self._client._conversations[self._id] = self
|
|
||||||
self._input_chat = \
|
self._input_chat = \
|
||||||
await self._client.get_input_entity(self._input_chat)
|
await self._client.get_input_entity(self._input_chat)
|
||||||
|
|
||||||
self._chat_peer = utils.get_peer(self._input_chat)
|
self._chat_peer = utils.get_peer(self._input_chat)
|
||||||
|
|
||||||
|
# Make sure we're the only conversation in this chat if it's exclusive
|
||||||
|
chat_id = utils.get_peer_id(self._chat_peer)
|
||||||
|
count = self._client._ids_in_conversations.get(chat_id, 0)
|
||||||
|
if self._exclusive and count:
|
||||||
|
raise errors.AlreadyInConversationError()
|
||||||
|
|
||||||
|
self._client._ids_in_conversations[chat_id] = count + 1
|
||||||
|
self._client._conversations[self._id] = self
|
||||||
|
|
||||||
self._last_outgoing = 0
|
self._last_outgoing = 0
|
||||||
self._last_incoming = 0
|
self._last_incoming = 0
|
||||||
for d in (
|
for d in (
|
||||||
|
@ -405,5 +416,11 @@ class Conversation(ChatGetter):
|
||||||
return self._client.loop.run_until_complete(self.__aexit__(*args))
|
return self._client.loop.run_until_complete(self.__aexit__(*args))
|
||||||
|
|
||||||
async def __aexit__(self, *args):
|
async def __aexit__(self, *args):
|
||||||
|
chat_id = utils.get_peer_id(self._chat_peer)
|
||||||
|
if self._client._ids_in_conversations[chat_id] == 1:
|
||||||
|
del self._client._ids_in_conversations[chat_id]
|
||||||
|
else:
|
||||||
|
self._client._ids_in_conversations[chat_id] -= 1
|
||||||
|
|
||||||
del self._client._conversations[self._id]
|
del self._client._conversations[self._id]
|
||||||
self._cancel_all()
|
self._cancel_all()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user