Add Methods Chat.mention_{html, markdown, markdown_v2} (#3308)

This commit is contained in:
miles 2022-10-31 16:45:21 +08:00 committed by GitHub
parent f68663af7e
commit 25dc87a633
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 199 additions and 0 deletions

View file

@ -19,6 +19,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/]. # along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Chat.""" """This module contains an object that represents a Telegram Chat."""
from datetime import datetime from datetime import datetime
from html import escape
from typing import TYPE_CHECKING, ClassVar, List, Optional, Tuple, Union from typing import TYPE_CHECKING, ClassVar, List, Optional, Tuple, Union
from telegram import constants from telegram import constants
@ -30,6 +31,9 @@ from telegram._telegramobject import TelegramObject
from telegram._utils import enum from telegram._utils import enum
from telegram._utils.defaultvalue import DEFAULT_NONE from telegram._utils.defaultvalue import DEFAULT_NONE
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
from telegram.helpers import escape_markdown
from telegram.helpers import mention_html as helpers_mention_html
from telegram.helpers import mention_markdown as helpers_mention_markdown
if TYPE_CHECKING: if TYPE_CHECKING:
from telegram import ( from telegram import (
@ -355,6 +359,107 @@ class Chat(TelegramObject):
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs) return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
def mention_markdown(self, name: str = None) -> str:
"""
Note:
:tg-const:`telegram.constants.ParseMode.MARKDOWN` is a legacy mode, retained by
Telegram for backward compatibility. You should use :meth:`mention_markdown_v2`
instead.
.. versionadded:: 20.0
Args:
name (:obj:`str`): The name used as a link for the chat. Defaults to :attr:`full_name`.
Returns:
:obj:`str`: The inline mention for the chat as markdown (version 1).
Raises:
:exc:`TypeError`: If the chat is a private chat and neither the :paramref:`name`
nor the :attr:`first_name` is set, then throw an :exc:`TypeError`.
If the chat is a public chat and neither the :paramref:`name` nor the :attr:`title`
is set, then throw an :exc:`TypeError`. If chat is a private group chat, then
throw an :exc:`TypeError`.
"""
if self.type == self.PRIVATE:
if name:
return helpers_mention_markdown(self.id, name)
if self.full_name:
return helpers_mention_markdown(self.id, self.full_name)
raise TypeError("Can not create a mention to a private chat without first name")
if self.username:
if name:
return f"[{name}]({self.link})"
if self.title:
return f"[{self.title}]({self.link})"
raise TypeError("Can not create a mention to a public chat without title")
raise TypeError("Can not create a mention to a private group chat")
def mention_markdown_v2(self, name: str = None) -> str:
"""
.. versionadded:: 20.0
Args:
name (:obj:`str`): The name used as a link for the chat. Defaults to :attr:`full_name`.
Returns:
:obj:`str`: The inline mention for the chat as markdown (version 2).
Raises:
:exc:`TypeError`: If the chat is a private chat and neither the :paramref:`name`
nor the :attr:`first_name` is set, then throw an :exc:`TypeError`.
If the chat is a public chat and neither the :paramref:`name` nor the :attr:`title`
is set, then throw an :exc:`TypeError`. If chat is a private group chat, then
throw an :exc:`TypeError`.
"""
if self.type == self.PRIVATE:
if name:
return helpers_mention_markdown(self.id, name, version=2)
if self.full_name:
return helpers_mention_markdown(self.id, self.full_name, version=2)
raise TypeError("Can not create a mention to a private chat without first name")
if self.username:
if name:
return f"[{escape_markdown(name, version=2)}]({self.link})"
if self.title:
return f"[{escape_markdown(self.title, version=2)}]({self.link})"
raise TypeError("Can not create a mention to a public chat without title")
raise TypeError("Can not create a mention to a private group chat")
def mention_html(self, name: str = None) -> str:
"""
.. versionadded:: 20.0
Args:
name (:obj:`str`): The name used as a link for the chat. Defaults to :attr:`full_name`.
Returns:
:obj:`str`: The inline mention for the chat as HTML.
Raises:
:exc:`TypeError`: If the chat is a private chat and neither the :paramref:`name`
nor the :attr:`first_name` is set, then throw an :exc:`TypeError`.
If the chat is a public chat and neither the :paramref:`name` nor the :attr:`title`
is set, then throw an :exc:`TypeError`. If chat is a private group chat, then
throw an :exc:`TypeError`.
"""
if self.type == self.PRIVATE:
if name:
return helpers_mention_html(self.id, name)
if self.full_name:
return helpers_mention_html(self.id, self.full_name)
raise TypeError("Can not create a mention to a private chat without first name")
if self.username:
if name:
return f'<a href="{self.link}">{escape(name)}</a>'
if self.title:
return f'<a href="{self.link}">{escape(self.title)}</a>'
raise TypeError("Can not create a mention to a public chat without title")
raise TypeError("Can not create a mention to a private group chat")
async def leave( async def leave(
self, self,
*, *,

View file

@ -21,6 +21,7 @@ import pytest
from telegram import Bot, Chat, ChatLocation, ChatPermissions, Location, User from telegram import Bot, Chat, ChatLocation, ChatPermissions, Location, User
from telegram.constants import ChatAction, ChatType from telegram.constants import ChatAction, ChatType
from telegram.helpers import escape_markdown
from tests.conftest import check_defaults_handling, check_shortcut_call, check_shortcut_signature from tests.conftest import check_defaults_handling, check_shortcut_call, check_shortcut_signature
@ -880,6 +881,99 @@ class TestChat:
monkeypatch.setattr(chat.get_bot(), "decline_chat_join_request", make_assertion) monkeypatch.setattr(chat.get_bot(), "decline_chat_join_request", make_assertion)
assert await chat.decline_join_request(user_id=42) assert await chat.decline_join_request(user_id=42)
def test_mention_html(self):
with pytest.raises(TypeError, match="Can not create a mention to a private group chat"):
chat = Chat(id=1, type="foo")
chat.mention_html()
expected = '<a href="tg://user?id={}">{}</a>'
chat = Chat(
id=1, type=Chat.PRIVATE, first_name="first\u2022name", last_name="last\u2022name"
)
assert chat.mention_html("the_name*\u2022") == expected.format(chat.id, "the_name*\u2022")
assert chat.mention_html() == expected.format(chat.id, chat.full_name)
with pytest.raises(
TypeError, match="Can not create a mention to a private chat without first name"
):
chat = Chat(id=1, type=Chat.PRIVATE, last_name="last\u2022name")
chat.mention_html()
expected = '<a href="https://t.me/{}">{}</a>'
chat = Chat(id=1, type="foo", username="user\u2022name", title="\u2022title")
assert chat.mention_html("the_name*\u2022") == expected.format(
chat.username, "the_name*\u2022"
)
assert chat.mention_html() == expected.format(chat.username, chat.title)
with pytest.raises(
TypeError, match="Can not create a mention to a public chat without title"
):
chat = Chat(id=1, type="foo", username="user\u2022name")
chat.mention_html()
def test_mention_markdown(self):
with pytest.raises(TypeError, match="Can not create a mention to a private group chat"):
chat = Chat(id=1, type="foo")
chat.mention_markdown()
expected = "[{}](tg://user?id={})"
chat = Chat(
id=1, type=Chat.PRIVATE, first_name="first\u2022name", last_name="last\u2022name"
)
assert chat.mention_markdown("the_name*\u2022") == expected.format(
"the_name*\u2022", chat.id
)
assert chat.mention_markdown() == expected.format(chat.full_name, chat.id)
with pytest.raises(
TypeError, match="Can not create a mention to a private chat without first name"
):
chat = Chat(id=1, type=Chat.PRIVATE, last_name="last\u2022name")
chat.mention_markdown()
expected = "[{}](https://t.me/{})"
chat = Chat(id=1, type="foo", username="user\u2022name", title="\u2022title")
assert chat.mention_markdown("the_name*\u2022") == expected.format(
"the_name*\u2022", chat.username
)
assert chat.mention_markdown() == expected.format(chat.title, chat.username)
with pytest.raises(
TypeError, match="Can not create a mention to a public chat without title"
):
chat = Chat(id=1, type="foo", username="user\u2022name")
chat.mention_markdown()
def test_mention_markdown_v2(self):
with pytest.raises(TypeError, match="Can not create a mention to a private group chat"):
chat = Chat(id=1, type="foo")
chat.mention_markdown_v2()
expected = "[{}](tg://user?id={})"
chat = Chat(id=1, type=Chat.PRIVATE, first_name="first{name", last_name="last_name")
assert chat.mention_markdown_v2("the{name>\u2022") == expected.format(
"the\\{name\\>\u2022", chat.id
)
assert chat.mention_markdown_v2() == expected.format(
escape_markdown(chat.full_name, version=2), chat.id
)
with pytest.raises(
TypeError, match="Can not create a mention to a private chat without first name"
):
chat = Chat(id=1, type=Chat.PRIVATE, last_name="last_name")
chat.mention_markdown_v2()
expected = "[{}](https://t.me/{})"
chat = Chat(id=1, type="foo", username="user{name", title="{title")
assert chat.mention_markdown_v2("the{name>\u2022") == expected.format(
"the\\{name\\>\u2022", chat.username
)
assert chat.mention_markdown_v2() == expected.format(
escape_markdown(chat.title, version=2), chat.username
)
with pytest.raises(
TypeError, match="Can not create a mention to a public chat without title"
):
chat = Chat(id=1, type="foo", username="user\u2022name")
chat.mention_markdown_v2()
def test_equality(self): def test_equality(self):
a = Chat(self.id_, self.title, self.type_) a = Chat(self.id_, self.title, self.type_)
b = Chat(self.id_, self.title, self.type_) b = Chat(self.id_, self.title, self.type_)