Fix and update usage of parse_mode

This commit is contained in:
Lonami Exo 2022-02-04 12:19:53 +01:00
parent 4b477e5b27
commit 56faccf151
7 changed files with 35 additions and 74 deletions

View File

@ -284,11 +284,7 @@ async def sign_up(
pass # code is correct and was used, now need to sign in
if self._tos and self._tos.text:
if self.parse_mode:
t = self.parse_mode.unparse(self._tos.text, self._tos.entities)
else:
t = self._tos.text
sys.stderr.write("{}\n".format(t))
sys.stderr.write("{}\n".format(self._tos.text))
sys.stderr.flush()
phone, phone_code_hash = \

View File

@ -4,6 +4,7 @@ import typing
from .._misc import helpers, utils
from ..types import _custom
from ..types._custom.inputmessage import InputMessage
from .. import _tl
if typing.TYPE_CHECKING:
@ -29,7 +30,7 @@ async def _parse_message_text(self: 'TelegramClient', message, parse_mode):
Returns a (parsed message, entities) tuple depending on ``parse_mode``.
"""
if parse_mode == ():
parse_mode = self._parse_mode
parse_mode = InputMessage._default_parse_mode
else:
parse_mode = utils.sanitize_parse_mode(parse_mode)

View File

@ -141,7 +141,6 @@ def init(
self._connect_timeout = connect_timeout
self.flood_sleep_threshold = flood_sleep_threshold
self._flood_waited_requests = {} # prevent calls that would floodwait entirely
self._parse_mode = markdown
# Update handling.
self._catch_up = catch_up

View File

@ -2196,7 +2196,8 @@ class TelegramClient:
await client.send_message('me', 'Hello **world**!')
# Default to another parse mode
client.parse_mode = 'html'
from telethon.types import Message
Message.set_default_parse_mode('html')
await client.send_message('me', 'Some <b>bold</b> and <i>italic</i> text')
await client.send_message('me', 'An <a href="https://example.com">URL</a>')
@ -2204,8 +2205,8 @@ class TelegramClient:
await client.send_message('me', '<a href="tg://user?id=me">Mentions</a>')
# Explicit parse mode
# No parse mode by default
client.parse_mode = None
# No parse mode by default (import Message first)
Message.set_default_parse_mode(None)
# ...but here I want markdown
await client.send_message('me', 'Hello, **world**!', parse_mode='md')

View File

@ -748,37 +748,26 @@ def get_attributes(file, *, attributes=None, mime_type=None,
return list(attr_dict.values()), mime_type
def sanitize_parse_mode(mode):
"""
Converts the given parse mode into an object with
``parse`` and ``unparse`` callable properties.
"""
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
def sanitize_parse_mode(mode, *, _nop_parse=lambda t: (t, []), _nop_unparse=lambda t, e: t):
if mode is None:
mode = (_nop_parse, _nop_unparse)
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))
mode = mode.lower()
if mode in ('md', 'markdown'):
mode = (markdown.parse, markdown.unparse)
elif mode in ('htm', 'html'):
mode = (html.parse, html.unparse)
else:
raise ValueError(f'mode must be one of md, markdown, htm or html, but was {mode!r}')
elif callable(mode):
mode = (mode, _nop_unparse)
elif isinstance(mode, tuple):
if not (len(mode) == 2 and callable(mode[0]) and callable(mode[1])):
raise ValueError(f'mode must be a tuple of exactly two callables')
else:
raise TypeError('Invalid parse mode type {}'.format(mode))
raise TypeError(f'mode must be either a str, callable or tuple, but was {mode!r}')
return mode
def get_input_location(location):

View File

@ -489,7 +489,8 @@ class Message(ChatGetter, SenderGetter):
* A string equal to ``'md'`` or ``'markdown`` for parsing with commonmark,
``'htm'`` or ``'html'`` for parsing HTML.
* A ``callable``, which accepts a ``str`` as input and returns a tuple of
``(parsed str, formatting entities)``.
``(parsed str, formatting entities)``. Obtaining formatted text from a message in
this setting is not supported and will instead return the plain text.
* A ``tuple`` of two ``callable``. The first must accept a ``str`` as input and return
a tuple of ``(parsed str, list of formatting entities)``. The second must accept two
parameters, a parsed ``str`` and a ``list`` of formatting entities, and must return
@ -497,25 +498,7 @@ class Message(ChatGetter, SenderGetter):
If it's not one of these values or types, the method fails accordingly.
"""
if isinstance(mode, str):
mode = mode.lower()
if mode in ('md', 'markdown'):
mode = (_misc.markdown.parse, _misc.markdown.unparse)
elif mode in ('htm', 'html'):
mode = (_misc.html.parse, _misc.html.unparse)
else:
raise ValueError(f'mode must be one of md, markdown, htm or html, but was {mode!r}')
elif callable(mode):
mode = (mode, lambda t, e: t)
elif isinstance(mode, tuple):
if len(mode) == 2 and callable(mode[0]) and callable(mode[1]):
mode = mode
else:
raise ValueError(f'mode must be a tuple of exactly two callables')
else:
raise TypeError(f'mode must be either a str, callable or tuple, but was {mode!r}')
InputMessage._default_parse_mode = mode
InputMessage._default_parse_mode = utils.sanitize_parse_mode(mode)
@classmethod
def set_default_link_preview(cls, enabled):
@ -545,22 +528,11 @@ class Message(ChatGetter, SenderGetter):
The message text, formatted using the client's default
parse mode. Will be `None` for :tl:`MessageService`.
"""
if self._text is None and self._client:
if not self._client.parse_mode:
self._text = self.message
else:
self._text = self._client.parse_mode.unparse(
self.message, self.entities)
return self._text
return InputMessage._default_parse_mode[1](self.message, self.entities)
@text.setter
def text(self, value):
self._text = value
if self._client and self._client.parse_mode:
self.message, self.entities = self._client.parse_mode.parse(value)
else:
self.message, self.entities = value, []
self.message, self.entities = InputMessage._default_parse_mode[0](value)
@property
def raw_text(self):

View File

@ -5,6 +5,7 @@ import hypercorn.asyncio
from quart import Quart, render_template_string, request
from telethon import TelegramClient, utils
from telethon.types import Message
from telethon.errors import SessionPasswordNeededError
@ -51,9 +52,11 @@ SESSION = os.environ.get('TG_SESSION', 'quart')
API_ID = int(get_env('TG_API_ID', 'Enter your API ID: '))
API_HASH = get_env('TG_API_HASH', 'Enter your API hash: ')
# Render things nicely (global setting)
Message.set_default_parse_mode('html')
# Telethon client
client = TelegramClient(SESSION, API_ID, API_HASH)
client.parse_mode = 'html' # <- Render things nicely
phone = None
# Quart app
@ -69,7 +72,7 @@ async def format_message(message):
message.raw_text
)
else:
# client.parse_mode = 'html', so bold etc. will work!
# The Message parse_mode is 'html', so bold etc. will work!
content = (message.text or '(action message)').replace('\n', '<br>')
return '<p><strong>{}</strong>: {}<sub>{}</sub></p>'.format(