mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-12 10:11:52 +00:00
Fixed markup-entities parsing.
This commit is contained in:
parent
3abb48537c
commit
f52c59376d
2 changed files with 98 additions and 56 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
import functools
|
import functools
|
||||||
|
import sys
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from . import base
|
from . import base
|
||||||
|
|
@ -21,6 +22,7 @@ from .video import Video
|
||||||
from .video_note import VideoNote
|
from .video_note import VideoNote
|
||||||
from .voice import Voice
|
from .voice import Voice
|
||||||
from ..utils import helper
|
from ..utils import helper
|
||||||
|
from ..utils import markdown as md
|
||||||
|
|
||||||
|
|
||||||
class Message(base.TelegramObject):
|
class Message(base.TelegramObject):
|
||||||
|
|
@ -157,6 +159,49 @@ class Message(base.TelegramObject):
|
||||||
if command:
|
if command:
|
||||||
return command[1].strip()
|
return command[1].strip()
|
||||||
|
|
||||||
|
def parse_entities(self, as_html=True):
|
||||||
|
"""
|
||||||
|
Text or caption formatted as HTML.
|
||||||
|
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
text = self.text or self.caption
|
||||||
|
if text is None:
|
||||||
|
raise TypeError("This message doesn't have any text.")
|
||||||
|
|
||||||
|
quote_fn = md.quote_html if as_html else md.escape_md
|
||||||
|
|
||||||
|
if not self.entities:
|
||||||
|
return quote_fn(text)
|
||||||
|
|
||||||
|
if not sys.maxunicode == 0xffff:
|
||||||
|
text = text.encode('utf-16-le')
|
||||||
|
|
||||||
|
result = ''
|
||||||
|
offset = 0
|
||||||
|
|
||||||
|
for entity in sorted(self.entities, key=lambda item: item.offset):
|
||||||
|
entity_text = entity.parse(text, as_html=as_html)
|
||||||
|
|
||||||
|
if sys.maxunicode == 0xffff:
|
||||||
|
part = text[offset:entity.offset]
|
||||||
|
result += quote_fn(part) + entity_text
|
||||||
|
else:
|
||||||
|
part = text[offset * 2:entity.offset * 2]
|
||||||
|
result += quote_fn(part.decode('utf-16-le')) + entity_text
|
||||||
|
|
||||||
|
offset = entity.offset + entity.length
|
||||||
|
|
||||||
|
if sys.maxunicode == 0xffff:
|
||||||
|
part = text[offset:]
|
||||||
|
result += quote_fn(part)
|
||||||
|
else:
|
||||||
|
part = text[offset * 2:]
|
||||||
|
result += quote_fn(part.decode('utf-16-le'))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def md_text(self) -> str:
|
def md_text(self) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
@ -164,28 +209,16 @@ class Message(base.TelegramObject):
|
||||||
|
|
||||||
:return: str
|
:return: str
|
||||||
"""
|
"""
|
||||||
text = self.caption if self.caption else self.text
|
return self.parse_entities(False)
|
||||||
|
|
||||||
if self.text and self.entities:
|
|
||||||
for entity in reversed(self.entities):
|
|
||||||
text = entity.apply_md(text)
|
|
||||||
|
|
||||||
return text
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def html_text(self) -> str:
|
def html_text(self) -> str:
|
||||||
"""
|
"""
|
||||||
Text or caption formatted as HTML.
|
Text or caption formatted as HTML
|
||||||
|
|
||||||
:return: str
|
:return: str
|
||||||
"""
|
"""
|
||||||
text = self.caption if self.caption else self.text
|
return self.parse_entities(True)
|
||||||
|
|
||||||
if self.text and self.entities:
|
|
||||||
for entity in reversed(self.entities):
|
|
||||||
text = entity.apply_html(text)
|
|
||||||
|
|
||||||
return text
|
|
||||||
|
|
||||||
async def reply(self, text, parse_mode=None, disable_web_page_preview=None,
|
async def reply(self, text, parse_mode=None, disable_web_page_preview=None,
|
||||||
disable_notification=None, reply_markup=None, reply=True) -> 'Message':
|
disable_notification=None, reply_markup=None, reply=True) -> 'Message':
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
from . import base
|
from . import base
|
||||||
from . import fields
|
from . import fields
|
||||||
from .user import User
|
from .user import User
|
||||||
|
|
@ -16,56 +18,63 @@ class MessageEntity(base.TelegramObject):
|
||||||
url: base.String = fields.Field()
|
url: base.String = fields.Field()
|
||||||
user: User = fields.Field(base=User)
|
user: User = fields.Field(base=User)
|
||||||
|
|
||||||
def _apply(self, text, func):
|
def get_text(self, text):
|
||||||
return text[:self.offset] + \
|
|
||||||
func(text[self.offset:self.offset + self.length]) + \
|
|
||||||
text[self.offset + self.length:]
|
|
||||||
|
|
||||||
def apply_md(self, text):
|
|
||||||
"""
|
"""
|
||||||
Apply entity for text as Markdown
|
Get value of entity
|
||||||
|
|
||||||
:param text:
|
:param text: full text
|
||||||
:return:
|
:return: part of text
|
||||||
"""
|
"""
|
||||||
if self.type == MessageEntityType.BOLD:
|
if sys.maxunicode == 0xffff:
|
||||||
return self._apply(text, markdown.bold)
|
return text[self.offset:self.offset + self.length]
|
||||||
elif self.type == MessageEntityType.ITALIC:
|
|
||||||
return self._apply(text, markdown.italic)
|
if not isinstance(text, bytes):
|
||||||
elif self.type == MessageEntityType.PRE:
|
entity_text = text.encode('utf-16-le')
|
||||||
return self._apply(text, markdown.pre)
|
else:
|
||||||
elif self.type == MessageEntityType.CODE:
|
entity_text = text
|
||||||
return self._apply(text, markdown.code)
|
|
||||||
elif self.type == MessageEntityType.URL:
|
entity_text = entity_text[self.offset * 2:(self.offset + self.length) * 2]
|
||||||
return self._apply(text, lambda url: markdown.link(url, url))
|
return entity_text.decode('utf-16-le')
|
||||||
elif self.type == MessageEntityType.TEXT_LINK:
|
|
||||||
return self._apply(text, lambda url: markdown.link(url, self.url))
|
def parse(self, text, as_html=True):
|
||||||
if self.type == MessageEntityType.TEXT_MENTION and self.user:
|
"""
|
||||||
return self._apply(text, lambda name: self.user.get_mention(name, as_html=False))
|
Get entity value with markup
|
||||||
|
|
||||||
|
:param text: original text
|
||||||
|
:param as_html: as html?
|
||||||
|
:return: entity text with markup
|
||||||
|
"""
|
||||||
|
if not text:
|
||||||
return text
|
return text
|
||||||
|
entity_text = self.get_text(text)
|
||||||
|
|
||||||
def apply_html(self, text):
|
|
||||||
"""
|
|
||||||
Apply entity for text as HTML
|
|
||||||
|
|
||||||
:param text:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
if self.type == MessageEntityType.BOLD:
|
if self.type == MessageEntityType.BOLD:
|
||||||
return self._apply(text, markdown.hbold)
|
if as_html:
|
||||||
|
return markdown.hbold(entity_text)
|
||||||
|
return markdown.bold(entity_text)
|
||||||
elif self.type == MessageEntityType.ITALIC:
|
elif self.type == MessageEntityType.ITALIC:
|
||||||
return self._apply(text, markdown.hitalic)
|
if as_html:
|
||||||
|
return markdown.hitalic(entity_text)
|
||||||
|
return markdown.italic(entity_text)
|
||||||
elif self.type == MessageEntityType.PRE:
|
elif self.type == MessageEntityType.PRE:
|
||||||
return self._apply(text, markdown.hpre)
|
if as_html:
|
||||||
|
return markdown.hpre(entity_text)
|
||||||
|
return markdown.pre(entity_text)
|
||||||
elif self.type == MessageEntityType.CODE:
|
elif self.type == MessageEntityType.CODE:
|
||||||
return self._apply(text, markdown.hcode)
|
if as_html:
|
||||||
|
return markdown.hcode(entity_text)
|
||||||
|
return markdown.code(entity_text)
|
||||||
elif self.type == MessageEntityType.URL:
|
elif self.type == MessageEntityType.URL:
|
||||||
return self._apply(text, lambda url: markdown.hlink(url, url))
|
if as_html:
|
||||||
|
return markdown.hlink(entity_text, entity_text)
|
||||||
|
return markdown.link(entity_text, entity_text)
|
||||||
elif self.type == MessageEntityType.TEXT_LINK:
|
elif self.type == MessageEntityType.TEXT_LINK:
|
||||||
return self._apply(text, lambda url: markdown.hlink(url, self.url))
|
if as_html:
|
||||||
if self.type == MessageEntityType.TEXT_MENTION and self.user:
|
return markdown.hlink(entity_text, self.url)
|
||||||
return self._apply(text, lambda name: self.user.get_mention(name, as_html=True))
|
return markdown.link(entity_text, self.url)
|
||||||
return text
|
elif self.type == MessageEntityType.TEXT_MENTION and self.user:
|
||||||
|
return self.user.get_mention(entity_text)
|
||||||
|
return entity_text
|
||||||
|
|
||||||
|
|
||||||
class MessageEntityType(helper.Helper):
|
class MessageEntityType(helper.Helper):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue