From 19bf13815582140e25ca7ff540c839e282fc41db Mon Sep 17 00:00:00 2001 From: pplulee Date: Sat, 5 Apr 2025 23:22:22 +0800 Subject: [PATCH 1/3] Add support for processing language parameter in message entities --- telebot/formatting.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/telebot/formatting.py b/telebot/formatting.py index 801a67ec1..aa24c2007 100644 --- a/telebot/formatting.py +++ b/telebot/formatting.py @@ -418,13 +418,16 @@ def apply_html_entities(text: str, entities: Optional[List], custom_subs: Option utf16_text = text.encode("utf-16-le") html_text = "" - def func(upd_text, subst_type=None, url=None, user=None, custom_emoji_id=None): + def func(upd_text, subst_type=None, url=None, user=None, custom_emoji_id=None, language=None): upd_text = upd_text.decode("utf-16-le") if subst_type == "text_mention": subst_type = "text_link" url = "tg://user?id={0}".format(user.id) elif subst_type == "mention": url = "https://t.me/{0}".format(upd_text[1:]) + elif subst_type == "pre": + if language is not None: + return '
{1}
'.format(language, upd_text) upd_text = upd_text.replace("&", "&").replace("<", "<").replace(">", ">") if not subst_type or not _subs.get(subst_type): return upd_text @@ -444,14 +447,16 @@ def func(upd_text, subst_type=None, url=None, user=None, custom_emoji_id=None): offset = entity.offset new_string = func(utf16_text[offset * 2: (offset + entity.length) * 2], subst_type=entity.type, - url=entity.url, user=entity.user, custom_emoji_id=entity.custom_emoji_id) + url=entity.url, user=entity.user, custom_emoji_id=entity.custom_emoji_id, + language=entity.language) start_index = len(html_text) html_text += new_string offset += entity.length end_index = len(html_text) elif entity.offset == offset: new_string = func(utf16_text[offset * 2: (offset + entity.length) * 2], subst_type=entity.type, - url=entity.url, user=entity.user, custom_emoji_id=entity.custom_emoji_id) + url=entity.url, user=entity.user, custom_emoji_id=entity.custom_emoji_id, + language=entity.language) start_index = len(html_text) html_text += new_string end_index = len(html_text) @@ -463,7 +468,8 @@ def func(upd_text, subst_type=None, url=None, user=None, custom_emoji_id=None): # And we don't change it). entity_string = html_text[start_index: end_index].encode("utf-16-le") formatted_string = func(entity_string, subst_type=entity.type, url=entity.url, user=entity.user, - custom_emoji_id=entity.custom_emoji_id). \ + custom_emoji_id=entity.custom_emoji_id, + language=entity.language). \ replace("&", "&").replace("<", "<").replace(">", ">") html_text = html_text[:start_index] + formatted_string + html_text[end_index:] end_index = len(html_text) From e270371d0277af3a1b197826bc5a07f3035bd42e Mon Sep 17 00:00:00 2001 From: pplulee Date: Sun, 6 Apr 2025 12:11:06 +0800 Subject: [PATCH 2/3] Add test for HTML parsing --- tests/test_telebot.py | 80 +++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/tests/test_telebot.py b/tests/test_telebot.py index 8b04ac402..4c364d952 100644 --- a/tests/test_telebot.py +++ b/tests/test_telebot.py @@ -44,11 +44,11 @@ def test_message_listener(self): def listener(messages): assert len(messages) == 100 - tb = telebot.TeleBot('') + tb = telebot.TeleBot(TOKEN) tb.set_update_listener(listener) def test_message_handler(self): - tb = telebot.TeleBot('') + tb = telebot.TeleBot(TOKEN) msg = self.create_text_message('/help') @tb.message_handler(commands=['help', 'start']) @@ -60,7 +60,7 @@ def command_handler(message): assert msg.text == 'got' def test_message_handler_reg(self): - bot = telebot.TeleBot('') + bot = telebot.TeleBot(TOKEN) msg = self.create_text_message(r'https://web.telegram.org/') # noinspection PyUnusedLocal @@ -73,7 +73,7 @@ def command_url(message): assert msg.text == 'got' def test_message_handler_lambda(self): - bot = telebot.TeleBot('') + bot = telebot.TeleBot(TOKEN) msg = self.create_text_message(r'lambda_text') # noinspection PyUnusedLocal @@ -86,7 +86,7 @@ def command_url(message): assert msg.text == 'got' def test_message_handler_lambda_fail(self): - bot = telebot.TeleBot('') + bot = telebot.TeleBot(TOKEN) msg = self.create_text_message(r'text') # noinspection PyUnusedLocal @@ -99,7 +99,7 @@ def command_url(message): assert not msg.text == 'got' def test_message_handler_reg_fail(self): - bot = telebot.TeleBot('') + bot = telebot.TeleBot(TOKEN) msg = self.create_text_message(r'web.telegram.org/') # noinspection PyUnusedLocal @@ -147,6 +147,7 @@ def test_send_file_with_filename(self): ret_msg = tb.send_document(CHAT_ID, file_data) assert ret_msg.message_id + file_data.seek(0) ret_msg = tb.send_document(CHAT_ID, file_data, visible_file_name="test.jpg") assert ret_msg.message_id @@ -529,28 +530,31 @@ def create_message_update(text): params = {'text': text} chat = types.User(11, False, 'test') message = types.Message(1, None, None, chat, 'text', params, "") - edited_message = None - channel_post = None - edited_channel_post = None - inline_query = None - chosen_inline_result = None - callback_query = None - shipping_query = None - pre_checkout_query = None - poll = None - poll_answer = None - my_chat_member = None - chat_member = None - chat_join_request = None - message_reaction = None - message_reaction_count = None - chat_boost = None - chat_boost_removed = None - purchased_paid_media = None - return types.Update(-1001234038283, message, edited_message, channel_post, edited_channel_post, inline_query, - chosen_inline_result, callback_query, shipping_query, pre_checkout_query, poll, poll_answer, - my_chat_member, chat_member, chat_join_request, message_reaction, message_reaction_count, chat_boost, chat_boost_removed, - purchased_paid_media) + return types.Update( + update_id=-1001234038283, + message=message, + edited_message=None, + channel_post=None, + edited_channel_post=None, + inline_query=None, + chosen_inline_result=None, + callback_query=None, + shipping_query=None, + pre_checkout_query=None, + poll=None, + poll_answer=None, + my_chat_member=None, + chat_member=None, + chat_join_request=None, + message_reaction=None, + message_reaction_count=None, + chat_boost=None, + removed_chat_boost=None, + purchased_paid_media=None, + business_message=None, + business_connection=None, + edited_business_message=None, + deleted_business_messages=None, ) def test_is_string_unicode(self): s1 = u'string' @@ -657,7 +661,7 @@ def test_typed_middleware_handler(self): apihelper.ENABLE_MIDDLEWARE = True - tb = telebot.TeleBot('') + tb = telebot.TeleBot(TOKEN) update = self.create_message_update('/help') # noinspection PyUnusedLocal @@ -678,7 +682,7 @@ def test_default_middleware_handler(self): apihelper.ENABLE_MIDDLEWARE = True - tb = telebot.TeleBot('') + tb = telebot.TeleBot(TOKEN) update = self.create_message_update('/help') # noinspection PyUnusedLocal @@ -703,3 +707,19 @@ def test_chat_permissions(self): #tb = telebot.TeleBot(TOKEN) #permissions = types.ChatPermissions(can_send_messages=True, can_send_polls=False) #msg = tb.set_chat_permissions(CHAT_ID, permissions) + + def test_apply_html_entities(self): + text = { + "*bold*": "bold", + "__italic__": "italic", + "~strikethrough~": "strikethrough", + "`inline code`": "inline code", + "```\ncode block```": "
code block
", + "```python\nprint('Hello, world!')\n```": "
print('Hello, world!')
", + "[link](http://example.com/)": "link", + ">blockquote": "
blockquote
", + } + tb = telebot.TeleBot(TOKEN) + for key, value in text.items(): + ret_msg = tb.send_message(CHAT_ID, text=key, parse_mode='MarkdownV2') + assert telebot.formatting.apply_html_entities(ret_msg.text, ret_msg.entities, None) == value From d25dae870fc88bad9ff9e62a90587b07bed45eb0 Mon Sep 17 00:00:00 2001 From: pplulee Date: Sun, 6 Apr 2025 22:03:01 +0800 Subject: [PATCH 3/3] Fix special character conversion --- telebot/formatting.py | 5 ++--- tests/test_telebot.py | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/telebot/formatting.py b/telebot/formatting.py index aa24c2007..0e300f7c1 100644 --- a/telebot/formatting.py +++ b/telebot/formatting.py @@ -425,15 +425,14 @@ def func(upd_text, subst_type=None, url=None, user=None, custom_emoji_id=None, l url = "tg://user?id={0}".format(user.id) elif subst_type == "mention": url = "https://t.me/{0}".format(upd_text[1:]) - elif subst_type == "pre": - if language is not None: - return '
{1}
'.format(language, upd_text) upd_text = upd_text.replace("&", "&").replace("<", "<").replace(">", ">") if not subst_type or not _subs.get(subst_type): return upd_text subs = _subs.get(subst_type) if subst_type == "custom_emoji": return subs.format(text=upd_text, custom_emoji_id=custom_emoji_id) + elif (subst_type == "pre") and language: + return "
{1}
".format(language, upd_text) return subs.format(text=upd_text, url=url) offset = 0 diff --git a/tests/test_telebot.py b/tests/test_telebot.py index 4c364d952..f395ff9c5 100644 --- a/tests/test_telebot.py +++ b/tests/test_telebot.py @@ -716,6 +716,7 @@ def test_apply_html_entities(self): "`inline code`": "inline code", "```\ncode block```": "
code block
", "```python\nprint('Hello, world!')\n```": "
print('Hello, world!')
", + "```python\nprint(1 < 2)\n```": "
print(1 < 2)
", "[link](http://example.com/)": "link", ">blockquote": "
blockquote
", }