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/].
"""This module contains an object that represents a Telegram Chat."""
from datetime import datetime
from html import escape
from typing import TYPE_CHECKING, ClassVar, List, Optional, Tuple, Union
from telegram import constants
@ -30,6 +31,9 @@ from telegram._telegramobject import TelegramObject
from telegram._utils import enum
from telegram._utils.defaultvalue import DEFAULT_NONE
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:
from telegram import (
@ -355,6 +359,107 @@ class Chat(TelegramObject):
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(
self,
*,

View file

@ -21,6 +21,7 @@ import pytest
from telegram import Bot, Chat, ChatLocation, ChatPermissions, Location, User
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
@ -880,6 +881,99 @@ class TestChat:
monkeypatch.setattr(chat.get_bot(), "decline_chat_join_request", make_assertion)
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):
a = Chat(self.id_, self.title, self.type_)
b = Chat(self.id_, self.title, self.type_)