mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-11-04 01:47:27 +03:00 
			
		
		
		
	Add support to get all dialogs at once
This commit is contained in:
		
							parent
							
								
									06bb09b95c
								
							
						
					
					
						commit
						68e7d481f4
					
				| 
						 | 
				
			
			@ -41,6 +41,7 @@ from .tl.types import (
 | 
			
		|||
    InputUserSelf, UserProfilePhoto, ChatPhoto, UpdateMessageID,
 | 
			
		||||
    UpdateNewMessage, UpdateShortSentMessage
 | 
			
		||||
)
 | 
			
		||||
from .tl.types.messages import DialogsSlice
 | 
			
		||||
from .utils import find_user_or_chat, get_extension
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -224,22 +225,61 @@ class TelegramClient(TelegramBareClient):
 | 
			
		|||
                    offset_id=0,
 | 
			
		||||
                    offset_peer=InputPeerEmpty()):
 | 
			
		||||
        """Returns a tuple of lists ([dialogs], [entities])
 | 
			
		||||
           with at least 'limit' items each.
 | 
			
		||||
           with at least 'limit' items each unless all dialogs were consumed.
 | 
			
		||||
 | 
			
		||||
           If `limit` is None, all dialogs will be retrieved (from the given
 | 
			
		||||
           offset) will be retrieved.
 | 
			
		||||
 | 
			
		||||
           If `limit` is 0, all dialogs will (should) retrieved.
 | 
			
		||||
           The `entities` represent the user, chat or channel
 | 
			
		||||
           corresponding to that dialog.
 | 
			
		||||
           corresponding to that dialog. If it's an integer, not
 | 
			
		||||
           all dialogs may be retrieved at once.
 | 
			
		||||
        """
 | 
			
		||||
        if limit is None:
 | 
			
		||||
            limit = float('inf')
 | 
			
		||||
 | 
			
		||||
        r = self(
 | 
			
		||||
            GetDialogsRequest(
 | 
			
		||||
        dialogs = {}  # Use Dialog.top_message as identifier to avoid dupes
 | 
			
		||||
        messages = {}  # Used later for sorting TODO also return these?
 | 
			
		||||
        entities = {}
 | 
			
		||||
        while len(dialogs) < limit:
 | 
			
		||||
            r = self(GetDialogsRequest(
 | 
			
		||||
                offset_date=offset_date,
 | 
			
		||||
                offset_id=offset_id,
 | 
			
		||||
                offset_peer=offset_peer,
 | 
			
		||||
                limit=limit))
 | 
			
		||||
                limit=0  # limit 0 often means "as much as possible"
 | 
			
		||||
            ))
 | 
			
		||||
            if not r.dialogs:
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
            for d in r.dialogs:
 | 
			
		||||
                dialogs[d.top_message] = d
 | 
			
		||||
            for m in r.messages:
 | 
			
		||||
                messages[m.id] = m
 | 
			
		||||
 | 
			
		||||
            # We assume users can't have the same ID as a chat
 | 
			
		||||
            for u in r.users:
 | 
			
		||||
                entities[u.id] = u
 | 
			
		||||
            for c in r.chats:
 | 
			
		||||
                entities[c.id] = c
 | 
			
		||||
 | 
			
		||||
            if isinstance(r, DialogsSlice):
 | 
			
		||||
                # Don't enter next iteration if we already got all
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
            offset_date = r.messages[-1].date
 | 
			
		||||
            offset_peer = find_user_or_chat(r.dialogs[-1].peer, entities,
 | 
			
		||||
                                            entities)
 | 
			
		||||
            offset_id = r.messages[-1].id & 4294967296  # Telegram/danog magic
 | 
			
		||||
 | 
			
		||||
        # Sort by message date
 | 
			
		||||
        no_date = datetime.fromtimestamp(0)
 | 
			
		||||
        dialogs = sorted(
 | 
			
		||||
            list(dialogs.values()),
 | 
			
		||||
            key=lambda d: getattr(messages[d.top_message], 'date', no_date)
 | 
			
		||||
        )
 | 
			
		||||
        return (
 | 
			
		||||
            r.dialogs,
 | 
			
		||||
            [find_user_or_chat(d.peer, r.users, r.chats) for d in r.dialogs])
 | 
			
		||||
            dialogs,
 | 
			
		||||
            [find_user_or_chat(d.peer, entities, entities) for d in dialogs]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    # endregion
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -302,24 +302,23 @@ def get_input_media(media, user_caption=None, is_photo=False):
 | 
			
		|||
def find_user_or_chat(peer, users, chats):
 | 
			
		||||
    """Finds the corresponding user or chat given a peer.
 | 
			
		||||
       Returns None if it was not found"""
 | 
			
		||||
    try:
 | 
			
		||||
        if isinstance(peer, PeerUser):
 | 
			
		||||
            return next(u for u in users if u.id == peer.user_id)
 | 
			
		||||
 | 
			
		||||
        elif isinstance(peer, PeerChat):
 | 
			
		||||
            return next(c for c in chats if c.id == peer.chat_id)
 | 
			
		||||
 | 
			
		||||
    if isinstance(peer, PeerUser):
 | 
			
		||||
        peer, where = peer.user_id, users
 | 
			
		||||
    else:
 | 
			
		||||
        where = chats
 | 
			
		||||
        if isinstance(peer, PeerChat):
 | 
			
		||||
            peer = peer.chat_id
 | 
			
		||||
        elif isinstance(peer, PeerChannel):
 | 
			
		||||
            return next(c for c in chats if c.id == peer.channel_id)
 | 
			
		||||
 | 
			
		||||
    except StopIteration: return
 | 
			
		||||
            peer = peer.channel_id
 | 
			
		||||
 | 
			
		||||
    if isinstance(peer, int):
 | 
			
		||||
        try: return next(u for u in users if u.id == peer)
 | 
			
		||||
        except StopIteration: pass
 | 
			
		||||
 | 
			
		||||
        try: return next(c for c in chats if c.id == peer)
 | 
			
		||||
        except StopIteration: pass
 | 
			
		||||
        if isinstance(where, dict):
 | 
			
		||||
            return where.get(peer)
 | 
			
		||||
        else:
 | 
			
		||||
            try:
 | 
			
		||||
                return next(x for x in where if x.id == peer)
 | 
			
		||||
            except StopIteration:
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_appropriated_part_size(file_size):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user