Add some setters for custom.Message

This commit is contained in:
Lonami Exo 2018-06-03 11:53:18 +02:00
parent 8b16023566
commit 8d7c7a19c0
4 changed files with 79 additions and 49 deletions

View File

@ -148,3 +148,6 @@ class NewMessage(EventBuilder):
def __getattr__(self, item): def __getattr__(self, item):
return getattr(self.message, item) return getattr(self.message, item)
def __setattr__(self, name, value):
return setattr(self.original_message, name, value)

View File

@ -4,15 +4,16 @@ for use within the library, which attempts to handle emojies correctly,
since they seem to count as two characters and it's a bit strange. since they seem to count as two characters and it's a bit strange.
""" """
import re import re
import struct
from ..tl import TLObject from ..tl import TLObject
from ..tl.types import ( from ..tl.types import (
MessageEntityBold, MessageEntityItalic, MessageEntityCode, MessageEntityBold, MessageEntityItalic, MessageEntityCode,
MessageEntityPre, MessageEntityTextUrl MessageEntityPre, MessageEntityTextUrl
) )
from ..utils import (
add_surrogate as _add_surrogate,
del_surrogate as _del_surrogate
)
DEFAULT_DELIMITERS = { DEFAULT_DELIMITERS = {
'**': MessageEntityBold, '**': MessageEntityBold,
@ -25,19 +26,6 @@ DEFAULT_URL_RE = re.compile(r'\[([\S\s]+?)\]\((.+?)\)')
DEFAULT_URL_FORMAT = '[{0}]({1})' DEFAULT_URL_FORMAT = '[{0}]({1})'
def _add_surrogate(text):
return ''.join(
# SMP -> Surrogate Pairs (Telegram offsets are calculated with these).
# See https://en.wikipedia.org/wiki/Plane_(Unicode)#Overview for more.
''.join(chr(y) for y in struct.unpack('<HH', x.encode('utf-16le')))
if (0x10000 <= ord(x) <= 0x10FFFF) else x for x in text
)
def _del_surrogate(text):
return text.encode('utf-16', 'surrogatepass').decode('utf-16')
def parse(message, delimiters=None, url_re=None): def parse(message, delimiters=None, url_re=None):
""" """
Parses the given markdown message and returns its stripped representation Parses the given markdown message and returns its stripped representation
@ -181,28 +169,3 @@ def unparse(text, entities, delimiters=None, url_fmt=None):
) )
return _del_surrogate(text) return _del_surrogate(text)
def get_inner_text(text, entity):
"""
Gets the inner text that's surrounded by the given entity or entities.
For instance: text = 'hey!', entity = MessageEntityBold(2, 2) -> 'y!'.
:param text: the original text.
:param entity: the entity or entities that must be matched.
:return: a single result or a list of the text surrounded by the entities.
"""
if isinstance(entity, TLObject):
entity = (entity,)
multiple = True
else:
multiple = False
text = _add_surrogate(text)
result = []
for e in entity:
start = e.offset
end = e.offset + e.length
result.append(_del_surrogate(text[start:end]))
return result if multiple else result[0]

View File

@ -1,6 +1,5 @@
from .. import types from .. import types
from ...extensions import markdown from ...utils import get_input_peer, get_peer_id, get_inner_text
from ...utils import get_input_peer, get_peer_id
from .messagebutton import MessageButton from .messagebutton import MessageButton
@ -55,6 +54,9 @@ class Message:
def __getattr__(self, item): def __getattr__(self, item):
return getattr(self.original_message, item) return getattr(self.original_message, item)
def __setattr__(self, name, value):
return setattr(self.original_message, name, value)
def __str__(self): def __str__(self):
return str(self.original_message) return str(self.original_message)
@ -75,17 +77,28 @@ class Message:
@property @property
def text(self): def text(self):
""" """
The message text, markdown-formatted. The message text, formatted using the client's default parse mode.
Will be ``None`` for :tl:`MessageService`. Will be ``None`` for :tl:`MessageService`.
""" """
if self._text is None\ if self._text is None\
and isinstance(self.original_message, types.Message): and isinstance(self.original_message, types.Message):
if not self.original_message.entities: if not self._client.parse_mode:
return self.original_message.message return self.original_message.message
self._text = markdown.unparse(self.original_message.message, self._text = self._client.parse_mode.unparse(
self.original_message.entities or []) self.original_message.message, self.original_message.entities)
return self._text return self._text
@text.setter
def text(self, value):
if isinstance(self.original_message, types.Message):
if self._client.parse_mode:
msg, ent = self._client.parse_mode.parse(value)
else:
msg, ent = value, []
self.original_message.message = msg
self.original_message.entities = ent
self._text = value
@property @property
def raw_text(self): def raw_text(self):
""" """
@ -95,6 +108,13 @@ class Message:
if isinstance(self.original_message, types.Message): if isinstance(self.original_message, types.Message):
return self.original_message.message return self.original_message.message
@raw_text.setter
def raw_text(self, value):
if isinstance(self.original_message, types.Message):
self.original_message.message = value
self.original_message.entities = []
self._text = None
@property @property
def message(self): def message(self):
""" """
@ -103,6 +123,10 @@ class Message:
""" """
return self.raw_text return self.raw_text
@message.setter
def message(self, value):
self.raw_text = value
@property @property
def action(self): def action(self):
""" """
@ -478,8 +502,8 @@ class Message:
Returns a list of tuples [(:tl:`MessageEntity`, `str`)], the string Returns a list of tuples [(:tl:`MessageEntity`, `str`)], the string
being the inner text of the message entity (like bold, italics, etc). being the inner text of the message entity (like bold, italics, etc).
""" """
texts = markdown.get_inner_text(self.original_message.message, texts = get_inner_text(self.original_message.message,
self.original_message.entities) self.original_message.entities)
return list(zip(self.original_message.entities, texts)) return list(zip(self.original_message.entities, texts))
def click(self, i=None, j=None, *, text=None, filter=None): def click(self, i=None, j=None, *, text=None, filter=None):

View File

@ -6,10 +6,12 @@ import math
import mimetypes import mimetypes
import os import os
import re import re
import struct
import types import types
from collections import UserList from collections import UserList
from mimetypes import guess_extension from mimetypes import guess_extension
from .tl import TLObject
from .tl.types import ( from .tl.types import (
Channel, ChannelForbidden, Chat, ChatEmpty, ChatForbidden, ChatFull, Channel, ChannelForbidden, Chat, ChatEmpty, ChatForbidden, ChatFull,
ChatPhoto, InputPeerChannel, InputPeerChat, InputPeerUser, InputPeerEmpty, ChatPhoto, InputPeerChannel, InputPeerChat, InputPeerUser, InputPeerEmpty,
@ -500,6 +502,44 @@ def _fix_peer_id(peer_id):
return int(peer_id) return int(peer_id)
def add_surrogate(text):
return ''.join(
# SMP -> Surrogate Pairs (Telegram offsets are calculated with these).
# See https://en.wikipedia.org/wiki/Plane_(Unicode)#Overview for more.
''.join(chr(y) for y in struct.unpack('<HH', x.encode('utf-16le')))
if (0x10000 <= ord(x) <= 0x10FFFF) else x for x in text
)
def del_surrogate(text):
return text.encode('utf-16', 'surrogatepass').decode('utf-16')
def get_inner_text(text, entity):
"""
Gets the inner text that's surrounded by the given entity or entities.
For instance: text = 'hey!', entity = MessageEntityBold(2, 2) -> 'y!'.
:param text: the original text.
:param entity: the entity or entities that must be matched.
:return: a single result or a list of the text surrounded by the entities.
"""
if isinstance(entity, TLObject):
entity = (entity,)
multiple = True
else:
multiple = False
text = add_surrogate(text)
result = []
for e in entity:
start = e.offset
end = e.offset + e.length
result.append(del_surrogate(text[start:end]))
return result if multiple else result[0]
def get_peer_id(peer): def get_peer_id(peer):
""" """
Finds the ID of the given peer, and converts it to the "bot api" format Finds the ID of the given peer, and converts it to the "bot api" format