Add support for manual text entities.

This commit is contained in:
Dan 2020-11-29 15:48:29 +01:00
parent 72db61a416
commit 384f4eba71
18 changed files with 270 additions and 59 deletions

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from typing import Union, List
from pyrogram import types
from pyrogram.scaffold import Scaffold
@ -29,6 +29,7 @@ class EditMessageCaption(Scaffold):
message_id: int,
caption: str,
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
reply_markup: "types.InlineKeyboardMarkup" = None
) -> "types.Message":
"""Edit the caption of media messages.
@ -52,6 +53,9 @@ class EditMessageCaption(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup`, *optional*):
An InlineKeyboardMarkup object.
@ -68,5 +72,6 @@ class EditMessageCaption(Scaffold):
message_id=message_id,
text=caption,
parse_mode=parse_mode,
entities=caption_entities,
reply_markup=reply_markup
)

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from typing import Union, List
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
from pyrogram.scaffold import Scaffold
@ -30,6 +31,7 @@ class EditMessageText(Scaffold):
message_id: int,
text: str,
parse_mode: Union[str, None] = object,
entities: List["types.MessageEntity"] = None,
disable_web_page_preview: bool = None,
reply_markup: "types.InlineKeyboardMarkup" = None
) -> "types.Message":
@ -54,6 +56,9 @@ class EditMessageText(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in message text, which can be specified instead of __parse_mode__.
disable_web_page_preview (``bool``, *optional*):
Disables link previews for links in this message.
@ -81,7 +86,7 @@ class EditMessageText(Scaffold):
id=message_id,
no_webpage=disable_web_page_preview or None,
reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(text, parse_mode)
**await utils.parse_text_entities(self, text, parse_mode, entities)
)
)

View File

@ -18,7 +18,7 @@
import os
import re
from typing import Union, BinaryIO
from typing import Union, BinaryIO, List
from pyrogram import StopTransmission
from pyrogram import raw
@ -37,6 +37,7 @@ class SendAnimation(Scaffold):
caption: str = "",
unsave: bool = False,
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
duration: int = 0,
width: int = 0,
height: int = 0,
@ -83,6 +84,9 @@ class SendAnimation(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of sent animation in seconds.
@ -219,7 +223,7 @@ class SendAnimation(Scaffold):
random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode)
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)
)
)
except FilePartMissing as e:

View File

@ -18,7 +18,7 @@
import os
import re
from typing import Union, BinaryIO
from typing import Union, BinaryIO, List
from pyrogram import StopTransmission
from pyrogram import raw
@ -36,10 +36,12 @@ class SendAudio(Scaffold):
audio: Union[str, BinaryIO],
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
duration: int = 0,
performer: str = None,
title: str = None,
thumb: Union[str, BinaryIO] = None, file_name: str = None,
thumb: Union[str, BinaryIO] = None,
file_name: str = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
schedule_date: int = None,
@ -79,6 +81,9 @@ class SendAudio(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of the audio in seconds.
@ -213,7 +218,7 @@ class SendAudio(Scaffold):
random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode)
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)
)
)
except FilePartMissing as e:

View File

@ -18,7 +18,7 @@
import os
import re
from typing import Union, BinaryIO
from typing import Union, BinaryIO, List
from pyrogram import StopTransmission
from pyrogram import raw
@ -37,6 +37,7 @@ class SendDocument(Scaffold):
thumb: Union[str, BinaryIO] = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
file_name: str = None,
force_document: bool = None,
disable_notification: bool = None,
@ -82,6 +83,9 @@ class SendDocument(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
file_name (``str``, *optional*):
File name of the document sent.
Defaults to file's path basename.
@ -191,7 +195,7 @@ class SendDocument(Scaffold):
random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode)
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)
)
)
except FilePartMissing as e:

View File

@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from typing import Union, List
from pyrogram import raw
from pyrogram import raw, utils
from pyrogram import types
from pyrogram.scaffold import Scaffold
@ -29,6 +29,7 @@ class SendMessage(Scaffold):
chat_id: Union[int, str],
text: str,
parse_mode: Union[str, None] = object,
entities: List["types.MessageEntity"] = None,
disable_web_page_preview: bool = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
@ -58,6 +59,9 @@ class SendMessage(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in message text, which can be specified instead of __parse_mode__.
disable_web_page_preview (``bool``, *optional*):
Disables link previews for links in this message.
@ -116,7 +120,7 @@ class SendMessage(Scaffold):
]))
"""
message, entities = (await self.parser.parse(text, parse_mode)).values()
message, entities = (await utils.parse_text_entities(self, text, parse_mode, entities)).values()
r = await self.send(
raw.functions.messages.SendMessage(

View File

@ -18,7 +18,7 @@
import os
import re
from typing import Union, BinaryIO
from typing import Union, BinaryIO, List
import pyrogram
from pyrogram import raw
@ -36,6 +36,7 @@ class SendPhoto(Scaffold):
photo: Union[str, BinaryIO],
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
ttl_seconds: int = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
@ -74,6 +75,9 @@ class SendPhoto(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
ttl_seconds (``int``, *optional*):
Self-Destruct Timer.
If you set a timer, the photo will self-destruct in *ttl_seconds*
@ -169,7 +173,7 @@ class SendPhoto(Scaffold):
random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode)
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)
)
)
except FilePartMissing as e:

View File

@ -18,7 +18,7 @@
import os
import re
from typing import Union, BinaryIO
from typing import Union, BinaryIO, List
from pyrogram import StopTransmission
from pyrogram import raw
@ -36,6 +36,7 @@ class SendVideo(Scaffold):
video: Union[str, BinaryIO],
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
duration: int = 0,
width: int = 0,
height: int = 0,
@ -79,6 +80,9 @@ class SendVideo(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of sent video in seconds.
@ -213,7 +217,7 @@ class SendVideo(Scaffold):
random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode)
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)
)
)
except FilePartMissing as e:

View File

@ -18,7 +18,7 @@
import os
import re
from typing import Union, BinaryIO
from typing import Union, BinaryIO, List
from pyrogram import StopTransmission
from pyrogram import raw
@ -36,6 +36,7 @@ class SendVoice(Scaffold):
voice: Union[str, BinaryIO],
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
duration: int = 0,
disable_notification: bool = None,
reply_to_message_id: int = None,
@ -74,6 +75,9 @@ class SendVoice(Scaffold):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of the voice message in seconds.
@ -175,7 +179,7 @@ class SendVoice(Scaffold):
random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode)
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)
)
)
except FilePartMissing as e:

View File

@ -16,6 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import List
from ..messages_and_media import MessageEntity
from ..object import Object
@ -31,9 +34,16 @@ class InputMedia(Object):
- :obj:`~pyrogram.types.InputMediaVideo`
"""
def __init__(self, media: str, caption: str, parse_mode: str):
def __init__(
self,
media: str,
caption: str = None,
parse_mode: str = None,
caption_entities: List[MessageEntity] = None
):
super().__init__()
self.media = media
self.caption = caption
self.parse_mode = parse_mode
self.caption_entities = caption_entities

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from typing import Union, List
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
class InputMediaAnimation(InputMedia):
@ -46,6 +47,9 @@ class InputMediaAnimation(InputMedia):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
width (``int``, *optional*):
Animation width.
@ -62,11 +66,12 @@ class InputMediaAnimation(InputMedia):
thumb: str = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List[MessageEntity] = None,
width: int = 0,
height: int = 0,
duration: int = 0
):
super().__init__(media, caption, parse_mode)
super().__init__(media, caption, parse_mode, caption_entities)
self.thumb = thumb
self.width = width

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from typing import Union, List
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
class InputMediaAudio(InputMedia):
@ -48,6 +49,9 @@ class InputMediaAudio(InputMedia):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of the audio in seconds
@ -64,11 +68,12 @@ class InputMediaAudio(InputMedia):
thumb: str = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List[MessageEntity] = None,
duration: int = 0,
performer: str = "",
title: str = ""
):
super().__init__(media, caption, parse_mode)
super().__init__(media, caption, parse_mode, caption_entities)
self.thumb = thumb
self.duration = duration

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from typing import Union, List
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
class InputMediaDocument(InputMedia):
@ -45,6 +46,9 @@ class InputMediaDocument(InputMedia):
Pass "markdown" or "md" to enable Markdown-style parsing only.
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
"""
def __init__(
@ -52,8 +56,9 @@ class InputMediaDocument(InputMedia):
media: str,
thumb: str = None,
caption: str = "",
parse_mode: Union[str, None] = object
parse_mode: Union[str, None] = object,
caption_entities: List[MessageEntity] = None
):
super().__init__(media, caption, parse_mode)
super().__init__(media, caption, parse_mode, caption_entities)
self.thumb = thumb

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from typing import Union, List
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
class InputMediaPhoto(InputMedia):
@ -41,12 +42,16 @@ class InputMediaPhoto(InputMedia):
Pass "markdown" or "md" to enable Markdown-style parsing only.
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
"""
def __init__(
self,
media: str,
caption: str = "",
parse_mode: Union[str, None] = object
parse_mode: Union[str, None] = object,
caption_entities: List[MessageEntity] = None
):
super().__init__(media, caption, parse_mode)
super().__init__(media, caption, parse_mode, caption_entities)

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from typing import Union, List
from .input_media import InputMedia
from ..messages_and_media import MessageEntity
class InputMediaVideo(InputMedia):
@ -48,6 +49,9 @@ class InputMediaVideo(InputMedia):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
width (``int``, *optional*):
Video width.
@ -67,12 +71,13 @@ class InputMediaVideo(InputMedia):
thumb: str = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List[MessageEntity] = None,
width: int = 0,
height: int = 0,
duration: int = 0,
supports_streaming: bool = True
):
super().__init__(media, caption, parse_mode)
super().__init__(media, caption, parse_mode, caption_entities)
self.thumb = thumb
self.width = width

View File

@ -711,6 +711,7 @@ class Message(Object, Update):
text: str,
quote: bool = None,
parse_mode: Union[str, None] = object,
entities: List["types.MessageEntity"] = None,
disable_web_page_preview: bool = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
@ -749,6 +750,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in message text, which can be specified instead of __parse_mode__.
disable_web_page_preview (``bool``, *optional*):
Disables link previews for links in this message.
@ -779,6 +783,7 @@ class Message(Object, Update):
chat_id=self.chat.id,
text=text,
parse_mode=parse_mode,
entities=entities,
disable_web_page_preview=disable_web_page_preview,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
@ -793,6 +798,7 @@ class Message(Object, Update):
quote: bool = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
duration: int = 0,
width: int = 0,
height: int = 0,
@ -846,6 +852,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of sent animation in seconds.
@ -913,6 +922,7 @@ class Message(Object, Update):
animation=animation,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
duration=duration,
width=width,
height=height,
@ -930,6 +940,7 @@ class Message(Object, Update):
quote: bool = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
duration: int = 0,
performer: str = None,
title: str = None,
@ -983,6 +994,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of the audio in seconds.
@ -1050,6 +1064,7 @@ class Message(Object, Update):
audio=audio,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
duration=duration,
performer=performer,
title=title,
@ -1067,6 +1082,7 @@ class Message(Object, Update):
quote: bool = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union[
@ -1112,6 +1128,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
disable_notification (``bool``, *optional*):
Sends the message silently.
Users will receive a notification with no sound.
@ -1140,6 +1159,7 @@ class Message(Object, Update):
file_id=file_id,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
reply_markup=reply_markup
@ -1275,6 +1295,7 @@ class Message(Object, Update):
thumb: str = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union[
@ -1330,6 +1351,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
disable_notification (``bool``, *optional*):
Sends the message silently.
Users will receive a notification with no sound.
@ -1383,6 +1407,7 @@ class Message(Object, Update):
thumb=thumb,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
reply_markup=reply_markup,
@ -1670,6 +1695,7 @@ class Message(Object, Update):
quote: bool = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
ttl_seconds: int = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
@ -1720,6 +1746,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
ttl_seconds (``int``, *optional*):
Self-Destruct Timer.
If you set a timer, the photo will self-destruct in *ttl_seconds*
@ -1777,6 +1806,7 @@ class Message(Object, Update):
photo=photo,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
ttl_seconds=ttl_seconds,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
@ -2093,6 +2123,7 @@ class Message(Object, Update):
quote: bool = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
duration: int = 0,
width: int = 0,
height: int = 0,
@ -2147,6 +2178,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of sent video in seconds.
@ -2217,6 +2251,7 @@ class Message(Object, Update):
video=video,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
duration=duration,
width=width,
height=height,
@ -2353,6 +2388,7 @@ class Message(Object, Update):
quote: bool = None,
caption: str = "",
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
duration: int = 0,
disable_notification: bool = None,
reply_to_message_id: int = None,
@ -2403,6 +2439,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
duration (``int``, *optional*):
Duration of the voice message in seconds.
@ -2458,6 +2497,7 @@ class Message(Object, Update):
voice=voice,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
duration=duration,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
@ -2470,6 +2510,7 @@ class Message(Object, Update):
self,
text: str,
parse_mode: Union[str, None] = object,
entities: List["types.MessageEntity"] = None,
disable_web_page_preview: bool = None,
reply_markup: "types.InlineKeyboardMarkup" = None
) -> "Message":
@ -2501,6 +2542,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in message text, which can be specified instead of __parse_mode__.
disable_web_page_preview (``bool``, *optional*):
Disables link previews for links in this message.
@ -2518,6 +2562,7 @@ class Message(Object, Update):
message_id=self.message_id,
text=text,
parse_mode=parse_mode,
entities=entities,
disable_web_page_preview=disable_web_page_preview,
reply_markup=reply_markup
)
@ -2528,6 +2573,7 @@ class Message(Object, Update):
self,
caption: str,
parse_mode: Union[str, None] = object,
caption_entities: List["types.MessageEntity"] = None,
reply_markup: "types.InlineKeyboardMarkup" = None
) -> "Message":
"""Bound method *edit_caption* of :obj:`~pyrogram.types.Message`.
@ -2558,6 +2604,9 @@ class Message(Object, Update):
Pass "html" to enable HTML-style parsing only.
Pass None to completely disable style parsing.
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
List of special entities that appear in the caption, which can be specified instead of __parse_mode__.
reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup`, *optional*):
An InlineKeyboardMarkup object.
@ -2572,6 +2621,7 @@ class Message(Object, Update):
message_id=self.message_id,
caption=caption,
parse_mode=parse_mode,
caption_entities=caption_entities,
reply_markup=reply_markup
)

View File

@ -16,12 +16,60 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from enum import Enum, auto
import pyrogram
from pyrogram import raw
from pyrogram import types
from ..object import Object
class AutoName(Enum):
def _generate_next_value_(self, *args):
return self.lower()
class MessageEntityType(AutoName):
MENTION = auto()
HASHTAG = auto()
CASHTAG = auto()
BOT_COMMAND = auto()
URL = auto()
EMAIL = auto()
PHONE_NUMBER = auto()
BOLD = auto()
ITALIC = auto()
UNDERLINE = auto()
STRIKETHROUGH = auto()
CODE = auto()
PRE = auto()
TEXT_LINK = auto()
TEXT_MENTION = auto()
BLOCKQUOTE = auto()
RAW_ENTITIES_TO_TYPE = {
raw.types.MessageEntityMention: MessageEntityType.MENTION,
raw.types.MessageEntityHashtag: MessageEntityType.HASHTAG,
raw.types.MessageEntityCashtag: MessageEntityType.CASHTAG,
raw.types.MessageEntityBotCommand: MessageEntityType.BOT_COMMAND,
raw.types.MessageEntityUrl: MessageEntityType.URL,
raw.types.MessageEntityEmail: MessageEntityType.EMAIL,
raw.types.MessageEntityBold: MessageEntityType.BOLD,
raw.types.MessageEntityItalic: MessageEntityType.ITALIC,
raw.types.MessageEntityCode: MessageEntityType.CODE,
raw.types.MessageEntityPre: MessageEntityType.PRE,
raw.types.MessageEntityUnderline: MessageEntityType.UNDERLINE,
raw.types.MessageEntityStrike: MessageEntityType.STRIKETHROUGH,
raw.types.MessageEntityBlockquote: MessageEntityType.BLOCKQUOTE,
raw.types.MessageEntityTextUrl: MessageEntityType.TEXT_LINK,
raw.types.MessageEntityMentionName: MessageEntityType.TEXT_MENTION,
raw.types.MessageEntityPhone: MessageEntityType.PHONE_NUMBER
}
TYPE_TO_RAW_ENTITIES = {v.value: k for k, v in RAW_ENTITIES_TO_TYPE.items()}
class MessageEntity(Object):
"""One special entity in a text message.
For example, hashtags, usernames, URLs, etc.
@ -29,9 +77,12 @@ class MessageEntity(Object):
Parameters:
type (``str``):
Type of the entity.
Can be "mention" (@username), "hashtag", "cashtag", "bot_command", "url", "email", "phone_number", "bold"
(bold text), "italic" (italic text), "code" (monowidth string), "pre" (monowidth block), "text_link"
(for clickable text URLs), "text_mention" (for custom text mentions based on users' identifiers).
Can be "mention" (``@username``), "hashtag" (``#hashtag``), "cashtag" (``$PYRO``),
"bot_command" (``/start@pyrogrambot``), "url" (``https://pyrogram.org``),
"email" (``do-not-reply@pyrogram.org``), "phone_number" (``+1-420-069-1337``), "bold" (**bold text**),
"italic" (*italic text*), "underline" (underlined text), "strikethrough" (strikethrough text),
"code" (monowidth string), "pre" (monowidth block), "text_link" (for clickable text URLs),
"text_mention" (for users without usernames).
offset (``int``):
Offset in UTF-16 code units to the start of the entity.
@ -44,26 +95,10 @@ class MessageEntity(Object):
user (:obj:`~pyrogram.types.User`, *optional*):
For "text_mention" only, the mentioned user.
"""
ENTITIES = {
raw.types.MessageEntityMention.ID: "mention",
raw.types.MessageEntityHashtag.ID: "hashtag",
raw.types.MessageEntityCashtag.ID: "cashtag",
raw.types.MessageEntityBotCommand.ID: "bot_command",
raw.types.MessageEntityUrl.ID: "url",
raw.types.MessageEntityEmail.ID: "email",
raw.types.MessageEntityBold.ID: "bold",
raw.types.MessageEntityItalic.ID: "italic",
raw.types.MessageEntityCode.ID: "code",
raw.types.MessageEntityPre.ID: "pre",
raw.types.MessageEntityUnderline.ID: "underline",
raw.types.MessageEntityStrike.ID: "strike",
raw.types.MessageEntityBlockquote.ID: "blockquote",
raw.types.MessageEntityTextUrl.ID: "text_link",
raw.types.MessageEntityMentionName.ID: "text_mention",
raw.types.MessageEntityPhone.ID: "phone_number"
}
language (``str``. *optional*):
For "pre" only, the programming language of the entity text.
"""
def __init__(
self,
@ -73,7 +108,8 @@ class MessageEntity(Object):
offset: int,
length: int,
url: str = None,
user: "types.User" = None
user: "types.User" = None,
language: str = None
):
super().__init__(client)
@ -82,19 +118,49 @@ class MessageEntity(Object):
self.length = length
self.url = url
self.user = user
self.language = language
@staticmethod
def _parse(client, entity, users: dict) -> "MessageEntity" or None:
type = MessageEntity.ENTITIES.get(entity.ID, None)
type = RAW_ENTITIES_TO_TYPE.get(entity.__class__, None)
if type is None:
return None
return MessageEntity(
type=type,
type=type.value,
offset=entity.offset,
length=entity.length,
url=getattr(entity, "url", None),
user=types.User._parse(client, users.get(getattr(entity, "user_id", None), None)),
language=getattr(entity, "language", None),
client=client
)
async def write(self):
args = self.__dict__.copy()
for arg in ("_client", "type", "user"):
args.pop(arg)
if self.user:
args["user_id"] = await self._client.resolve_peer(self.user.id)
if not self.url:
args.pop("url")
if self.language is None:
args.pop("language")
try:
entity = TYPE_TO_RAW_ENTITIES[self.type]
if entity is raw.types.MessageEntityMentionName:
entity = raw.types.InputMessageEntityMentionName
except KeyError as e:
raise ValueError(f"Invalid message entity type {e}")
else:
try:
return entity(**args)
except TypeError as e:
raise TypeError(f"{entity.QUALNAME}'s {e}")

View File

@ -24,9 +24,9 @@ import os
import struct
from concurrent.futures.thread import ThreadPoolExecutor
from getpass import getpass
from typing import List
from typing import Union
from typing import Union, List, Dict
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram.file_id import FileId, FileType, PHOTO_TYPES, DOCUMENT_TYPES
@ -294,3 +294,24 @@ def compute_password_check(r: raw.types.account.Password, password: str) -> raw.
)
return raw.types.InputCheckPasswordSRP(srp_id=srp_id, A=A_bytes, M1=M1_bytes)
async def parse_text_entities(
client: "pyrogram.Client",
text: str,
parse_mode: str,
entities: List["types.MessageEntity"]
) -> Dict[str, raw.base.MessageEntity]:
if entities:
# Inject the client instance because parsing user mentions requires it
for entity in entities:
entity._client = client
text, entities = text, [await entity.write() for entity in entities]
else:
text, entities = (await client.parser.parse(text, parse_mode)).values()
return {
"message": text,
"entities": entities
}