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,
 | 
					    InputUserSelf, UserProfilePhoto, ChatPhoto, UpdateMessageID,
 | 
				
			||||||
    UpdateNewMessage, UpdateShortSentMessage
 | 
					    UpdateNewMessage, UpdateShortSentMessage
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from .tl.types.messages import DialogsSlice
 | 
				
			||||||
from .utils import find_user_or_chat, get_extension
 | 
					from .utils import find_user_or_chat, get_extension
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -224,22 +225,61 @@ class TelegramClient(TelegramBareClient):
 | 
				
			||||||
                    offset_id=0,
 | 
					                    offset_id=0,
 | 
				
			||||||
                    offset_peer=InputPeerEmpty()):
 | 
					                    offset_peer=InputPeerEmpty()):
 | 
				
			||||||
        """Returns a tuple of lists ([dialogs], [entities])
 | 
					        """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
 | 
					           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(
 | 
					        dialogs = {}  # Use Dialog.top_message as identifier to avoid dupes
 | 
				
			||||||
            GetDialogsRequest(
 | 
					        messages = {}  # Used later for sorting TODO also return these?
 | 
				
			||||||
 | 
					        entities = {}
 | 
				
			||||||
 | 
					        while len(dialogs) < limit:
 | 
				
			||||||
 | 
					            r = self(GetDialogsRequest(
 | 
				
			||||||
                offset_date=offset_date,
 | 
					                offset_date=offset_date,
 | 
				
			||||||
                offset_id=offset_id,
 | 
					                offset_id=offset_id,
 | 
				
			||||||
                offset_peer=offset_peer,
 | 
					                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 (
 | 
					        return (
 | 
				
			||||||
            r.dialogs,
 | 
					            dialogs,
 | 
				
			||||||
            [find_user_or_chat(d.peer, r.users, r.chats) for d in r.dialogs])
 | 
					            [find_user_or_chat(d.peer, entities, entities) for d in dialogs]
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # endregion
 | 
					    # endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -302,24 +302,23 @@ def get_input_media(media, user_caption=None, is_photo=False):
 | 
				
			||||||
def find_user_or_chat(peer, users, chats):
 | 
					def find_user_or_chat(peer, users, chats):
 | 
				
			||||||
    """Finds the corresponding user or chat given a peer.
 | 
					    """Finds the corresponding user or chat given a peer.
 | 
				
			||||||
       Returns None if it was not found"""
 | 
					       Returns None if it was not found"""
 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
    if isinstance(peer, PeerUser):
 | 
					    if isinstance(peer, PeerUser):
 | 
				
			||||||
            return next(u for u in users if u.id == peer.user_id)
 | 
					        peer, where = peer.user_id, users
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
        elif isinstance(peer, PeerChat):
 | 
					        where = chats
 | 
				
			||||||
            return next(c for c in chats if c.id == peer.chat_id)
 | 
					        if isinstance(peer, PeerChat):
 | 
				
			||||||
 | 
					            peer = peer.chat_id
 | 
				
			||||||
        elif isinstance(peer, PeerChannel):
 | 
					        elif isinstance(peer, PeerChannel):
 | 
				
			||||||
            return next(c for c in chats if c.id == peer.channel_id)
 | 
					            peer = peer.channel_id
 | 
				
			||||||
 | 
					 | 
				
			||||||
    except StopIteration: return
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if isinstance(peer, int):
 | 
					    if isinstance(peer, int):
 | 
				
			||||||
        try: return next(u for u in users if u.id == peer)
 | 
					        if isinstance(where, dict):
 | 
				
			||||||
        except StopIteration: pass
 | 
					            return where.get(peer)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
        try: return next(c for c in chats if c.id == peer)
 | 
					            try:
 | 
				
			||||||
        except StopIteration: pass
 | 
					                return next(x for x in where if x.id == peer)
 | 
				
			||||||
 | 
					            except StopIteration:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_appropriated_part_size(file_size):
 | 
					def get_appropriated_part_size(file_size):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user