async def resolve_and_set_join_as(self, join_as): my_peer = await self.get_and_set_self_peer() if join_as is None: self.join_as = self.full_chat.groupcall_default_join_as if self.join_as: # convert Peer to InputPeer self.join_as = await self.client.resolve_peer(get_peer_id(self.join_as)) else: self.join_as = my_peer elif isinstance(join_as, str) or isinstance(join_as, int): self.join_as = await self.client.resolve_peer(join_as) else: self.join_as = join_as
async def get_dialogs( self, offset_date: int = 0, limit: int = 100, pinned_only: bool = False ) -> List["types.Dialog"]: """Get a chunk of the user's dialogs. You can get up to 100 dialogs at once. For a more convenient way of getting a user's dialogs see :meth:`~pyrogram.Client.iter_dialogs`. Parameters: offset_date (``int``): The offset date in Unix time taken from the top message of a :obj:`~pyrogram.types.Dialog`. Defaults to 0. Valid for non-pinned dialogs only. limit (``str``, *optional*): Limits the number of dialogs to be retrieved. Defaults to 100. Valid for non-pinned dialogs only. pinned_only (``bool``, *optional*): Pass True if you want to get only pinned dialogs. Defaults to False. Returns: List of :obj:`~pyrogram.types.Dialog`: On success, a list of dialogs is returned. Example: .. code-block:: python # Get first 100 dialogs app.get_dialogs() # Get pinned dialogs app.get_dialogs(pinned_only=True) """ if pinned_only: r = await self.send( raw.functions.messages.GetPinnedDialogs(folder_id=0), sleep_threshold=60 ) else: r = await self.send( raw.functions.messages.GetDialogs( offset_date=offset_date, offset_id=0, offset_peer=raw.types.InputPeerEmpty(), limit=limit, hash=0, exclude_pinned=True ), sleep_threshold=60 ) users = {i.id: i for i in r.users} chats = {i.id: i for i in r.chats} messages = {} for message in r.messages: to_id = message.to_id if isinstance(to_id, raw.types.PeerUser): if message.out: chat_id = to_id.user_id else: chat_id = message.from_id else: chat_id = utils.get_peer_id(to_id) messages[chat_id] = await types.Message._parse(self, message, users, chats) parsed_dialogs = [] for dialog in r.dialogs: if not isinstance(dialog, raw.types.Dialog): continue parsed_dialogs.append(types.Dialog._parse(self, dialog, messages, users, chats)) return types.List(parsed_dialogs)
async def _stream_handler(self, request: Request) -> typing.Optional[Response]: _message_id: str = request.match_info["message_id"] if not _message_id.isdigit(): return Response(status=401) _token: str = request.match_info["token"] if not _token.isdigit(): return Response(status=401) token = int(_token) del _token message_id = int(_message_id) del _message_id local_token = serialize_token(message_id, token) if not self._check_local_token(local_token): return Response(status=403) range_header = request.headers.get("Range") if range_header is None: offset = 0 data_to_skip = False max_size = None else: try: offset, data_to_skip, max_size = parse_http_range( range_header, self._config.block_size) except ValueError: return Response(status=400) if data_to_skip > self._config.block_size: return Response(status=500) try: message = await self._mtproto.get_message(int(message_id)) except ValueError: return Response(status=404) if not isinstance(message.media, MessageMediaDocument): return Response(status=404) if not isinstance(message.media.document, Document): return Response(status=404) size = message.media.document.size read_after = offset + data_to_skip if read_after > size: return Response(status=400) if (max_size is not None) and (size < max_size): return Response(status=400) if max_size is None: max_size = size stream = StreamResponse( status=206 if (read_after or (max_size != size)) else 200) self._write_http_range_headers(stream, read_after, size, max_size) try: filename = mtproto_filename(message) except TypeError: filename = f"file_{message.media.document.id}" self._write_filename_header(stream, filename) self._write_access_control_headers(stream) await stream.prepare(request) while offset < max_size: self._feed_timeout(message_id, get_peer_id(message.peer_id), local_token, size) block = await self._mtproto.get_block(message, offset, self._config.block_size) new_offset = offset + len(block) if data_to_skip: block = block[data_to_skip:] data_to_skip = False if new_offset > max_size: block = block[:-(new_offset - max_size)] if request.transport is None: break self._feed_stream_transport(local_token, request.transport) if request.transport.is_closing(): break await stream.write(block) self._feed_downloaded_blocks(offset, local_token) offset = new_offset await stream.write_eof()
async def iter_dialogs( self, limit: int = 0) -> Optional[AsyncGenerator["types.Dialog", None]]: """Iterate through a user's dialogs sequentially. This convenience method does the same as repeatedly calling :meth:`~pyrogram.Client.get_dialogs` in a loop, thus saving you from the hassle of setting up boilerplate code. It is useful for getting the whole dialogs list with a single call. Parameters: limit (``int``, *optional*): Limits the number of dialogs to be retrieved. By default, no limit is applied and all dialogs are returned. Returns: ``Generator``: A generator yielding :obj:`~pyrogram.types.Dialog` objects. Example: .. code-block:: python # Iterate through all dialogs for dialog in app.iter_dialogs(): print(dialog.chat.first_name or dialog.chat.title) """ current = 0 total = limit or (1 << 31) - 1 limit = min(100, total) offset_date = 0 offset_id = 0 offset_peer = raw.types.InputPeerEmpty() while True: r = (await self.send(raw.functions.messages.GetDialogs( offset_date=offset_date, offset_id=offset_id, offset_peer=offset_peer, limit=limit, hash=0), sleep_threshold=60)) users = {i.id: i for i in r.users} chats = {i.id: i for i in r.chats} messages = {} for message in r.messages: if isinstance(message, raw.types.MessageEmpty): continue chat_id = utils.get_peer_id(message.peer_id) messages[chat_id] = await types.Message._parse( self, message, users, chats) dialogs = [] for dialog in r.dialogs: if not isinstance(dialog, raw.types.Dialog): continue dialogs.append( types.Dialog._parse(self, dialog, messages, users, chats)) if not dialogs: return last = dialogs[-1] offset_id = last.top_message.message_id offset_date = last.top_message.date offset_peer = await self.resolve_peer(last.chat.id) for dialog in dialogs: yield dialog current += 1 if current >= total: return
async def get_dialogs( self: "pyrogram.Client", limit: int = 0 ) -> Optional[AsyncGenerator["types.Dialog", None]]: """Get a user's dialogs sequentially. Parameters: limit (``int``, *optional*): Limits the number of dialogs to be retrieved. By default, no limit is applied and all dialogs are returned. Returns: ``Generator``: A generator yielding :obj:`~pyrogram.types.Dialog` objects. Example: .. code-block:: python # Iterate through all dialogs async for dialog in app.get_dialogs(): print(dialog.chat.first_name or dialog.chat.title) """ current = 0 total = limit or (1 << 31) - 1 limit = min(100, total) offset_date = 0 offset_id = 0 offset_peer = raw.types.InputPeerEmpty() while True: r = await self.invoke( raw.functions.messages.GetDialogs( offset_date=offset_date, offset_id=offset_id, offset_peer=offset_peer, limit=limit, hash=0 ), sleep_threshold=60 ) users = {i.id: i for i in r.users} chats = {i.id: i for i in r.chats} messages = {} for message in r.messages: if isinstance(message, raw.types.MessageEmpty): continue chat_id = utils.get_peer_id(message.peer_id) messages[chat_id] = await types.Message._parse(self, message, users, chats) dialogs = [] for dialog in r.dialogs: if not isinstance(dialog, raw.types.Dialog): continue dialogs.append(types.Dialog._parse(self, dialog, messages, users, chats)) if not dialogs: return last = dialogs[-1] offset_id = last.top_message.id offset_date = utils.datetime_to_timestamp(last.top_message.date) offset_peer = await self.resolve_peer(last.chat.id) for dialog in dialogs: yield dialog current += 1 if current >= total: return