mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-06-22 13:06:37 +00:00
Allow setting a per-client default parse mode
This commit is contained in:
parent
12812ea542
commit
8b16023566
@ -81,7 +81,7 @@ from .tl.types import (
|
|||||||
InputUserSelf, UserProfilePhoto, ChatPhoto, UpdateMessageID,
|
InputUserSelf, UserProfilePhoto, ChatPhoto, UpdateMessageID,
|
||||||
UpdateNewChannelMessage, UpdateNewMessage, UpdateShortSentMessage,
|
UpdateNewChannelMessage, UpdateNewMessage, UpdateShortSentMessage,
|
||||||
PeerUser, InputPeerUser, InputPeerChat, InputPeerChannel, MessageEmpty,
|
PeerUser, InputPeerUser, InputPeerChat, InputPeerChannel, MessageEmpty,
|
||||||
ChatInvite, ChatInviteAlready, PeerChannel, Photo, InputPeerSelf,
|
ChatInvite, ChatInviteAlready, Photo, InputPeerSelf,
|
||||||
InputSingleMedia, InputMediaPhoto, InputPhoto, InputFile, InputFileBig,
|
InputSingleMedia, InputMediaPhoto, InputPhoto, InputFile, InputFileBig,
|
||||||
InputDocument, InputMediaDocument, Document, MessageEntityTextUrl,
|
InputDocument, InputMediaDocument, Document, MessageEntityTextUrl,
|
||||||
InputMessageEntityMentionName, DocumentAttributeVideo,
|
InputMessageEntityMentionName, DocumentAttributeVideo,
|
||||||
@ -94,6 +94,7 @@ from .tl.types import (
|
|||||||
from .tl.types.messages import DialogsSlice
|
from .tl.types.messages import DialogsSlice
|
||||||
from .tl.types.account import PasswordInputSettings, NoPassword
|
from .tl.types.account import PasswordInputSettings, NoPassword
|
||||||
from .tl import custom
|
from .tl import custom
|
||||||
|
from .utils import Default
|
||||||
from .extensions import markdown, html
|
from .extensions import markdown, html
|
||||||
|
|
||||||
__log__ = logging.getLogger(__name__)
|
__log__ = logging.getLogger(__name__)
|
||||||
@ -200,6 +201,9 @@ class TelegramClient(TelegramBareClient):
|
|||||||
self._event_builders = []
|
self._event_builders = []
|
||||||
self._events_pending_resolve = []
|
self._events_pending_resolve = []
|
||||||
|
|
||||||
|
# Default parse mode
|
||||||
|
self._parse_mode = markdown
|
||||||
|
|
||||||
# Some fields to easy signing in. Let {phone: hash} be
|
# Some fields to easy signing in. Let {phone: hash} be
|
||||||
# a dictionary because the user may change their mind.
|
# a dictionary because the user may change their mind.
|
||||||
self._phone_code_hash = {}
|
self._phone_code_hash = {}
|
||||||
@ -704,26 +708,78 @@ class TelegramClient(TelegramBareClient):
|
|||||||
if found:
|
if found:
|
||||||
return custom.Message(self, found, entities, input_chat)
|
return custom.Message(self, found, entities, input_chat)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parse_mode(self):
|
||||||
|
"""
|
||||||
|
This property is the default parse mode used when sending messages.
|
||||||
|
Defaults to `telethon.extensions.markdown`. It will always
|
||||||
|
be either ``None`` or an object with ``parse`` and ``unparse``
|
||||||
|
methods.
|
||||||
|
|
||||||
|
When setting a different value it should be one of:
|
||||||
|
|
||||||
|
* Object with ``parse`` and ``unparse`` methods.
|
||||||
|
* A ``callable`` to act as the parse method.
|
||||||
|
* A ``str`` indicating the ``parse_mode``. For Markdown ``'md'``
|
||||||
|
or ``'markdown'`` may be used. For HTML, ``'htm'`` or ``'html'``
|
||||||
|
may be used.
|
||||||
|
|
||||||
|
The ``parse`` method should be a function accepting a single
|
||||||
|
parameter, the text to parse, and returning a tuple consisting
|
||||||
|
of ``(parsed message str, [MessageEntity instances])``.
|
||||||
|
|
||||||
|
The ``unparse`` method should be the inverse of ``parse`` such
|
||||||
|
that ``assert text == unparse(*parse(text))``.
|
||||||
|
|
||||||
|
See :tl:`MessageEntity` for allowed message entities.
|
||||||
|
"""
|
||||||
|
return self._parse_mode
|
||||||
|
|
||||||
|
@parse_mode.setter
|
||||||
|
def parse_mode(self, mode):
|
||||||
|
self._parse_mode = self._sanitize_parse_mode(mode)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _sanitize_parse_mode(mode):
|
||||||
|
if not mode:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if callable(mode):
|
||||||
|
class CustomMode:
|
||||||
|
@staticmethod
|
||||||
|
def unparse(text, entities):
|
||||||
|
raise NotImplementedError
|
||||||
|
CustomMode.parse = mode
|
||||||
|
return CustomMode
|
||||||
|
elif (all(hasattr(mode, x) for x in ('parse', 'unparse'))
|
||||||
|
and all(callable(x) for x in (mode.parse, mode.unparse))):
|
||||||
|
return mode
|
||||||
|
elif isinstance(mode, str):
|
||||||
|
try:
|
||||||
|
return {
|
||||||
|
'md': markdown,
|
||||||
|
'markdown': markdown,
|
||||||
|
'htm': html,
|
||||||
|
'html': html
|
||||||
|
}[mode.lower()]
|
||||||
|
except KeyError:
|
||||||
|
raise ValueError('Unknown parse mode {}'.format(mode))
|
||||||
|
else:
|
||||||
|
raise TypeError('Invalid parse mode type {}'.format(mode))
|
||||||
|
|
||||||
def _parse_message_text(self, message, parse_mode):
|
def _parse_message_text(self, message, parse_mode):
|
||||||
"""
|
"""
|
||||||
Returns a (parsed message, entities) tuple depending on ``parse_mode``.
|
Returns a (parsed message, entities) tuple depending on ``parse_mode``.
|
||||||
"""
|
"""
|
||||||
|
if parse_mode == Default:
|
||||||
|
parse_mode = self._parse_mode
|
||||||
|
else:
|
||||||
|
parse_mode = self._sanitize_parse_mode(parse_mode)
|
||||||
|
|
||||||
if not parse_mode:
|
if not parse_mode:
|
||||||
return message, []
|
return message, []
|
||||||
|
|
||||||
if isinstance(parse_mode, str):
|
message, msg_entities = parse_mode.parse(message)
|
||||||
parse_mode = parse_mode.lower()
|
|
||||||
if parse_mode in {'md', 'markdown'}:
|
|
||||||
message, msg_entities = markdown.parse(message)
|
|
||||||
elif parse_mode.startswith('htm'):
|
|
||||||
message, msg_entities = html.parse(message)
|
|
||||||
else:
|
|
||||||
raise ValueError('Unknown parsing mode: {}'.format(parse_mode))
|
|
||||||
elif callable(parse_mode):
|
|
||||||
message, msg_entities = parse_mode(message)
|
|
||||||
else:
|
|
||||||
raise TypeError('Invalid parsing mode type: {}'.format(parse_mode))
|
|
||||||
|
|
||||||
for i, e in enumerate(msg_entities):
|
for i, e in enumerate(msg_entities):
|
||||||
if isinstance(e, MessageEntityTextUrl):
|
if isinstance(e, MessageEntityTextUrl):
|
||||||
m = re.match(r'^@|\+|tg://user\?id=(\d+)', e.url)
|
m = re.match(r'^@|\+|tg://user\?id=(\d+)', e.url)
|
||||||
@ -740,9 +796,9 @@ class TelegramClient(TelegramBareClient):
|
|||||||
|
|
||||||
return message, msg_entities
|
return message, msg_entities
|
||||||
|
|
||||||
def send_message(self, entity, message='', reply_to=None, parse_mode='md',
|
def send_message(self, entity, message='', reply_to=None,
|
||||||
link_preview=True, file=None, force_document=False,
|
parse_mode=Default, link_preview=True, file=None,
|
||||||
clear_draft=False):
|
force_document=False, clear_draft=False):
|
||||||
"""
|
"""
|
||||||
Sends the given message to the specified entity (user/chat/channel).
|
Sends the given message to the specified entity (user/chat/channel).
|
||||||
|
|
||||||
@ -773,17 +829,9 @@ class TelegramClient(TelegramBareClient):
|
|||||||
Whether to reply to a message or not. If an integer is provided,
|
Whether to reply to a message or not. If an integer is provided,
|
||||||
it should be the ID of the message that it should reply to.
|
it should be the ID of the message that it should reply to.
|
||||||
|
|
||||||
parse_mode (`str`, optional):
|
parse_mode (`object`, optional):
|
||||||
Can be 'md' or 'markdown' for markdown-like parsing (default),
|
See the `TelegramClient.parse_mode` property for allowed
|
||||||
or 'htm' or 'html' for HTML-like parsing. If ``None`` or any
|
values. Markdown parsing will be used by default.
|
||||||
other false-y value is provided, the message will be sent with
|
|
||||||
no formatting.
|
|
||||||
|
|
||||||
If a ``callable`` is passed, it should be a function accepting
|
|
||||||
a `str` as an input and return as output a tuple consisting
|
|
||||||
of ``(parsed message str, [MessageEntity instances])``.
|
|
||||||
|
|
||||||
See :tl:`MessageEntity` for allowed message entities.
|
|
||||||
|
|
||||||
link_preview (`bool`, optional):
|
link_preview (`bool`, optional):
|
||||||
Should the link preview be shown?
|
Should the link preview be shown?
|
||||||
@ -925,8 +973,8 @@ class TelegramClient(TelegramBareClient):
|
|||||||
result = [id_to_message[random_to_id[rnd]] for rnd in req.random_id]
|
result = [id_to_message[random_to_id[rnd]] for rnd in req.random_id]
|
||||||
return result[0] if single else result
|
return result[0] if single else result
|
||||||
|
|
||||||
def edit_message(self, entity, message=None, text=None, parse_mode='md',
|
def edit_message(self, entity, message=None, text=None,
|
||||||
link_preview=True):
|
parse_mode=Default, link_preview=True):
|
||||||
"""
|
"""
|
||||||
Edits the given message ID (to change its contents or disable preview).
|
Edits the given message ID (to change its contents or disable preview).
|
||||||
|
|
||||||
@ -946,11 +994,9 @@ class TelegramClient(TelegramBareClient):
|
|||||||
The new text of the message. Does nothing if the `entity`
|
The new text of the message. Does nothing if the `entity`
|
||||||
was a :tl:`Message`.
|
was a :tl:`Message`.
|
||||||
|
|
||||||
parse_mode (`str`, optional):
|
parse_mode (`object`, optional):
|
||||||
Can be 'md' or 'markdown' for markdown-like parsing (default),
|
See the `TelegramClient.parse_mode` property for allowed
|
||||||
or 'htm' or 'html' for HTML-like parsing. If ``None`` or any
|
values. Markdown parsing will be used by default.
|
||||||
other false-y value is provided, the message will be sent with
|
|
||||||
no formatting.
|
|
||||||
|
|
||||||
link_preview (`bool`, optional):
|
link_preview (`bool`, optional):
|
||||||
Should the link preview be shown?
|
Should the link preview be shown?
|
||||||
@ -1531,7 +1577,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
attributes=None,
|
attributes=None,
|
||||||
thumb=None,
|
thumb=None,
|
||||||
allow_cache=True,
|
allow_cache=True,
|
||||||
parse_mode='md',
|
parse_mode=Default,
|
||||||
voice_note=False,
|
voice_note=False,
|
||||||
video_note=False,
|
video_note=False,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
@ -1584,8 +1630,9 @@ class TelegramClient(TelegramBareClient):
|
|||||||
Must be ``False`` if you wish to use different attributes
|
Must be ``False`` if you wish to use different attributes
|
||||||
or thumb than those that were used when the file was cached.
|
or thumb than those that were used when the file was cached.
|
||||||
|
|
||||||
parse_mode (`str`, optional):
|
parse_mode (`object`, optional):
|
||||||
The parse mode for the caption message.
|
See the `TelegramClient.parse_mode` property for allowed
|
||||||
|
values. Markdown parsing will be used by default.
|
||||||
|
|
||||||
voice_note (`bool`, optional):
|
voice_note (`bool`, optional):
|
||||||
If ``True`` the audio will be sent as a voice note.
|
If ``True`` the audio will be sent as a voice note.
|
||||||
@ -1788,7 +1835,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
|
|
||||||
def _send_album(self, entity, files, caption='',
|
def _send_album(self, entity, files, caption='',
|
||||||
progress_callback=None, reply_to=None,
|
progress_callback=None, reply_to=None,
|
||||||
parse_mode='md'):
|
parse_mode=Default):
|
||||||
"""Specialized version of .send_file for albums"""
|
"""Specialized version of .send_file for albums"""
|
||||||
# We don't care if the user wants to avoid cache, we will use it
|
# We don't care if the user wants to avoid cache, we will use it
|
||||||
# anyway. Why? The cached version will be exactly the same thing
|
# anyway. Why? The cached version will be exactly the same thing
|
||||||
|
@ -5,6 +5,7 @@ from ..functions.messages import SaveDraftRequest
|
|||||||
from ..types import UpdateDraftMessage, DraftMessage
|
from ..types import UpdateDraftMessage, DraftMessage
|
||||||
from ...errors import RPCError
|
from ...errors import RPCError
|
||||||
from ...extensions import markdown
|
from ...extensions import markdown
|
||||||
|
from ...utils import Default
|
||||||
|
|
||||||
|
|
||||||
class Draft:
|
class Draft:
|
||||||
@ -82,7 +83,7 @@ class Draft:
|
|||||||
"""
|
"""
|
||||||
return not self._text
|
return not self._text
|
||||||
|
|
||||||
def set_message(self, text=None, reply_to=0, parse_mode='md',
|
def set_message(self, text=None, reply_to=0, parse_mode=Default,
|
||||||
link_preview=None):
|
link_preview=None):
|
||||||
"""
|
"""
|
||||||
Changes the draft message on the Telegram servers. The changes are
|
Changes the draft message on the Telegram servers. The changes are
|
||||||
@ -127,7 +128,7 @@ class Draft:
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def send(self, clear=True, parse_mode='md'):
|
def send(self, clear=True, parse_mode=Default):
|
||||||
"""
|
"""
|
||||||
Sends the contents of this draft to the dialog. This is just a
|
Sends the contents of this draft to the dialog. This is just a
|
||||||
wrapper around ``send_message(dialog.input_entity, *args, **kwargs)``.
|
wrapper around ``send_message(dialog.input_entity, *args, **kwargs)``.
|
||||||
|
@ -46,6 +46,14 @@ VALID_USERNAME_RE = re.compile(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Default:
|
||||||
|
"""
|
||||||
|
Sentinel value to indicate that the default value should be used.
|
||||||
|
Currently used for the ``parse_mode``, where a ``None`` mode should
|
||||||
|
be considered different from using the default.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def get_display_name(entity):
|
def get_display_name(entity):
|
||||||
"""
|
"""
|
||||||
Gets the display name for the given entity, if it's an :tl:`User`,
|
Gets the display name for the given entity, if it's an :tl:`User`,
|
||||||
|
Loading…
Reference in New Issue
Block a user