Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API 6.8 #3853

Merged
merged 20 commits into from Sep 3, 2023
Merged

API 6.8 #3853

Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.rst
Expand Up @@ -14,7 +14,7 @@
:target: https://pypi.org/project/python-telegram-bot/
:alt: Supported Python versions

.. image:: https://img.shields.io/badge/Bot%20API-6.7-blue?logo=telegram
.. image:: https://img.shields.io/badge/Bot%20API-6.8-blue?logo=telegram
:target: https://core.telegram.org/bots/api-changelog
:alt: Supported Bot API versions

Expand Down Expand Up @@ -93,7 +93,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
Telegram API support
====================

All types and methods of the Telegram Bot API **6.7** are supported.
All types and methods of the Telegram Bot API **6.8** are supported.

Installing
==========
Expand Down
4 changes: 2 additions & 2 deletions README_RAW.rst
Expand Up @@ -14,7 +14,7 @@
:target: https://pypi.org/project/python-telegram-bot-raw/
:alt: Supported Python versions

.. image:: https://img.shields.io/badge/Bot%20API-6.7-blue?logo=telegram
.. image:: https://img.shields.io/badge/Bot%20API-6.8-blue?logo=telegram
:target: https://core.telegram.org/bots/api-changelog
:alt: Supported Bot API versions

Expand Down Expand Up @@ -89,7 +89,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
Telegram API support
====================

All types and methods of the Telegram Bot API **6.7** are supported.
All types and methods of the Telegram Bot API **6.8** are supported.

Installing
==========
Expand Down
2 changes: 2 additions & 0 deletions docs/source/inclusions/bot_methods.rst
Expand Up @@ -328,6 +328,8 @@
- Used to reopen the general topic
* - :meth:`~telegram.Bot.unpin_all_forum_topic_messages`
- Used to unpin all messages in a forum topic
* - :meth:`~telegram.Bot.unpin_all_general_forum_topic_messages`
- Used to unpin all messages in the general forum topic

.. raw:: html

Expand Down
1 change: 1 addition & 0 deletions docs/source/telegram.at-tree.rst
Expand Up @@ -79,6 +79,7 @@ Available Types
telegram.replykeyboardmarkup
telegram.replykeyboardremove
telegram.sentwebappmessage
telegram.story
telegram.switchinlinequerychosenchat
telegram.telegramobject
telegram.update
Expand Down
6 changes: 6 additions & 0 deletions docs/source/telegram.story.rst
@@ -0,0 +1,6 @@
Story
=====

.. autoclass:: telegram.Story
:members:
:show-inheritance:
2 changes: 2 additions & 0 deletions telegram/__init__.py
Expand Up @@ -170,6 +170,7 @@
"ShippingQuery",
"Sticker",
"StickerSet",
"Story",
"SuccessfulPayment",
"SwitchInlineQueryChosenChat",
"TelegramObject",
Expand Down Expand Up @@ -341,6 +342,7 @@
from ._replykeyboardremove import ReplyKeyboardRemove
from ._sentwebappmessage import SentWebAppMessage
from ._shared import ChatShared, UserShared
from ._story import Story
from ._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
from ._telegramobject import TelegramObject
from ._update import Update
Expand Down
42 changes: 42 additions & 0 deletions telegram/_bot.py
Expand Up @@ -7814,6 +7814,46 @@ async def unpin_all_forum_topic_messages(
api_kwargs=api_kwargs,
)

@_log
async def unpin_all_general_forum_topic_messages(
self,
chat_id: Union[str, int],
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> bool:
"""
Use this method to clear the list of pinned messages in a General forum topic. The bot must
be an administrator in the chat for this to work and must have
:paramref:`~telegram.ChatAdministratorRights.can_pin_messages` administrator rights in the
supergroup.

.. versionadded:: NEXT.VERSION

Args:
chat_id (:obj:`int` | :obj:`str`): |chat_id_group|

Returns:
:obj:`bool`: On success, :obj:`True` is returned.

Raises:
:class:`telegram.error.TelegramError`
"""
data: JSONDict = {"chat_id": chat_id}

return await self._post(
"unpinAllGeneralForumTopicMessages",
data,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)

@_log
async def edit_general_forum_topic(
self,
Expand Down Expand Up @@ -8527,3 +8567,5 @@ def __hash__(self) -> int:
"""Alias for :meth:`set_my_name`"""
getMyName = get_my_name
"""Alias for :meth:`get_my_name`"""
unpinAllGeneralForumTopicMessages = unpin_all_general_forum_topic_messages
"""Alias for :meth:`unpin_all_general_forum_topic_messages`"""
31 changes: 31 additions & 0 deletions telegram/_chat.py
Expand Up @@ -2904,6 +2904,37 @@ async def unpin_all_forum_topic_messages(
api_kwargs=api_kwargs,
)

async def unpin_all_general_forum_topic_messages(
self,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
) -> bool:
"""Shortcut for::

await bot.unpin_all_general_forum_topic_messages(chat_id=update.effective_chat.id,
*args, **kwargs)

For the documentation of the arguments, please see
:meth:`telegram.Bot.unpin_all_general_forum_topic_messages`.

.. versionadded:: NEXT.VERSION

Returns:
:obj:`bool`: On success, :obj:`True` is returned.
"""
return await self.get_bot().unpin_all_general_forum_topic_messages(
chat_id=self.id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=api_kwargs,
)

async def edit_general_forum_topic(
self,
name: str,
Expand Down
11 changes: 11 additions & 0 deletions telegram/_message.py
Expand Up @@ -53,6 +53,7 @@
from telegram._poll import Poll
from telegram._proximityalerttriggered import ProximityAlertTriggered
from telegram._shared import ChatShared, UserShared
from telegram._story import Story
from telegram._telegramobject import TelegramObject
from telegram._user import User
from telegram._utils.argumentparsing import parse_sequence_arg
Expand Down Expand Up @@ -201,6 +202,9 @@ class Message(TelegramObject):

sticker (:class:`telegram.Sticker`, optional): Message is a sticker, information
about the sticker.
story (:class:`telegram.Story`, optional): Message is a forwarded story.
harshil21 marked this conversation as resolved.
Show resolved Hide resolved

.. versionadded:: NEXT.VERSION
video (:class:`telegram.Video`, optional): Message is a video, information about the
video.
voice (:class:`telegram.Voice`, optional): Message is a voice message, information about
Expand Down Expand Up @@ -435,6 +439,9 @@ class Message(TelegramObject):
about the sticker.

.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
story (:class:`telegram.Story`): Optional. Message is a forwarded story.

.. versionadded:: NEXT.VERSION
video (:class:`telegram.Video`): Optional. Message is a video, information about the
video.

Expand Down Expand Up @@ -671,6 +678,7 @@ class Message(TelegramObject):
"has_media_spoiler",
"user_shared",
"chat_shared",
"story",
)

def __init__(
Expand Down Expand Up @@ -746,6 +754,7 @@ def __init__(
has_media_spoiler: Optional[bool] = None,
user_shared: Optional[UserShared] = None,
chat_shared: Optional[ChatShared] = None,
story: Optional[Story] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
Expand Down Expand Up @@ -834,6 +843,7 @@ def __init__(
self.has_media_spoiler: Optional[bool] = has_media_spoiler
self.user_shared: Optional[UserShared] = user_shared
self.chat_shared: Optional[ChatShared] = chat_shared
self.story: Optional[Story] = story

self._effective_attachment = DEFAULT_NONE

Expand Down Expand Up @@ -903,6 +913,7 @@ def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Message"]:
data["game"] = Game.de_json(data.get("game"), bot)
data["photo"] = PhotoSize.de_list(data.get("photo"), bot)
data["sticker"] = Sticker.de_json(data.get("sticker"), bot)
data["story"] = Story.de_json(data.get("story"), bot)
data["video"] = Video.de_json(data.get("video"), bot)
data["voice"] = Voice.de_json(data.get("voice"), bot)
data["video_note"] = VideoNote.de_json(data.get("video_note"), bot)
Expand Down
41 changes: 41 additions & 0 deletions telegram/_story.py
@@ -0,0 +1,41 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2023
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object related to a Telegram Story."""

from typing import Optional

from telegram._telegramobject import TelegramObject
from telegram._utils.types import JSONDict


class Story(TelegramObject):
"""
This object represents a message about a forwarded story in the chat. Currently holds no
information.

.. versionadded:: NEXT.VERSION

"""

__slots__ = ()

def __init__(self, *, api_kwargs: Optional[JSONDict] = None) -> None:
super().__init__(api_kwargs=api_kwargs)

self._freeze()
2 changes: 1 addition & 1 deletion telegram/constants.py
Expand Up @@ -116,7 +116,7 @@ def __str__(self) -> str:
#: :data:`telegram.__bot_api_version_info__`.
#:
#: .. versionadded:: 20.0
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=6, minor=7)
BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=6, minor=8)
#: :obj:`str`: Telegram Bot API
#: version supported by this version of `python-telegram-bot`. Also available as
#: :data:`telegram.__bot_api_version__`.
Expand Down
21 changes: 21 additions & 0 deletions telegram/ext/_extbot.py
Expand Up @@ -3486,6 +3486,26 @@ async def unpin_all_forum_topic_messages(
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
)

async def unpin_all_general_forum_topic_messages(
self,
chat_id: Union[str, int],
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
api_kwargs: Optional[JSONDict] = None,
rate_limit_args: Optional[RLARGS] = None,
) -> bool:
return await super().unpin_all_general_forum_topic_messages(
chat_id=chat_id,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
)

async def upload_sticker_file(
self,
user_id: Union[str, int],
Expand Down Expand Up @@ -3884,3 +3904,4 @@ async def set_sticker_mask_position(
setStickerMaskPosition = set_sticker_mask_position
setMyName = set_my_name
getMyName = get_my_name
unpinAllGeneralForumTopicMessages = unpin_all_general_forum_topic_messages
15 changes: 15 additions & 0 deletions telegram/ext/filters.py
Expand Up @@ -72,6 +72,7 @@
"REPLY",
"Regex",
"Sticker",
"STORY",
"SUCCESSFUL_PAYMENT",
"SenderChat",
"StatusUpdate",
Expand Down Expand Up @@ -2143,6 +2144,20 @@ def filter(self, message: Message) -> bool:
# neither mask nor emoji can be a message.sticker, so no filters for them


class _Story(MessageFilter):
__slots__ = ()

def filter(self, message: Message) -> bool:
return bool(message.story)


STORY = _Story(name="filters.STORY")
"""Messages that contain :attr:`telegram.Message.story`.

.. versionadded:: NEXT.VERSION
"""


class _SuccessfulPayment(MessageFilter):
__slots__ = ()

Expand Down
2 changes: 0 additions & 2 deletions tests/_utils/test_files.py
Expand Up @@ -33,8 +33,6 @@ class TestFiles:
@pytest.mark.parametrize(
("string", "expected"),
[
(str(data_file("game.gif")), True),
(str(TEST_DATA_PATH), False),
(str(data_file("game.gif")), True),
(str(TEST_DATA_PATH), False),
(data_file("game.gif"), True),
Expand Down
5 changes: 5 additions & 0 deletions tests/ext/test_filters.py
Expand Up @@ -884,6 +884,11 @@ def test_filters_sticker(self, update):
assert filters.Sticker.VIDEO.check_update(update)
assert filters.Sticker.PREMIUM.check_update(update)

def test_filters_story(self, update):
assert not filters.STORY.check_update(update)
update.message.story = "test"
assert filters.STORY.check_update(update)

def test_filters_video(self, update):
assert not filters.VIDEO.check_update(update)
update.message.video = "test"
Expand Down
25 changes: 25 additions & 0 deletions tests/test_chat.py
Expand Up @@ -1075,6 +1075,31 @@ async def make_assertion(*_, **kwargs):
monkeypatch.setattr(chat.get_bot(), "unpin_all_forum_topic_messages", make_assertion)
assert await chat.unpin_all_forum_topic_messages(message_thread_id=42)

async def test_unpin_all_general_forum_topic_messages(self, monkeypatch, chat):
async def make_assertion(*_, **kwargs):
return kwargs["chat_id"] == chat.id

assert check_shortcut_signature(
Chat.unpin_all_general_forum_topic_messages,
Bot.unpin_all_general_forum_topic_messages,
["chat_id"],
[],
)
assert await check_shortcut_call(
chat.unpin_all_general_forum_topic_messages,
chat.get_bot(),
"unpin_all_general_forum_topic_messages",
shortcut_kwargs=["chat_id"],
)
assert await check_defaults_handling(
chat.unpin_all_general_forum_topic_messages, chat.get_bot()
)

monkeypatch.setattr(
chat.get_bot(), "unpin_all_general_forum_topic_messages", make_assertion
)
assert await chat.unpin_all_general_forum_topic_messages()

async def test_edit_general_forum_topic(self, monkeypatch, chat):
async def make_assertion(*_, **kwargs):
return kwargs["chat_id"] == chat.id and kwargs["name"] == "WhatAName"
Expand Down