diff --git a/docs/source/topics/text-formatting.rst b/docs/source/topics/text-formatting.rst index 1c3d39f2e..10772e8a1 100644 --- a/docs/source/topics/text-formatting.rst +++ b/docs/source/topics/text-formatting.rst @@ -74,6 +74,8 @@ To strictly use this mode, pass :obj:`~pyrogram.enums.ParseMode.MARKDOWN` to the code block ``` + > Quoted text + **Example**: .. code-block:: python diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 77eaad0cb..2f7635719 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -18,7 +18,7 @@ # along with Pyrofork. If not, see . __fork_name__ = "PyroFork" -__version__ = "2.3.16.post2" +__version__ = "2.3.16.post3" __license__ = "GNU Lesser General Public License v3.0 (LGPL-3.0)" __copyright__ = "Copyright (C) 2022-present Mayuri-Chan " diff --git a/pyrogram/methods/chats/get_dialogs.py b/pyrogram/methods/chats/get_dialogs.py index 3509ccbcc..ccca63816 100644 --- a/pyrogram/methods/chats/get_dialogs.py +++ b/pyrogram/methods/chats/get_dialogs.py @@ -20,6 +20,7 @@ import pyrogram from pyrogram import types, raw, utils +from pyrogram.errors import ChannelPrivate class GetDialogs: @@ -76,7 +77,10 @@ async def get_dialogs( continue chat_id = utils.get_peer_id(message.peer_id) - messages[chat_id] = await types.Message._parse(self, message, users, chats) + try: + messages[chat_id] = await types.Message._parse(self, message, users, chats) + except ChannelPrivate: + continue dialogs = [] diff --git a/pyrogram/methods/users/send_story.py b/pyrogram/methods/users/send_story.py index 8ee3aed00..8808a66cf 100644 --- a/pyrogram/methods/users/send_story.py +++ b/pyrogram/methods/users/send_story.py @@ -28,6 +28,25 @@ class SendStory: def _split(self, message, entities, *args, **kwargs): return message, entities + async def _upload_video( + self: "pyrogram.Client", + file_name: str, + video: Union[str, BinaryIO] + ): + file = await self.save_file(video) + return raw.types.InputMediaUploadedDocument( + mime_type=self.guess_mime_type(file_name or video.name) or "video/mp4", + file=file, + attributes=[ + raw.types.DocumentAttributeVideo( + supports_streaming=True, + duration=0, + w=0, + h=0 + ) + ] + ) + async def send_story( self: "pyrogram.Client", chat_id: Union[int,str] = None, @@ -185,36 +204,12 @@ async def send_story( ) else: video = await self.download_media(video, in_memory=True) - file = await self.save_file(video) - media = raw.types.InputMediaUploadedDocument( - mime_type=self.guess_mime_type(file_name or video.name) or "video/mp4", - file=file, - attributes=[ - raw.types.DocumentAttributeVideo( - supports_streaming=True, - duration=0, - w=0, - h=0 - ) - ] - ) + media = await self._upload_video(file_name,video) else: - file = await self.save_file(video) - media = raw.types.InputMediaUploadedDocument( - mime_type=self.guess_mime_type(file_name or video.name) or "video/mp4", - file=file, - attributes=[ - raw.types.DocumentAttributeVideo( - supports_streaming=True, - duration=0, - w=0, - h=0 - ) - ] - ) + media = await self._upload_video(file_name,video) else: if forward_from_chat_id is None: - raise ValueError("You need to pass one of the following parameter animation/photo/video/forward_from_chat_id!") + raise ValueError("You need to pass one of the following parameter photo/video/forward_from_chat_id!") text, entities = self._split(**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)) diff --git a/pyrogram/parser/markdown.py b/pyrogram/parser/markdown.py index 6219d9583..f3f339862 100644 --- a/pyrogram/parser/markdown.py +++ b/pyrogram/parser/markdown.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . import html +import logging import re from typing import Optional @@ -32,6 +33,7 @@ SPOILER_DELIM = "||" CODE_DELIM = "`" PRE_DELIM = "```" +BLOCKQUOTE_DELIM = ">" MARKDOWN_RE = re.compile(r"({d})|\[(.+?)\]\((.+?)\)".format( d="|".join( @@ -59,9 +61,39 @@ class Markdown: def __init__(self, client: Optional["pyrogram.Client"]): self.html = HTML(client) + def blockquote_parser(self, text): + text = re.sub(r'\n>', '\n>', re.sub(r'^>', '>', text)) + lines = text.split('\n') + result = [] + + in_blockquote = False + + for line in lines: + if line.startswith(BLOCKQUOTE_DELIM): + if not in_blockquote: + line = re.sub(r'^> ', OPENING_TAG.format("blockquote"), line) + line = re.sub(r'^>', OPENING_TAG.format("blockquote"), line) + in_blockquote = True + result.append(line.strip()) + else: + result.append(line[-1].strip()) + else: + if in_blockquote: + line = CLOSING_TAG.format("blockquote") + line + in_blockquote = False + result.append(line.strip()) + + if in_blockquote: + line = result[len(result)-1] + CLOSING_TAG.format("blockquote") + result.pop(len(result)-1) + result.append(line) + + return '\n'.join(result) + async def parse(self, text: str, strict: bool = False): if strict: text = html.escape(text) + text = self.blockquote_parser(text) delims = set() is_fixed_width = False @@ -141,7 +173,21 @@ def unparse(text: str, entities: list): start_tag = f"{PRE_DELIM}{language}\n" end_tag = f"\n{PRE_DELIM}" elif entity_type == MessageEntityType.BLOCKQUOTE: - start_tag = end_tag = PRE_DELIM + start_tag = BLOCKQUOTE_DELIM + " " + end_tag = "" + blockquote_text = text[start:end] + lines = blockquote_text.split("\n") + last_length = 0 + for line in lines: + if len(line) == 0 and last_length == end: + continue + start_offset = start+last_length + last_length = last_length+len(line) + end_offset = start_offset+last_length + entities_offsets.append((start_tag, start_offset,)) + entities_offsets.append((end_tag, end_offset,)) + last_length = last_length+1 + continue elif entity_type == MessageEntityType.SPOILER: start_tag = end_tag = SPOILER_DELIM elif entity_type == MessageEntityType.TEXT_LINK: