Add basic support for bridging custom emojis from Telegram
This commit is contained in:
@@ -20,7 +20,7 @@ import logging
|
||||
import re
|
||||
|
||||
from telethon.errors import RPCError
|
||||
from telethon.helpers import add_surrogate, del_surrogate, within_surrogate
|
||||
from telethon.helpers import add_surrogate, del_surrogate
|
||||
from telethon.tl.custom import Message
|
||||
from telethon.tl.types import (
|
||||
MessageEntityBlockquote,
|
||||
@@ -52,8 +52,9 @@ from telethon.tl.types import (
|
||||
from mautrix.types import Format, MessageType, TextMessageEventContent
|
||||
|
||||
from .. import abstract_user as au, portal as po, puppet as pu, user as u
|
||||
from ..db import Message as DBMessage
|
||||
from ..db import Message as DBMessage, TelegramFile as DBTelegramFile
|
||||
from ..types import TelegramID
|
||||
from ..util.file_transfer import transfer_custom_emojis_to_matrix
|
||||
|
||||
log: logging.Logger = logging.getLogger("mau.fmt.tg")
|
||||
|
||||
@@ -125,6 +126,27 @@ async def _add_forward_header(
|
||||
)
|
||||
|
||||
|
||||
class ReuploadedCustomEmoji(MessageEntityCustomEmoji):
|
||||
file: DBTelegramFile
|
||||
|
||||
def __init__(self, parent: MessageEntityCustomEmoji, file: DBTelegramFile) -> None:
|
||||
super().__init__(parent.offset, parent.length, parent.document_id)
|
||||
self.file = file
|
||||
|
||||
|
||||
async def _convert_custom_emoji(
|
||||
source: au.AbstractUser, entities: list[TypeMessageEntity]
|
||||
) -> None:
|
||||
emoji_ids = [
|
||||
entity.document_id for entity in entities if isinstance(entity, MessageEntityCustomEmoji)
|
||||
]
|
||||
custom_emojis = await transfer_custom_emojis_to_matrix(source, emoji_ids)
|
||||
if len(custom_emojis) > 0:
|
||||
for i, entity in enumerate(entities):
|
||||
if isinstance(entity, MessageEntityCustomEmoji):
|
||||
entities[i] = ReuploadedCustomEmoji(entity, custom_emojis[entity.document_id])
|
||||
|
||||
|
||||
async def telegram_to_matrix(
|
||||
evt: Message | SponsoredMessage,
|
||||
source: au.AbstractUser,
|
||||
@@ -138,6 +160,7 @@ async def telegram_to_matrix(
|
||||
)
|
||||
entities = override_entities or evt.entities
|
||||
if entities:
|
||||
await _convert_custom_emoji(source, entities)
|
||||
content.format = Format.HTML
|
||||
html = await _telegram_entities_to_matrix_catch(add_surrogate(content.body), entities)
|
||||
content.formatted_body = del_surrogate(html)
|
||||
@@ -166,9 +189,20 @@ async def _telegram_entities_to_matrix_catch(text: str, entities: list[TypeMessa
|
||||
return "[failed conversion in _telegram_entities_to_matrix]"
|
||||
|
||||
|
||||
def within_surrogate(text, index):
|
||||
"""
|
||||
`True` if ``index`` is within a surrogate (before and after it, not at!).
|
||||
"""
|
||||
return (
|
||||
1 < index < len(text) # in bounds
|
||||
and "\ud800" <= text[index - 1] <= "\udbff" # current is low surrogate
|
||||
and "\udc00" <= text[index] <= "\udfff" # previous is high surrogate
|
||||
)
|
||||
|
||||
|
||||
async def _telegram_entities_to_matrix(
|
||||
text: str,
|
||||
entities: list[TypeMessageEntity],
|
||||
entities: list[TypeMessageEntity | ReuploadedCustomEmoji],
|
||||
offset: int = 0,
|
||||
length: int = None,
|
||||
in_codeblock: bool = False,
|
||||
@@ -197,10 +231,9 @@ async def _telegram_entities_to_matrix(
|
||||
elif relative_offset < last_offset:
|
||||
continue
|
||||
|
||||
# TODO this breaks when there are lots of emojis in a row (e.g. custom emojis)
|
||||
# while within_surrogate(text, relative_offset, length=length):
|
||||
# relative_offset += 1
|
||||
while within_surrogate(text, relative_offset + entity.length, length=length):
|
||||
while within_surrogate(text, relative_offset):
|
||||
relative_offset += 1
|
||||
while within_surrogate(text, relative_offset + entity.length):
|
||||
entity.length += 1
|
||||
|
||||
skip_entity = False
|
||||
@@ -244,8 +277,12 @@ async def _telegram_entities_to_matrix(
|
||||
html, entity_text, entity.url if entity_type == MessageEntityTextUrl else None
|
||||
)
|
||||
elif entity_type == MessageEntityCustomEmoji:
|
||||
# TODO support properly
|
||||
html.append(entity_text)
|
||||
elif entity_type == ReuploadedCustomEmoji:
|
||||
html.append(
|
||||
f'<img data-mx-emoticon src="{escape(entity.file.mxc)}" height="32" '
|
||||
f'alt="{entity_text}" title="{entity_text}"/>'
|
||||
)
|
||||
elif entity_type in (
|
||||
MessageEntityBotCommand,
|
||||
MessageEntityHashtag,
|
||||
|
||||
Reference in New Issue
Block a user