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: