This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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/].
|
||||
"""Common base class for media objects"""
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import File
|
||||
|
||||
|
||||
class _BaseMedium(TelegramObject):
|
||||
"""Base class for objects representing the various media file types.
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`, optional): File size.
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): File identifier.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`): Optional. File size.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("file_id", "file_size", "file_unique_id")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
file_size: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
|
||||
# Required
|
||||
self.file_id: str = str(file_id)
|
||||
self.file_unique_id: str = str(file_unique_id)
|
||||
# Optionals
|
||||
self.file_size: Optional[int] = file_size
|
||||
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
async def get_file(
|
||||
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,
|
||||
) -> "File":
|
||||
"""Convenience wrapper over :meth:`telegram.Bot.get_file`
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.File`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
return await self.get_bot().get_file(
|
||||
file_id=self.file_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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/].
|
||||
"""Common base class for media objects with thumbnails"""
|
||||
from typing import TYPE_CHECKING, Optional, TypeVar
|
||||
|
||||
from telegram._files._basemedium import _BaseMedium
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._utils.argumentparsing import de_json_optional
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
ThumbedMT_co = TypeVar("ThumbedMT_co", bound="_BaseThumbedMedium", covariant=True)
|
||||
|
||||
|
||||
class _BaseThumbedMedium(_BaseMedium):
|
||||
"""
|
||||
Base class for objects representing the various media file types that may include a thumbnail.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`, optional): File size.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Thumbnail as defined by the sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): File identifier.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`): Optional. File size.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Thumbnail as defined by the sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("thumbnail",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
file_size: Optional[int] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
self.thumbnail: Optional[PhotoSize] = thumbnail
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls: type[ThumbedMT_co], data: JSONDict, bot: Optional["Bot"] = None
|
||||
) -> ThumbedMT_co:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
# In case this wasn't already done by the subclass
|
||||
if not isinstance(data.get("thumbnail"), PhotoSize):
|
||||
data["thumbnail"] = de_json_optional(data.get("thumbnail"), PhotoSize, bot)
|
||||
|
||||
api_kwargs = {}
|
||||
# This is a deprecated field that TG still returns for backwards compatibility
|
||||
# Let's filter it out to speed up the de-json process
|
||||
if data.get("thumb") is not None:
|
||||
api_kwargs["thumb"] = data.pop("thumb")
|
||||
|
||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 objects that represent paid media in Telegram."""
|
||||
|
||||
import datetime as dtm
|
||||
from typing import Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.inputfile import InputFile
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import to_timedelta
|
||||
from telegram._utils.files import parse_file_input
|
||||
from telegram._utils.types import FileInput, JSONDict
|
||||
|
||||
|
||||
class InputStoryContent(TelegramObject):
|
||||
"""This object describes the content of a story to post. Currently, it can be one of:
|
||||
|
||||
* :class:`telegram.InputStoryContentPhoto`
|
||||
* :class:`telegram.InputStoryContentVideo`
|
||||
|
||||
.. versionadded:: 22.1
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of the content.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the content.
|
||||
"""
|
||||
|
||||
__slots__ = ("type",)
|
||||
|
||||
PHOTO: Final[str] = constants.InputStoryContentType.PHOTO
|
||||
""":const:`telegram.constants.InputStoryContentType.PHOTO`"""
|
||||
VIDEO: Final[str] = constants.InputStoryContentType.VIDEO
|
||||
""":const:`telegram.constants.InputStoryContentType.VIDEO`"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.type: str = enum.get_member(constants.InputStoryContentType, type, type)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@staticmethod
|
||||
def _parse_file_input(file_input: FileInput) -> Union[str, InputFile]:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
return parse_file_input(file_input, attach=True, local_mode=True)
|
||||
|
||||
|
||||
class InputStoryContentPhoto(InputStoryContent):
|
||||
"""Describes a photo to post as a story.
|
||||
|
||||
.. versionadded:: 22.1
|
||||
|
||||
Args:
|
||||
photo (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): The photo to post as a story. The photo must be of the
|
||||
size :tg-const:`telegram.constants.InputStoryContentLimit.PHOTO_WIDTH`
|
||||
x :tg-const:`telegram.constants.InputStoryContentLimit.PHOTO_HEIGHT` and must not
|
||||
exceed :tg-const:`telegram.constants.InputStoryContentLimit.PHOTOSIZE_UPLOAD` MB.
|
||||
|uploadinputnopath|.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the content, must be :attr:`~telegram.InputStoryContent.PHOTO`.
|
||||
photo (:class:`telegram.InputFile`): The photo to post as a story. The photo must be of the
|
||||
size :tg-const:`telegram.constants.InputStoryContentLimit.PHOTO_WIDTH`
|
||||
x :tg-const:`telegram.constants.InputStoryContentLimit.PHOTO_HEIGHT` and must not
|
||||
exceed :tg-const:`telegram.constants.InputStoryContentLimit.PHOTOSIZE_UPLOAD` MB.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("photo",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
photo: FileInput,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(type=InputStoryContent.PHOTO, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.photo: Union[str, InputFile] = self._parse_file_input(photo)
|
||||
|
||||
|
||||
class InputStoryContentVideo(InputStoryContent):
|
||||
"""
|
||||
Describes a video to post as a story.
|
||||
|
||||
.. versionadded:: 22.1
|
||||
|
||||
Args:
|
||||
video (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): The video to post as a story. The video must be of
|
||||
the size :tg-const:`telegram.constants.InputStoryContentLimit.VIDEO_WIDTH`
|
||||
x :tg-const:`telegram.constants.InputStoryContentLimit.VIDEO_HEIGHT`,
|
||||
streamable, encoded with ``H.265`` codec, with key frames added
|
||||
each second in the ``MPEG4`` format, and must not exceed
|
||||
:tg-const:`telegram.constants.InputStoryContentLimit.VIDEOSIZE_UPLOAD` MB.
|
||||
|uploadinputnopath|.
|
||||
duration (:class:`datetime.timedelta` | :obj:`int` | :obj:`float`, optional): Precise
|
||||
duration of the video in seconds;
|
||||
0-:tg-const:`telegram.constants.InputStoryContentLimit.MAX_VIDEO_DURATION`
|
||||
cover_frame_timestamp (:class:`datetime.timedelta` | :obj:`int` | :obj:`float`, optional):
|
||||
Timestamp in seconds of the frame that will be used as the static cover for the story.
|
||||
Defaults to ``0.0``.
|
||||
is_animation (:obj:`bool`, optional): Pass :obj:`True` if the video has no sound
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the content, must be :attr:`~telegram.InputStoryContent.VIDEO`.
|
||||
video (:class:`telegram.InputFile`): The video to post as a story. The video must be of
|
||||
the size :tg-const:`telegram.constants.InputStoryContentLimit.VIDEO_WIDTH`
|
||||
x :tg-const:`telegram.constants.InputStoryContentLimit.VIDEO_HEIGHT`,
|
||||
streamable, encoded with ``H.265`` codec, with key frames added
|
||||
each second in the ``MPEG4`` format, and must not exceed
|
||||
:tg-const:`telegram.constants.InputStoryContentLimit.VIDEOSIZE_UPLOAD` MB.
|
||||
duration (:class:`datetime.timedelta`): Optional. Precise duration of the video in seconds;
|
||||
0-:tg-const:`telegram.constants.InputStoryContentLimit.MAX_VIDEO_DURATION`
|
||||
cover_frame_timestamp (:class:`datetime.timedelta`): Optional. Timestamp in seconds of the
|
||||
frame that will be used as the static cover for the story. Defaults to ``0.0``.
|
||||
is_animation (:obj:`bool`): Optional. Pass :obj:`True` if the video has no sound
|
||||
"""
|
||||
|
||||
__slots__ = ("cover_frame_timestamp", "duration", "is_animation", "video")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
video: FileInput,
|
||||
duration: Optional[Union[float, dtm.timedelta]] = None,
|
||||
cover_frame_timestamp: Optional[Union[float, dtm.timedelta]] = None,
|
||||
is_animation: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
) -> None:
|
||||
super().__init__(type=InputStoryContent.VIDEO, api_kwargs=api_kwargs)
|
||||
|
||||
with self._unfrozen():
|
||||
self.video: Union[str, InputFile] = self._parse_file_input(video)
|
||||
self.duration: Optional[dtm.timedelta] = to_timedelta(duration)
|
||||
self.cover_frame_timestamp: Optional[dtm.timedelta] = to_timedelta(
|
||||
cover_frame_timestamp
|
||||
)
|
||||
self.is_animation: Optional[bool] = is_animation
|
||||
119
.venv/lib/python3.12/site-packages/telegram/_files/animation.py
Normal file
119
.venv/lib/python3.12/site-packages/telegram/_files/animation.py
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram Animation."""
|
||||
import datetime as dtm
|
||||
from typing import Optional, Union
|
||||
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._utils.argumentparsing import to_timedelta
|
||||
from telegram._utils.datetime import get_timedelta_value
|
||||
from telegram._utils.types import JSONDict, TimePeriod
|
||||
|
||||
|
||||
class Animation(_BaseThumbedMedium):
|
||||
"""This object represents an animation file (GIF or H.264/MPEG-4 AVC video without sound).
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by the sender.
|
||||
height (:obj:`int`): Video height as defined by the sender.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`, optional): Duration of the video
|
||||
in seconds as defined by the sender.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
file_name (:obj:`str`, optional): Original animation filename as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Animation thumbnail as defined by
|
||||
sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by the sender.
|
||||
height (:obj:`int`): Video height as defined by the sender.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the video in seconds
|
||||
as defined by the sender.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
file_name (:obj:`str`): Optional. Original animation filename as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Animation thumbnail as defined by
|
||||
sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("_duration", "file_name", "height", "mime_type", "width")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
duration: TimePeriod,
|
||||
file_name: Optional[str] = None,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
api_kwargs=api_kwargs,
|
||||
thumbnail=thumbnail,
|
||||
)
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.width: int = width
|
||||
self.height: int = height
|
||||
self._duration: dtm.timedelta = to_timedelta(duration)
|
||||
# Optional
|
||||
self.mime_type: Optional[str] = mime_type
|
||||
self.file_name: Optional[str] = file_name
|
||||
|
||||
@property
|
||||
def duration(self) -> Union[int, dtm.timedelta]:
|
||||
return get_timedelta_value( # type: ignore[return-value]
|
||||
self._duration, attribute="duration"
|
||||
)
|
||||
121
.venv/lib/python3.12/site-packages/telegram/_files/audio.py
Normal file
121
.venv/lib/python3.12/site-packages/telegram/_files/audio.py
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram Audio."""
|
||||
import datetime as dtm
|
||||
from typing import Optional, Union
|
||||
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._utils.argumentparsing import to_timedelta
|
||||
from telegram._utils.datetime import get_timedelta_value
|
||||
from telegram._utils.types import JSONDict, TimePeriod
|
||||
|
||||
|
||||
class Audio(_BaseThumbedMedium):
|
||||
"""This object represents an audio file to be treated as music by the Telegram clients.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the audio in
|
||||
seconds as defined by the sender.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by the sender or by
|
||||
audio tags.
|
||||
title (:obj:`str`, optional): Title of the audio as defined by the sender or by audio tags.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Thumbnail of the album cover to
|
||||
which the music file belongs.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the audio in seconds as
|
||||
defined by the sender.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
performer (:obj:`str`): Optional. Performer of the audio as defined by the sender or by
|
||||
audio tags.
|
||||
title (:obj:`str`): Optional. Title of the audio as defined by the sender or by audio tags.
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Thumbnail of the album cover to
|
||||
which the music file belongs.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("_duration", "file_name", "mime_type", "performer", "title")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
duration: TimePeriod,
|
||||
performer: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
file_name: Optional[str] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self._duration: dtm.timedelta = to_timedelta(duration)
|
||||
# Optional
|
||||
self.performer: Optional[str] = performer
|
||||
self.title: Optional[str] = title
|
||||
self.mime_type: Optional[str] = mime_type
|
||||
self.file_name: Optional[str] = file_name
|
||||
|
||||
@property
|
||||
def duration(self) -> Union[int, dtm.timedelta]:
|
||||
return get_timedelta_value( # type: ignore[return-value]
|
||||
self._duration, attribute="duration"
|
||||
)
|
||||
176
.venv/lib/python3.12/site-packages/telegram/_files/chatphoto.py
Normal file
176
.venv/lib/python3.12/site-packages/telegram/_files/chatphoto.py
Normal file
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram ChatPhoto."""
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import File
|
||||
|
||||
|
||||
class ChatPhoto(TelegramObject):
|
||||
"""This object represents a chat photo.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`small_file_unique_id` and :attr:`big_file_unique_id` are
|
||||
equal.
|
||||
|
||||
Args:
|
||||
small_file_id (:obj:`str`): File identifier of small
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_SMALL` x :tg-const:`telegram.ChatPhoto.SIZE_SMALL`)
|
||||
chat photo. This file_id can be used only for photo download and only for as long
|
||||
as the photo is not changed.
|
||||
small_file_unique_id (:obj:`str`): Unique file identifier of small
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_SMALL` x :tg-const:`telegram.ChatPhoto.SIZE_SMALL`)
|
||||
chat photo, which is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
big_file_id (:obj:`str`): File identifier of big
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_BIG` x :tg-const:`telegram.ChatPhoto.SIZE_BIG`)
|
||||
chat photo. This file_id can be used only for photo download and only for as long as
|
||||
the photo is not changed.
|
||||
big_file_unique_id (:obj:`str`): Unique file identifier of big
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_BIG` x :tg-const:`telegram.ChatPhoto.SIZE_BIG`)
|
||||
chat photo, which is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
|
||||
Attributes:
|
||||
small_file_id (:obj:`str`): File identifier of small
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_SMALL` x :tg-const:`telegram.ChatPhoto.SIZE_SMALL`)
|
||||
chat photo. This file_id can be used only for photo download and only for as long
|
||||
as the photo is not changed.
|
||||
small_file_unique_id (:obj:`str`): Unique file identifier of small
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_SMALL` x :tg-const:`telegram.ChatPhoto.SIZE_SMALL`)
|
||||
chat photo, which is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
big_file_id (:obj:`str`): File identifier of big
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_BIG` x :tg-const:`telegram.ChatPhoto.SIZE_BIG`)
|
||||
chat photo. This file_id can be used only for photo download and only for as long as
|
||||
the photo is not changed.
|
||||
big_file_unique_id (:obj:`str`): Unique file identifier of big
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_BIG` x :tg-const:`telegram.ChatPhoto.SIZE_BIG`)
|
||||
chat photo, which is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"big_file_id",
|
||||
"big_file_unique_id",
|
||||
"small_file_id",
|
||||
"small_file_unique_id",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
small_file_id: str,
|
||||
small_file_unique_id: str,
|
||||
big_file_id: str,
|
||||
big_file_unique_id: str,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.small_file_id: str = small_file_id
|
||||
self.small_file_unique_id: str = small_file_unique_id
|
||||
self.big_file_id: str = big_file_id
|
||||
self.big_file_unique_id: str = big_file_unique_id
|
||||
|
||||
self._id_attrs = (
|
||||
self.small_file_unique_id,
|
||||
self.big_file_unique_id,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
async def get_small_file(
|
||||
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,
|
||||
) -> "File":
|
||||
"""Convenience wrapper over :meth:`telegram.Bot.get_file` for getting the small
|
||||
(:tg-const:`telegram.ChatPhoto.SIZE_SMALL` x :tg-const:`telegram.ChatPhoto.SIZE_SMALL`)
|
||||
chat photo
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.File`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
return await self.get_bot().get_file(
|
||||
file_id=self.small_file_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
async def get_big_file(
|
||||
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,
|
||||
) -> "File":
|
||||
"""Convenience wrapper over :meth:`telegram.Bot.get_file` for getting the
|
||||
big (:tg-const:`telegram.ChatPhoto.SIZE_BIG` x :tg-const:`telegram.ChatPhoto.SIZE_BIG`)
|
||||
chat photo
|
||||
|
||||
For the documentation of the arguments, please see :meth:`telegram.Bot.get_file`.
|
||||
|
||||
Returns:
|
||||
:class:`telegram.File`
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
||||
"""
|
||||
return await self.get_bot().get_file(
|
||||
file_id=self.big_file_id,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
SIZE_SMALL: Final[int] = constants.ChatPhotoSize.SMALL
|
||||
""":const:`telegram.constants.ChatPhotoSize.SMALL`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
SIZE_BIG: Final[int] = constants.ChatPhotoSize.BIG
|
||||
""":const:`telegram.constants.ChatPhotoSize.BIG`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram Contact."""
|
||||
from typing import Optional
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
||||
class Contact(TelegramObject):
|
||||
"""This object represents a phone contact.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`phone_number` is equal.
|
||||
|
||||
Args:
|
||||
phone_number (:obj:`str`): Contact's phone number.
|
||||
first_name (:obj:`str`): Contact's first name.
|
||||
last_name (:obj:`str`, optional): Contact's last name.
|
||||
user_id (:obj:`int`, optional): Contact's user identifier in Telegram.
|
||||
vcard (:obj:`str`, optional): Additional data about the contact in the form of a vCard.
|
||||
|
||||
Attributes:
|
||||
phone_number (:obj:`str`): Contact's phone number.
|
||||
first_name (:obj:`str`): Contact's first name.
|
||||
last_name (:obj:`str`): Optional. Contact's last name.
|
||||
user_id (:obj:`int`): Optional. Contact's user identifier in Telegram.
|
||||
vcard (:obj:`str`): Optional. Additional data about the contact in the form of a vCard.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("first_name", "last_name", "phone_number", "user_id", "vcard")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
phone_number: str,
|
||||
first_name: str,
|
||||
last_name: Optional[str] = None,
|
||||
user_id: Optional[int] = None,
|
||||
vcard: Optional[str] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.phone_number: str = str(phone_number)
|
||||
self.first_name: str = first_name
|
||||
# Optionals
|
||||
self.last_name: Optional[str] = last_name
|
||||
self.user_id: Optional[int] = user_id
|
||||
self.vcard: Optional[str] = vcard
|
||||
|
||||
self._id_attrs = (self.phone_number,)
|
||||
|
||||
self._freeze()
|
||||
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram Document."""
|
||||
from typing import Optional
|
||||
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
||||
class Document(_BaseThumbedMedium):
|
||||
"""This object represents a general file
|
||||
(as opposed to photos, voice messages and audio files).
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
file_name (:obj:`str`, optional): Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Document thumbnail as defined by the
|
||||
sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which is supposed to be
|
||||
the same over time and for different bots. Can't be used to download or reuse the file.
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Document thumbnail as defined by the
|
||||
sender.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("file_name", "mime_type")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
file_name: Optional[str] = None,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
# Optional
|
||||
self.mime_type: Optional[str] = mime_type
|
||||
self.file_name: Optional[str] = file_name
|
||||
371
.venv/lib/python3.12/site-packages/telegram/_files/file.py
Normal file
371
.venv/lib/python3.12/site-packages/telegram/_files/file.py
Normal file
@@ -0,0 +1,371 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram File."""
|
||||
import shutil
|
||||
import urllib.parse as urllib_parse
|
||||
from base64 import b64decode
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, BinaryIO, Optional
|
||||
|
||||
from telegram._passport.credentials import decrypt
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.files import is_local_file
|
||||
from telegram._utils.types import FilePathInput, JSONDict, ODVInput
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import FileCredentials
|
||||
|
||||
|
||||
class File(TelegramObject):
|
||||
"""
|
||||
This object represents a file ready to be downloaded. The file can be e.g. downloaded with
|
||||
:attr:`download_to_drive`. It is guaranteed that the link will be valid for at least 1 hour.
|
||||
When the link expires, a new one can be requested by calling :meth:`telegram.Bot.get_file`.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
``download`` was split into :meth:`download_to_drive` and :meth:`download_to_memory`.
|
||||
|
||||
Note:
|
||||
* Maximum file size to download is
|
||||
:tg-const:`telegram.constants.FileSizeLimit.FILESIZE_DOWNLOAD`.
|
||||
* If you obtain an instance of this class from :attr:`telegram.PassportFile.get_file`,
|
||||
then it will automatically be decrypted as it downloads when you call e.g.
|
||||
:meth:`download_to_drive`.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`, optional): File size in bytes, if known.
|
||||
file_path (:obj:`str`, optional): File path. Use e.g. :meth:`download_to_drive` to get the
|
||||
file.
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
file_size (:obj:`int`): Optional. File size in bytes, if known.
|
||||
file_path (:obj:`str`): Optional. File path. Use e.g. :meth:`download_to_drive` to get the
|
||||
file.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"_credentials",
|
||||
"file_id",
|
||||
"file_path",
|
||||
"file_size",
|
||||
"file_unique_id",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
file_size: Optional[int] = None,
|
||||
file_path: Optional[str] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
|
||||
# Required
|
||||
self.file_id: str = str(file_id)
|
||||
self.file_unique_id: str = str(file_unique_id)
|
||||
# Optionals
|
||||
self.file_size: Optional[int] = file_size
|
||||
self.file_path: Optional[str] = file_path
|
||||
|
||||
self._credentials: Optional[FileCredentials] = None
|
||||
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
def _get_encoded_url(self) -> str:
|
||||
"""Convert any UTF-8 char in :obj:`File.file_path` into a url encoded ASCII string."""
|
||||
sres = urllib_parse.urlsplit(str(self.file_path))
|
||||
return urllib_parse.urlunsplit(
|
||||
urllib_parse.SplitResult(
|
||||
sres.scheme, sres.netloc, urllib_parse.quote(sres.path), sres.query, sres.fragment
|
||||
)
|
||||
)
|
||||
|
||||
def _prepare_decrypt(self, buf: bytes) -> bytes:
|
||||
return decrypt(b64decode(self._credentials.secret), b64decode(self._credentials.hash), buf)
|
||||
|
||||
async def download_to_drive(
|
||||
self,
|
||||
custom_path: Optional[FilePathInput] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
) -> Path:
|
||||
"""
|
||||
Download this file. By default, the file is saved in the current working directory with
|
||||
:attr:`file_path` as file name. If :paramref:`custom_path` is supplied as a :obj:`str` or
|
||||
:obj:`pathlib.Path`, it will be saved to that path.
|
||||
|
||||
Note:
|
||||
If :paramref:`custom_path` isn't provided and :attr:`file_path` is the path of a
|
||||
local file (which is the case when a Bot API Server is running in local mode), this
|
||||
method will just return the path.
|
||||
|
||||
The only exception to this are encrypted files (e.g. a passport file). For these, a
|
||||
file with the prefix `decrypted_` will be created in the same directory as the
|
||||
original file in order to decrypt the file without changing the existing one
|
||||
in-place.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* :paramref:`custom_path` parameter now also accepts :class:`pathlib.Path` as argument.
|
||||
* Returns :class:`pathlib.Path` object in cases where previously a :obj:`str` was
|
||||
returned.
|
||||
* This method was previously called ``download``. It was split into
|
||||
:meth:`download_to_drive` and :meth:`download_to_memory`.
|
||||
|
||||
.. versionchanged:: 21.7
|
||||
Raises :exc:`RuntimeError` if :attr:`file_path` is not set. Note that files without
|
||||
a :attr:`file_path` could never be downloaded, as this attribute is mandatory for that
|
||||
operation.
|
||||
|
||||
Args:
|
||||
custom_path (:class:`pathlib.Path` | :obj:`str` , optional): The path where the file
|
||||
will be saved to. If not specified, will be saved in the current working directory
|
||||
with :attr:`file_path` as file name or the :attr:`file_id` if :attr:`file_path`
|
||||
is not set.
|
||||
|
||||
Keyword Args:
|
||||
read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
|
||||
Returns:
|
||||
:class:`pathlib.Path`: Returns the Path object the file was downloaded to.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If :attr:`file_path` is not set.
|
||||
|
||||
"""
|
||||
if not self.file_path:
|
||||
raise RuntimeError("No `file_path` available for this file. Can not download.")
|
||||
|
||||
local_file = is_local_file(self.file_path)
|
||||
url = None if local_file else self._get_encoded_url()
|
||||
|
||||
# if _credentials exists we want to decrypt the file
|
||||
if local_file and self._credentials:
|
||||
file_to_decrypt = Path(self.file_path)
|
||||
buf = self._prepare_decrypt(file_to_decrypt.read_bytes())
|
||||
if custom_path is not None:
|
||||
path = Path(custom_path)
|
||||
else:
|
||||
path = Path(str(file_to_decrypt.parent) + "/decrypted_" + file_to_decrypt.name)
|
||||
path.write_bytes(buf)
|
||||
return path
|
||||
|
||||
if custom_path is not None and local_file:
|
||||
shutil.copyfile(self.file_path, str(custom_path))
|
||||
return Path(custom_path)
|
||||
|
||||
if custom_path:
|
||||
filename = Path(custom_path)
|
||||
elif local_file:
|
||||
return Path(self.file_path)
|
||||
else:
|
||||
filename = Path(Path(self.file_path).name)
|
||||
|
||||
buf = await self.get_bot().request.retrieve(
|
||||
url,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
)
|
||||
if self._credentials:
|
||||
buf = self._prepare_decrypt(buf)
|
||||
filename.write_bytes(buf)
|
||||
return filename
|
||||
|
||||
async def download_to_memory(
|
||||
self,
|
||||
out: BinaryIO,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
) -> None:
|
||||
"""
|
||||
Download this file into memory. :paramref:`out` needs to be supplied with a
|
||||
:obj:`io.BufferedIOBase`, the file contents will be saved to that object using the
|
||||
:obj:`out.write<io.BufferedIOBase.write>` method.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
Hint:
|
||||
If you want to immediately read the data from ``out`` after calling this method, you
|
||||
should call ``out.seek(0)`` first. See also :meth:`io.IOBase.seek`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
.. versionchanged:: 21.7
|
||||
Raises :exc:`RuntimeError` if :attr:`file_path` is not set. Note that files without
|
||||
a :attr:`file_path` could never be downloaded, as this attribute is mandatory for that
|
||||
operation.
|
||||
|
||||
Args:
|
||||
out (:obj:`io.BufferedIOBase`): A file-like object. Must be opened for writing in
|
||||
binary mode.
|
||||
|
||||
Keyword Args:
|
||||
read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If :attr:`file_path` is not set.
|
||||
"""
|
||||
if not self.file_path:
|
||||
raise RuntimeError("No `file_path` available for this file. Can not download.")
|
||||
|
||||
local_file = is_local_file(self.file_path)
|
||||
url = None if local_file else self._get_encoded_url()
|
||||
path = Path(self.file_path) if local_file else None
|
||||
if local_file:
|
||||
buf = path.read_bytes()
|
||||
else:
|
||||
buf = await self.get_bot().request.retrieve(
|
||||
url,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
)
|
||||
if self._credentials:
|
||||
buf = self._prepare_decrypt(buf)
|
||||
out.write(buf)
|
||||
|
||||
async def download_as_bytearray(
|
||||
self,
|
||||
buf: Optional[bytearray] = None,
|
||||
*,
|
||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
) -> bytearray:
|
||||
"""Download this file and return it as a bytearray.
|
||||
|
||||
.. versionchanged:: 21.7
|
||||
Raises :exc:`RuntimeError` if :attr:`file_path` is not set. Note that files without
|
||||
a :attr:`file_path` could never be downloaded, as this attribute is mandatory for that
|
||||
operation.
|
||||
|
||||
Args:
|
||||
buf (:obj:`bytearray`, optional): Extend the given bytearray with the downloaded data.
|
||||
|
||||
Keyword Args:
|
||||
read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
|
||||
:paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
|
||||
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
Returns:
|
||||
:obj:`bytearray`: The same object as :paramref:`buf` if it was specified. Otherwise a
|
||||
newly allocated :obj:`bytearray`.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If :attr:`file_path` is not set.
|
||||
|
||||
"""
|
||||
if not self.file_path:
|
||||
raise RuntimeError("No `file_path` available for this file. Can not download.")
|
||||
|
||||
if buf is None:
|
||||
buf = bytearray()
|
||||
|
||||
if is_local_file(self.file_path):
|
||||
bytes_data = Path(self.file_path).read_bytes()
|
||||
else:
|
||||
bytes_data = await self.get_bot().request.retrieve(
|
||||
self._get_encoded_url(),
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
)
|
||||
if self._credentials:
|
||||
buf.extend(self._prepare_decrypt(bytes_data))
|
||||
else:
|
||||
buf.extend(bytes_data)
|
||||
return buf
|
||||
|
||||
def set_credentials(self, credentials: "FileCredentials") -> None:
|
||||
"""Sets the passport credentials for the file.
|
||||
|
||||
Args:
|
||||
credentials (:class:`telegram.FileCredentials`): The credentials.
|
||||
"""
|
||||
self._credentials = credentials
|
||||
142
.venv/lib/python3.12/site-packages/telegram/_files/inputfile.py
Normal file
142
.venv/lib/python3.12/site-packages/telegram/_files/inputfile.py
Normal file
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram InputFile."""
|
||||
|
||||
import mimetypes
|
||||
from typing import IO, Optional, Union
|
||||
from uuid import uuid4
|
||||
|
||||
from telegram._utils.files import guess_file_name, load_file
|
||||
from telegram._utils.strings import TextEncoding
|
||||
from telegram._utils.types import FieldTuple
|
||||
|
||||
_DEFAULT_MIME_TYPE = "application/octet-stream"
|
||||
|
||||
|
||||
class InputFile:
|
||||
"""This object represents a Telegram InputFile.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* The former attribute ``attach`` was renamed to :attr:`attach_name`.
|
||||
* Method ``is_image`` was removed. If you pass :obj:`bytes` to :paramref:`obj` and would
|
||||
like to have the mime type automatically guessed, please pass :paramref:`filename`
|
||||
in addition.
|
||||
|
||||
Args:
|
||||
obj (:term:`file object` | :obj:`bytes` | :obj:`str`): An open file descriptor or the files
|
||||
content as bytes or string.
|
||||
|
||||
Note:
|
||||
If :paramref:`obj` is a string, it will be encoded as bytes via
|
||||
:external:obj:`obj.encode('utf-8') <str.encode>`.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
Accept string input.
|
||||
filename (:obj:`str`, optional): Filename for this InputFile.
|
||||
attach (:obj:`bool`, optional): Pass :obj:`True` if the parameter this file belongs to in
|
||||
the request to Telegram should point to the multipart data via an ``attach://`` URI.
|
||||
Defaults to `False`.
|
||||
read_file_handle (:obj:`bool`, optional): If :obj:`True` and :paramref:`obj` is a file
|
||||
handle, the data will be read from the file handle on initialization of this object.
|
||||
If :obj:`False`, the file handle will be passed on to the
|
||||
:attr:`networking backend <telegram.request.BaseRequest.do_request>` which will have
|
||||
to handle the reading. Defaults to :obj:`True`.
|
||||
|
||||
Tip:
|
||||
If you upload extremely large files, you may want to set this to :obj:`False` to
|
||||
avoid reading the complete file into memory. Additionally, this may be supported
|
||||
better by the networking backend (in particular it is handled better by
|
||||
the default :class:`~telegram.request.HTTPXRequest`).
|
||||
|
||||
Important:
|
||||
If you set this to :obj:`False`, you have to ensure that the file handle is still
|
||||
open when the request is made. In particular, the following snippet can *not* work
|
||||
as expected.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with open('file.txt', 'rb') as file:
|
||||
input_file = InputFile(file, read_file_handle=False)
|
||||
|
||||
# here the file handle is already closed and the upload will fail
|
||||
await bot.send_document(chat_id, input_file)
|
||||
|
||||
.. versionadded:: 21.5
|
||||
|
||||
|
||||
Attributes:
|
||||
input_file_content (:obj:`bytes` | :class:`IO`): The binary content of the file to send.
|
||||
attach_name (:obj:`str`): Optional. If present, the parameter this file belongs to in
|
||||
the request to Telegram should point to the multipart data via a an URI of the form
|
||||
``attach://<attach_name>`` URI.
|
||||
filename (:obj:`str`): Filename for the file to be sent.
|
||||
mimetype (:obj:`str`): The mimetype inferred from the file to be sent.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("attach_name", "filename", "input_file_content", "mimetype")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
obj: Union[IO[bytes], bytes, str],
|
||||
filename: Optional[str] = None,
|
||||
attach: bool = False,
|
||||
read_file_handle: bool = True,
|
||||
):
|
||||
if isinstance(obj, bytes):
|
||||
self.input_file_content: Union[bytes, IO[bytes]] = obj
|
||||
elif isinstance(obj, str):
|
||||
self.input_file_content = obj.encode(TextEncoding.UTF_8)
|
||||
elif read_file_handle:
|
||||
reported_filename, self.input_file_content = load_file(obj)
|
||||
filename = filename or reported_filename
|
||||
else:
|
||||
self.input_file_content = obj
|
||||
filename = filename or guess_file_name(obj)
|
||||
|
||||
self.attach_name: Optional[str] = "attached" + uuid4().hex if attach else None
|
||||
|
||||
if filename:
|
||||
self.mimetype: str = (
|
||||
mimetypes.guess_type(filename, strict=False)[0] or _DEFAULT_MIME_TYPE
|
||||
)
|
||||
else:
|
||||
self.mimetype = _DEFAULT_MIME_TYPE
|
||||
|
||||
self.filename: str = filename or self.mimetype.replace("/", ".")
|
||||
|
||||
@property
|
||||
def field_tuple(self) -> FieldTuple:
|
||||
"""Field tuple representing the contents of the file for upload to the Telegram servers.
|
||||
|
||||
.. versionchanged:: 21.5
|
||||
Content may now be a file handle.
|
||||
|
||||
Returns:
|
||||
tuple[:obj:`str`, :obj:`bytes` | :class:`IO`, :obj:`str`]:
|
||||
"""
|
||||
return self.filename, self.input_file_content, self.mimetype
|
||||
|
||||
@property
|
||||
def attach_uri(self) -> Optional[str]:
|
||||
"""URI to insert into the JSON data for uploading the file. Returns :obj:`None`, if
|
||||
:attr:`attach_name` is :obj:`None`.
|
||||
"""
|
||||
return f"attach://{self.attach_name}" if self.attach_name else None
|
||||
915
.venv/lib/python3.12/site-packages/telegram/_files/inputmedia.py
Normal file
915
.venv/lib/python3.12/site-packages/telegram/_files/inputmedia.py
Normal file
@@ -0,0 +1,915 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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/].
|
||||
"""Base class for Telegram InputMedia Objects."""
|
||||
import datetime as dtm
|
||||
from collections.abc import Sequence
|
||||
from typing import Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files.animation import Animation
|
||||
from telegram._files.audio import Audio
|
||||
from telegram._files.document import Document
|
||||
from telegram._files.inputfile import InputFile
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._files.video import Video
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg, to_timedelta
|
||||
from telegram._utils.datetime import get_timedelta_value
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.files import parse_file_input
|
||||
from telegram._utils.types import FileInput, JSONDict, ODVInput, TimePeriod
|
||||
from telegram.constants import InputMediaType
|
||||
|
||||
MediaType = Union[Animation, Audio, Document, PhotoSize, Video]
|
||||
|
||||
|
||||
class InputMedia(TelegramObject):
|
||||
"""
|
||||
Base class for Telegram InputMedia Objects.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
Added arguments and attributes :attr:`type`, :attr:`media`, :attr:`caption`,
|
||||
:attr:`caption_entities`, :paramref:`parse_mode`.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
Args:
|
||||
media_type (:obj:`str`): Type of media that the instance represents.
|
||||
media (:obj:`str` | :class:`~telegram.InputFile`): File to send.
|
||||
|fileinputnopath|
|
||||
caption (:obj:`str`, optional): Caption of the media to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the input media.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Media to send.
|
||||
caption (:obj:`str`): Optional. Caption of the media to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("caption", "caption_entities", "media", "parse_mode", "type")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media_type: str,
|
||||
media: Union[str, InputFile],
|
||||
caption: Optional[str] = None,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.type: str = enum.get_member(constants.InputMediaType, media_type, media_type)
|
||||
self.media: Union[str, InputFile] = media
|
||||
self.caption: Optional[str] = caption
|
||||
self.caption_entities: tuple[MessageEntity, ...] = parse_sequence_arg(caption_entities)
|
||||
self.parse_mode: ODVInput[str] = parse_mode
|
||||
|
||||
self._freeze()
|
||||
|
||||
@staticmethod
|
||||
def _parse_thumbnail_input(thumbnail: Optional[FileInput]) -> Optional[Union[str, InputFile]]:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
return (
|
||||
parse_file_input(thumbnail, attach=True, local_mode=True)
|
||||
if thumbnail is not None
|
||||
else thumbnail
|
||||
)
|
||||
|
||||
|
||||
class InputPaidMedia(TelegramObject):
|
||||
"""
|
||||
Base class for Telegram InputPaidMedia Objects. Currently, it can be one of:
|
||||
|
||||
* :class:`telegram.InputPaidMediaPhoto`
|
||||
* :class:`telegram.InputPaidMediaVideo`
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of media that the instance represents.
|
||||
media (:obj:`str` | :class:`~telegram.InputFile`): File
|
||||
to send. |fileinputnopath|
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the input media.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Media to send.
|
||||
"""
|
||||
|
||||
PHOTO: Final[str] = constants.InputPaidMediaType.PHOTO
|
||||
""":const:`telegram.constants.InputPaidMediaType.PHOTO`"""
|
||||
VIDEO: Final[str] = constants.InputPaidMediaType.VIDEO
|
||||
""":const:`telegram.constants.InputPaidMediaType.VIDEO`"""
|
||||
|
||||
__slots__ = ("media", "type")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
media: Union[str, InputFile],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.type: str = enum.get_member(constants.InputPaidMediaType, type, type)
|
||||
self.media: Union[str, InputFile] = media
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class InputPaidMediaPhoto(InputPaidMedia):
|
||||
"""The paid media to send is a photo.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.PhotoSize`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the media, always
|
||||
:tg-const:`telegram.constants.InputPaidMediaType.PHOTO`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Photo to send.
|
||||
"""
|
||||
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, PhotoSize],
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
media = parse_file_input(media, PhotoSize, attach=True, local_mode=True)
|
||||
super().__init__(type=InputPaidMedia.PHOTO, media=media, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class InputPaidMediaVideo(InputPaidMedia):
|
||||
"""
|
||||
The paid media to send is a video.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionadded:: 21.4
|
||||
|
||||
Note:
|
||||
* When using a :class:`telegram.Video` for the :attr:`media` attribute, it will take the
|
||||
width, height and duration from that video, unless otherwise specified with the optional
|
||||
arguments.
|
||||
* :paramref:`thumbnail` will be ignored for small video files, for which Telegram can
|
||||
easily generate thumbnails. However, this behaviour is undocumented and might be
|
||||
changed by Telegram.
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Video`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Video` object to send.
|
||||
thumbnail (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
cover (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): Cover for the video in the message. |fileinputnopath|
|
||||
|
||||
.. versionchanged:: 21.11
|
||||
start_timestamp (:obj:`int`, optional): Start timestamp for the video in the message
|
||||
|
||||
.. versionchanged:: 21.11
|
||||
width (:obj:`int`, optional): Video width.
|
||||
height (:obj:`int`, optional): Video height.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`, optional): Video duration in seconds.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
supports_streaming (:obj:`bool`, optional): Pass :obj:`True`, if the uploaded video is
|
||||
suitable for streaming.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the media, always
|
||||
:tg-const:`telegram.constants.InputPaidMediaType.VIDEO`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Video to send.
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
cover (:class:`telegram.InputFile`): Optional. Cover for the video in the message.
|
||||
|fileinputnopath|
|
||||
|
||||
.. versionchanged:: 21.11
|
||||
start_timestamp (:obj:`int`): Optional. Start timestamp for the video in the message
|
||||
|
||||
.. versionchanged:: 21.11
|
||||
width (:obj:`int`): Optional. Video width.
|
||||
height (:obj:`int`): Optional. Video height.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Optional. Video duration in seconds.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
supports_streaming (:obj:`bool`): Optional. :obj:`True`, if the uploaded video is
|
||||
suitable for streaming.
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"_duration",
|
||||
"cover",
|
||||
"height",
|
||||
"start_timestamp",
|
||||
"supports_streaming",
|
||||
"thumbnail",
|
||||
"width",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Video],
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
duration: Optional[TimePeriod] = None,
|
||||
supports_streaming: Optional[bool] = None,
|
||||
cover: Optional[FileInput] = None,
|
||||
start_timestamp: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if isinstance(media, Video):
|
||||
width = width if width is not None else media.width
|
||||
height = height if height is not None else media.height
|
||||
duration = duration if duration is not None else media._duration
|
||||
media = media.file_id
|
||||
else:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, attach=True, local_mode=True)
|
||||
|
||||
super().__init__(type=InputPaidMedia.VIDEO, media=media, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = InputMedia._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.width: Optional[int] = width
|
||||
self.height: Optional[int] = height
|
||||
self._duration: Optional[dtm.timedelta] = to_timedelta(duration)
|
||||
self.supports_streaming: Optional[bool] = supports_streaming
|
||||
self.cover: Optional[Union[InputFile, str]] = (
|
||||
parse_file_input(cover, attach=True, local_mode=True) if cover else None
|
||||
)
|
||||
self.start_timestamp: Optional[int] = start_timestamp
|
||||
|
||||
@property
|
||||
def duration(self) -> Optional[Union[int, dtm.timedelta]]:
|
||||
return get_timedelta_value(self._duration, attribute="duration")
|
||||
|
||||
|
||||
class InputMediaAnimation(InputMedia):
|
||||
"""Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent.
|
||||
|
||||
Note:
|
||||
When using a :class:`telegram.Animation` for the :attr:`media` attribute, it will take the
|
||||
width, height and duration from that animation, unless otherwise specified with the
|
||||
optional arguments.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Animation`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Animation` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
filename (:obj:`str`, optional): Custom file name for the animation, when uploading a
|
||||
new file. Convenience parameter, useful e.g. when sending files generated by the
|
||||
:obj:`tempfile` module.
|
||||
|
||||
.. versionadded:: 13.1
|
||||
caption (:obj:`str`, optional): Caption of the animation to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
width (:obj:`int`, optional): Animation width.
|
||||
height (:obj:`int`, optional): Animation height.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`, optional): Animation duration
|
||||
in seconds.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
has_spoiler (:obj:`bool`, optional): Pass :obj:`True`, if the animation needs to be covered
|
||||
with a spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumbnail (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.ANIMATION`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Animation to send.
|
||||
caption (:obj:`str`): Optional. Caption of the animation to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
width (:obj:`int`): Optional. Animation width.
|
||||
height (:obj:`int`): Optional. Animation height.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Optional. Animation duration
|
||||
in seconds.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
has_spoiler (:obj:`bool`): Optional. :obj:`True`, if the animation is covered with a
|
||||
spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"_duration",
|
||||
"has_spoiler",
|
||||
"height",
|
||||
"show_caption_above_media",
|
||||
"thumbnail",
|
||||
"width",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Animation],
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
duration: Optional[TimePeriod] = None,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
filename: Optional[str] = None,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if isinstance(media, Animation):
|
||||
width = media.width if width is None else width
|
||||
height = media.height if height is None else height
|
||||
duration = duration if duration is not None else media._duration
|
||||
media = media.file_id
|
||||
else:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, filename=filename, attach=True, local_mode=True)
|
||||
|
||||
super().__init__(
|
||||
InputMediaType.ANIMATION,
|
||||
media,
|
||||
caption,
|
||||
caption_entities,
|
||||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.width: Optional[int] = width
|
||||
self.height: Optional[int] = height
|
||||
self._duration: Optional[dtm.timedelta] = to_timedelta(duration)
|
||||
self.has_spoiler: Optional[bool] = has_spoiler
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
@property
|
||||
def duration(self) -> Optional[Union[int, dtm.timedelta]]:
|
||||
return get_timedelta_value(self._duration, attribute="duration")
|
||||
|
||||
|
||||
class InputMediaPhoto(InputMedia):
|
||||
"""Represents a photo to be sent.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.PhotoSize`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.PhotoSize` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
filename (:obj:`str`, optional): Custom file name for the photo, when uploading a
|
||||
new file. Convenience parameter, useful e.g. when sending files generated by the
|
||||
:obj:`tempfile` module.
|
||||
|
||||
.. versionadded:: 13.1
|
||||
caption (:obj:`str`, optional ): Caption of the photo to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
has_spoiler (:obj:`bool`, optional): Pass :obj:`True`, if the photo needs to be covered
|
||||
with a spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.PHOTO`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Photo to send.
|
||||
caption (:obj:`str`): Optional. Caption of the photo to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
has_spoiler (:obj:`bool`): Optional. :obj:`True`, if the photo is covered with a
|
||||
spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"has_spoiler",
|
||||
"show_caption_above_media",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, PhotoSize],
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
filename: Optional[str] = None,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, PhotoSize, filename=filename, attach=True, local_mode=True)
|
||||
super().__init__(
|
||||
InputMediaType.PHOTO,
|
||||
media,
|
||||
caption,
|
||||
caption_entities,
|
||||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
with self._unfrozen():
|
||||
self.has_spoiler: Optional[bool] = has_spoiler
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
|
||||
|
||||
class InputMediaVideo(InputMedia):
|
||||
"""Represents a video to be sent.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
Note:
|
||||
* When using a :class:`telegram.Video` for the :attr:`media` attribute, it will take the
|
||||
width, height and duration from that video, unless otherwise specified with the optional
|
||||
arguments.
|
||||
* :paramref:`thumbnail` will be ignored for small video files, for which Telegram can
|
||||
easily generate thumbnails. However, this behaviour is undocumented and might be
|
||||
changed by Telegram.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Video`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Video` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
filename (:obj:`str`, optional): Custom file name for the video, when uploading a
|
||||
new file. Convenience parameter, useful e.g. when sending files generated by the
|
||||
:obj:`tempfile` module.
|
||||
|
||||
.. versionadded:: 13.1
|
||||
caption (:obj:`str`, optional): Caption of the video to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
width (:obj:`int`, optional): Video width.
|
||||
height (:obj:`int`, optional): Video height.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`, optional): Video duration in seconds.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
supports_streaming (:obj:`bool`, optional): Pass :obj:`True`, if the uploaded video is
|
||||
suitable for streaming.
|
||||
has_spoiler (:obj:`bool`, optional): Pass :obj:`True`, if the video needs to be covered
|
||||
with a spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumbnail (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
cover (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): Cover for the video in the message. |fileinputnopath|
|
||||
|
||||
.. versionchanged:: 21.11
|
||||
start_timestamp (:obj:`int`, optional): Start timestamp for the video in the message
|
||||
|
||||
.. versionchanged:: 21.11
|
||||
show_caption_above_media (:obj:`bool`, optional): Pass |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.VIDEO`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Video file to send.
|
||||
caption (:obj:`str`): Optional. Caption of the video to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
width (:obj:`int`): Optional. Video width.
|
||||
height (:obj:`int`): Optional. Video height.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Optional. Video duration in seconds.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
supports_streaming (:obj:`bool`): Optional. :obj:`True`, if the uploaded video is
|
||||
suitable for streaming.
|
||||
has_spoiler (:obj:`bool`): Optional. :obj:`True`, if the video is covered with a
|
||||
spoiler animation.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
show_caption_above_media (:obj:`bool`): Optional. |show_cap_above_med|
|
||||
|
||||
.. versionadded:: 21.3
|
||||
cover (:class:`telegram.InputFile`): Optional. Cover for the video in the message.
|
||||
|fileinputnopath|
|
||||
|
||||
.. versionchanged:: 21.11
|
||||
start_timestamp (:obj:`int`): Optional. Start timestamp for the video in the message
|
||||
|
||||
.. versionchanged:: 21.11
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"_duration",
|
||||
"cover",
|
||||
"has_spoiler",
|
||||
"height",
|
||||
"show_caption_above_media",
|
||||
"start_timestamp",
|
||||
"supports_streaming",
|
||||
"thumbnail",
|
||||
"width",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Video],
|
||||
caption: Optional[str] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
duration: Optional[TimePeriod] = None,
|
||||
supports_streaming: Optional[bool] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
filename: Optional[str] = None,
|
||||
has_spoiler: Optional[bool] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
show_caption_above_media: Optional[bool] = None,
|
||||
cover: Optional[FileInput] = None,
|
||||
start_timestamp: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if isinstance(media, Video):
|
||||
width = width if width is not None else media.width
|
||||
height = height if height is not None else media.height
|
||||
duration = duration if duration is not None else media._duration
|
||||
media = media.file_id
|
||||
else:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, filename=filename, attach=True, local_mode=True)
|
||||
|
||||
super().__init__(
|
||||
InputMediaType.VIDEO,
|
||||
media,
|
||||
caption,
|
||||
caption_entities,
|
||||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
self.width: Optional[int] = width
|
||||
self.height: Optional[int] = height
|
||||
self._duration: Optional[dtm.timedelta] = to_timedelta(duration)
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.supports_streaming: Optional[bool] = supports_streaming
|
||||
self.has_spoiler: Optional[bool] = has_spoiler
|
||||
self.show_caption_above_media: Optional[bool] = show_caption_above_media
|
||||
self.cover: Optional[Union[InputFile, str]] = (
|
||||
parse_file_input(cover, attach=True, local_mode=True) if cover else None
|
||||
)
|
||||
self.start_timestamp: Optional[int] = start_timestamp
|
||||
|
||||
@property
|
||||
def duration(self) -> Optional[Union[int, dtm.timedelta]]:
|
||||
return get_timedelta_value(self._duration, attribute="duration")
|
||||
|
||||
|
||||
class InputMediaAudio(InputMedia):
|
||||
"""Represents an audio file to be treated as music to be sent.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
Note:
|
||||
When using a :class:`telegram.Audio` for the :attr:`media` attribute, it will take the
|
||||
duration, performer and title from that video, unless otherwise specified with the
|
||||
optional arguments.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path` | :class:`telegram.Audio`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Audio` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
filename (:obj:`str`, optional): Custom file name for the audio, when uploading a
|
||||
new file. Convenience parameter, useful e.g. when sending files generated by the
|
||||
:obj:`tempfile` module.
|
||||
|
||||
.. versionadded:: 13.1
|
||||
caption (:obj:`str`, optional): Caption of the audio to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`, optional): Duration of the audio
|
||||
in seconds as defined by the sender.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
performer (:obj:`str`, optional): Performer of the audio as defined by the sender or by
|
||||
audio tags.
|
||||
title (:obj:`str`, optional): Title of the audio as defined by the sender or by audio tags.
|
||||
thumbnail (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.AUDIO`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): Audio file to send.
|
||||
caption (:obj:`str`): Optional. Caption of the audio to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Optional. Duration of the audio
|
||||
in seconds.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
performer (:obj:`str`): Optional. Performer of the audio as defined by the sender or by
|
||||
audio tags.
|
||||
title (:obj:`str`): Optional. Title of the audio as defined by the sender or by audio tags.
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("_duration", "performer", "thumbnail", "title")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Audio],
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
duration: Optional[TimePeriod] = None,
|
||||
performer: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
filename: Optional[str] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
if isinstance(media, Audio):
|
||||
duration = duration if duration is not None else media._duration
|
||||
performer = media.performer if performer is None else performer
|
||||
title = media.title if title is None else title
|
||||
media = media.file_id
|
||||
else:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, filename=filename, attach=True, local_mode=True)
|
||||
|
||||
super().__init__(
|
||||
InputMediaType.AUDIO,
|
||||
media,
|
||||
caption,
|
||||
caption_entities,
|
||||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self._duration: Optional[dtm.timedelta] = to_timedelta(duration)
|
||||
self.title: Optional[str] = title
|
||||
self.performer: Optional[str] = performer
|
||||
|
||||
@property
|
||||
def duration(self) -> Optional[Union[int, dtm.timedelta]]:
|
||||
return get_timedelta_value(self._duration, attribute="duration")
|
||||
|
||||
|
||||
class InputMediaDocument(InputMedia):
|
||||
"""Represents a general file to be sent.
|
||||
|
||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
media (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` \
|
||||
| :class:`pathlib.Path` | :class:`telegram.Document`): File to send. |fileinputnopath|
|
||||
Lastly you can pass an existing :class:`telegram.Document` object to send.
|
||||
|
||||
.. versionchanged:: 13.2
|
||||
Accept :obj:`bytes` as input.
|
||||
filename (:obj:`str`, optional): Custom file name for the document, when uploading a
|
||||
new file. Convenience parameter, useful e.g. when sending files generated by the
|
||||
:obj:`tempfile` module.
|
||||
|
||||
.. versionadded:: 13.1
|
||||
caption (:obj:`str`, optional): Caption of the document to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
disable_content_type_detection (:obj:`bool`, optional): Disables automatic server-side
|
||||
content type detection for files uploaded using multipart/form-data. Always
|
||||
:obj:`True`, if the document is sent as part of an album.
|
||||
thumbnail (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.DOCUMENT`.
|
||||
media (:obj:`str` | :class:`telegram.InputFile`): File to send.
|
||||
caption (:obj:`str`): Optional. Caption of the document to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
disable_content_type_detection (:obj:`bool`): Optional. Disables automatic server-side
|
||||
content type detection for files uploaded using multipart/form-data. Always
|
||||
:obj:`True`, if the document is sent as part of an album.
|
||||
thumbnail (:class:`telegram.InputFile`): Optional. |thumbdocstringbase|
|
||||
|
||||
.. versionadded:: 20.2
|
||||
"""
|
||||
|
||||
__slots__ = ("disable_content_type_detection", "thumbnail")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
media: Union[FileInput, Document],
|
||||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_content_type_detection: Optional[bool] = None,
|
||||
caption_entities: Optional[Sequence[MessageEntity]] = None,
|
||||
filename: Optional[str] = None,
|
||||
thumbnail: Optional[FileInput] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
media = parse_file_input(media, Document, filename=filename, attach=True, local_mode=True)
|
||||
|
||||
super().__init__(
|
||||
InputMediaType.DOCUMENT,
|
||||
media,
|
||||
caption,
|
||||
caption_entities,
|
||||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
self.thumbnail: Optional[Union[str, InputFile]] = self._parse_thumbnail_input(
|
||||
thumbnail
|
||||
)
|
||||
self.disable_content_type_detection: Optional[bool] = disable_content_type_detection
|
||||
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 objects that represents a InputProfilePhoto and subclasses."""
|
||||
|
||||
import datetime as dtm
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import to_timedelta
|
||||
from telegram._utils.files import parse_file_input
|
||||
from telegram._utils.types import FileInput, JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import InputFile
|
||||
|
||||
|
||||
class InputProfilePhoto(TelegramObject):
|
||||
"""This object describes a profile photo to set. Currently, it can be one of
|
||||
|
||||
* :class:`InputProfilePhotoStatic`
|
||||
* :class:`InputProfilePhotoAnimated`
|
||||
|
||||
.. versionadded:: 22.1
|
||||
|
||||
Args:
|
||||
type (:obj:`str`): Type of the profile photo.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Type of the profile photo.
|
||||
|
||||
"""
|
||||
|
||||
STATIC = constants.InputProfilePhotoType.STATIC
|
||||
""":obj:`str`: :tg-const:`telegram.constants.InputProfilePhotoType.STATIC`."""
|
||||
ANIMATED = constants.InputProfilePhotoType.ANIMATED
|
||||
""":obj:`str`: :tg-const:`telegram.constants.InputProfilePhotoType.ANIMATED`."""
|
||||
|
||||
__slots__ = ("type",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.type: str = enum.get_member(constants.InputProfilePhotoType, type, type)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class InputProfilePhotoStatic(InputProfilePhoto):
|
||||
"""A static profile photo in the .JPG format.
|
||||
|
||||
.. versionadded:: 22.1
|
||||
|
||||
Args:
|
||||
photo (:term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path`): The static profile photo. |uploadinputnopath|
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputProfilePhotoType.STATIC`.
|
||||
photo (:class:`telegram.InputFile` | :obj:`str`): The static profile photo.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("photo",)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
photo: FileInput,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=constants.InputProfilePhotoType.STATIC, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
self.photo: Union[str, InputFile] = parse_file_input(
|
||||
photo, attach=True, local_mode=True
|
||||
)
|
||||
|
||||
|
||||
class InputProfilePhotoAnimated(InputProfilePhoto):
|
||||
"""An animated profile photo in the MPEG4 format.
|
||||
|
||||
.. versionadded:: 22.1
|
||||
|
||||
Args:
|
||||
animation (:term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` | \
|
||||
:class:`pathlib.Path`): The animated profile photo. |uploadinputnopath|
|
||||
main_frame_timestamp (:class:`datetime.timedelta` | :obj:`int` | :obj:`float`, optional):
|
||||
Timestamp in seconds of the frame that will be used as the static profile photo.
|
||||
Defaults to ``0.0``.
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputProfilePhotoType.ANIMATED`.
|
||||
animation (:class:`telegram.InputFile` | :obj:`str`): The animated profile photo.
|
||||
main_frame_timestamp (:class:`datetime.timedelta`): Optional. Timestamp in seconds of the
|
||||
frame that will be used as the static profile photo. Defaults to ``0.0``.
|
||||
"""
|
||||
|
||||
__slots__ = ("animation", "main_frame_timestamp")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
animation: FileInput,
|
||||
main_frame_timestamp: Union[float, dtm.timedelta, None] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(type=constants.InputProfilePhotoType.ANIMATED, api_kwargs=api_kwargs)
|
||||
with self._unfrozen():
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
self.animation: Union[str, InputFile] = parse_file_input(
|
||||
animation, attach=True, local_mode=True
|
||||
)
|
||||
|
||||
self.main_frame_timestamp: Optional[dtm.timedelta] = to_timedelta(main_frame_timestamp)
|
||||
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram InputSticker."""
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from telegram._files.sticker import MaskPosition
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.files import parse_file_input
|
||||
from telegram._utils.types import FileInput, JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram._files.inputfile import InputFile
|
||||
|
||||
|
||||
class InputSticker(TelegramObject):
|
||||
"""
|
||||
This object describes a sticker to be added to a sticker set.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
As of Bot API 7.2, the new argument :paramref:`format` is a required argument, and thus the
|
||||
order of the arguments has changed.
|
||||
|
||||
Args:
|
||||
sticker (:obj:`str` | :term:`file object` | :class:`~telegram.InputFile` | :obj:`bytes` \
|
||||
| :class:`pathlib.Path`): The
|
||||
added sticker. |uploadinputnopath| Animated and video stickers can't be uploaded via
|
||||
HTTP URL.
|
||||
emoji_list (Sequence[:obj:`str`]): Sequence of
|
||||
:tg-const:`telegram.constants.StickerLimit.MIN_STICKER_EMOJI` -
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_STICKER_EMOJI` emoji associated with the
|
||||
sticker.
|
||||
mask_position (:class:`telegram.MaskPosition`, optional): Position where the mask should be
|
||||
placed on faces. For ":tg-const:`telegram.constants.StickerType.MASK`" stickers only.
|
||||
keywords (Sequence[:obj:`str`], optional): Sequence of
|
||||
0-:tg-const:`telegram.constants.StickerLimit.MAX_SEARCH_KEYWORDS` search keywords
|
||||
for the sticker with the total length of up to
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_KEYWORD_LENGTH` characters. For
|
||||
":tg-const:`telegram.constants.StickerType.REGULAR`" and
|
||||
":tg-const:`telegram.constants.StickerType.CUSTOM_EMOJI`" stickers only.
|
||||
format (:obj:`str`): Format of the added sticker, must be one of
|
||||
:tg-const:`telegram.constants.StickerFormat.STATIC` for a
|
||||
``.WEBP`` or ``.PNG`` image, :tg-const:`telegram.constants.StickerFormat.ANIMATED`
|
||||
for a ``.TGS`` animation, :tg-const:`telegram.constants.StickerFormat.VIDEO` for a
|
||||
``.WEBM`` video.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
|
||||
Attributes:
|
||||
sticker (:obj:`str` | :class:`telegram.InputFile`): The added sticker.
|
||||
emoji_list (tuple[:obj:`str`]): Tuple of
|
||||
:tg-const:`telegram.constants.StickerLimit.MIN_STICKER_EMOJI` -
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_STICKER_EMOJI` emoji associated with the
|
||||
sticker.
|
||||
mask_position (:class:`telegram.MaskPosition`): Optional. Position where the mask should be
|
||||
placed on faces. For ":tg-const:`telegram.constants.StickerType.MASK`" stickers only.
|
||||
keywords (tuple[:obj:`str`]): Optional. Tuple of
|
||||
0-:tg-const:`telegram.constants.StickerLimit.MAX_SEARCH_KEYWORDS` search keywords
|
||||
for the sticker with the total length of up to
|
||||
:tg-const:`telegram.constants.StickerLimit.MAX_KEYWORD_LENGTH` characters. For
|
||||
":tg-const:`telegram.constants.StickerType.REGULAR`" and
|
||||
":tg-const:`telegram.constants.StickerType.CUSTOM_EMOJI`" stickers only.
|
||||
":tg-const:`telegram.constants.StickerType.CUSTOM_EMOJI`" stickers only.
|
||||
format (:obj:`str`): Format of the added sticker, must be one of
|
||||
:tg-const:`telegram.constants.StickerFormat.STATIC` for a
|
||||
``.WEBP`` or ``.PNG`` image, :tg-const:`telegram.constants.StickerFormat.ANIMATED`
|
||||
for a ``.TGS`` animation, :tg-const:`telegram.constants.StickerFormat.VIDEO` for a
|
||||
``.WEBM`` video.
|
||||
|
||||
.. versionadded:: 21.1
|
||||
"""
|
||||
|
||||
__slots__ = ("emoji_list", "format", "keywords", "mask_position", "sticker")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
sticker: FileInput,
|
||||
emoji_list: Sequence[str],
|
||||
format: str, # pylint: disable=redefined-builtin
|
||||
mask_position: Optional[MaskPosition] = None,
|
||||
keywords: Optional[Sequence[str]] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
# things to work in local mode.
|
||||
self.sticker: Union[str, InputFile] = parse_file_input(
|
||||
sticker,
|
||||
local_mode=True,
|
||||
attach=True,
|
||||
)
|
||||
self.emoji_list: tuple[str, ...] = parse_sequence_arg(emoji_list)
|
||||
self.format: str = format
|
||||
self.mask_position: Optional[MaskPosition] = mask_position
|
||||
self.keywords: tuple[str, ...] = parse_sequence_arg(keywords)
|
||||
|
||||
self._freeze()
|
||||
128
.venv/lib/python3.12/site-packages/telegram/_files/location.py
Normal file
128
.venv/lib/python3.12/site-packages/telegram/_files/location.py
Normal file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram Location."""
|
||||
|
||||
import datetime as dtm
|
||||
from typing import Final, Optional, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import to_timedelta
|
||||
from telegram._utils.datetime import get_timedelta_value
|
||||
from telegram._utils.types import JSONDict, TimePeriod
|
||||
|
||||
|
||||
class Location(TelegramObject):
|
||||
"""This object represents a point on the map.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`longitude` and :attr:`latitude` are equal.
|
||||
|
||||
Args:
|
||||
longitude (:obj:`float`): Longitude as defined by the sender.
|
||||
latitude (:obj:`float`): Latitude as defined by the sender.
|
||||
horizontal_accuracy (:obj:`float`, optional): The radius of uncertainty for the location,
|
||||
measured in meters; 0-:tg-const:`telegram.Location.HORIZONTAL_ACCURACY`.
|
||||
live_period (:obj:`int` | :class:`datetime.timedelta`, optional): Time relative to the
|
||||
message sending date, during which the location can be updated, in seconds. For active
|
||||
live locations only.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
heading (:obj:`int`, optional): The direction in which user is moving, in degrees;
|
||||
:tg-const:`telegram.Location.MIN_HEADING`-:tg-const:`telegram.Location.MAX_HEADING`.
|
||||
For active live locations only.
|
||||
proximity_alert_radius (:obj:`int`, optional): Maximum distance for proximity alerts about
|
||||
approaching another chat member, in meters. For sent live locations only.
|
||||
|
||||
Attributes:
|
||||
longitude (:obj:`float`): Longitude as defined by the sender.
|
||||
latitude (:obj:`float`): Latitude as defined by the sender.
|
||||
horizontal_accuracy (:obj:`float`): Optional. The radius of uncertainty for the location,
|
||||
measured in meters; 0-:tg-const:`telegram.Location.HORIZONTAL_ACCURACY`.
|
||||
live_period (:obj:`int` | :class:`datetime.timedelta`): Optional. Time relative to the
|
||||
message sending date, during which the location can be updated, in seconds. For active
|
||||
live locations only.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
heading (:obj:`int`): Optional. The direction in which user is moving, in degrees;
|
||||
:tg-const:`telegram.Location.MIN_HEADING`-:tg-const:`telegram.Location.MAX_HEADING`.
|
||||
For active live locations only.
|
||||
proximity_alert_radius (:obj:`int`): Optional. Maximum distance for proximity alerts about
|
||||
approaching another chat member, in meters. For sent live locations only.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"_live_period",
|
||||
"heading",
|
||||
"horizontal_accuracy",
|
||||
"latitude",
|
||||
"longitude",
|
||||
"proximity_alert_radius",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
longitude: float,
|
||||
latitude: float,
|
||||
horizontal_accuracy: Optional[float] = None,
|
||||
live_period: Optional[TimePeriod] = None,
|
||||
heading: Optional[int] = None,
|
||||
proximity_alert_radius: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.longitude: float = longitude
|
||||
self.latitude: float = latitude
|
||||
|
||||
# Optionals
|
||||
self.horizontal_accuracy: Optional[float] = horizontal_accuracy
|
||||
self._live_period: Optional[dtm.timedelta] = to_timedelta(live_period)
|
||||
self.heading: Optional[int] = heading
|
||||
self.proximity_alert_radius: Optional[int] = (
|
||||
int(proximity_alert_radius) if proximity_alert_radius else None
|
||||
)
|
||||
|
||||
self._id_attrs = (self.longitude, self.latitude)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@property
|
||||
def live_period(self) -> Optional[Union[int, dtm.timedelta]]:
|
||||
return get_timedelta_value(self._live_period, attribute="live_period")
|
||||
|
||||
HORIZONTAL_ACCURACY: Final[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
""":const:`telegram.constants.LocationLimit.HORIZONTAL_ACCURACY`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MIN_HEADING: Final[int] = constants.LocationLimit.MIN_HEADING
|
||||
""":const:`telegram.constants.LocationLimit.MIN_HEADING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
MAX_HEADING: Final[int] = constants.LocationLimit.MAX_HEADING
|
||||
""":const:`telegram.constants.LocationLimit.MAX_HEADING`
|
||||
|
||||
.. versionadded:: 20.0
|
||||
"""
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram PhotoSize."""
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from telegram._files._basemedium import _BaseMedium
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
||||
class PhotoSize(_BaseMedium):
|
||||
"""This object represents one size of a photo or a file/sticker thumbnail.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Photo width.
|
||||
height (:obj:`int`): Photo height.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Photo width.
|
||||
height (:obj:`int`): Photo height.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("height", "width")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
file_size: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.width: int = width
|
||||
self.height: int = height
|
||||
382
.venv/lib/python3.12/site-packages/telegram/_files/sticker.py
Normal file
382
.venv/lib/python3.12/site-packages/telegram/_files/sticker.py
Normal file
@@ -0,0 +1,382 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 objects that represent stickers."""
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Final, Optional
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
from telegram._files.file import File
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import de_json_optional, de_list_optional, parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class Sticker(_BaseThumbedMedium):
|
||||
"""This object represents a sticker.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
Note:
|
||||
As of v13.11 :paramref:`is_video` is a required argument and therefore the order of the
|
||||
arguments had to be changed. Use keyword arguments to make sure that the arguments are
|
||||
passed correctly.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Sticker width.
|
||||
height (:obj:`int`): Sticker height.
|
||||
is_animated (:obj:`bool`): :obj:`True`, if the sticker is animated.
|
||||
is_video (:obj:`bool`): :obj:`True`, if the sticker is a video sticker.
|
||||
|
||||
.. versionadded:: 13.11
|
||||
type (:obj:`str`): Type of the sticker. Currently one of :attr:`REGULAR`,
|
||||
:attr:`MASK`, :attr:`CUSTOM_EMOJI`. The type of the sticker is independent from its
|
||||
format, which is determined by the fields :attr:`is_animated` and :attr:`is_video`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
emoji (:obj:`str`, optional): Emoji associated with the sticker
|
||||
set_name (:obj:`str`, optional): Name of the sticker set to which the sticker belongs.
|
||||
mask_position (:class:`telegram.MaskPosition`, optional): For mask stickers, the position
|
||||
where the mask should be placed.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
|
||||
premium_animation (:class:`telegram.File`, optional): For premium regular stickers,
|
||||
premium animation for the sticker.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
custom_emoji_id (:obj:`str`, optional): For custom emoji stickers, unique identifier of the
|
||||
custom emoji.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Sticker thumbnail in the ``.WEBP`` or
|
||||
``.JPG`` format.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
needs_repainting (:obj:`bool`, optional): :obj:`True`, if the sticker must be repainted to
|
||||
a text color in messages, the color of the Telegram Premium badge in emoji status,
|
||||
white color on chat photos, or another appropriate color in other places.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Sticker width.
|
||||
height (:obj:`int`): Sticker height.
|
||||
is_animated (:obj:`bool`): :obj:`True`, if the sticker is animated.
|
||||
is_video (:obj:`bool`): :obj:`True`, if the sticker is a video sticker.
|
||||
|
||||
.. versionadded:: 13.11
|
||||
type (:obj:`str`): Type of the sticker. Currently one of :attr:`REGULAR`,
|
||||
:attr:`MASK`, :attr:`CUSTOM_EMOJI`. The type of the sticker is independent from its
|
||||
format, which is determined by the fields :attr:`is_animated` and :attr:`is_video`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
emoji (:obj:`str`): Optional. Emoji associated with the sticker.
|
||||
set_name (:obj:`str`): Optional. Name of the sticker set to which the sticker belongs.
|
||||
mask_position (:class:`telegram.MaskPosition`): Optional. For mask stickers, the position
|
||||
where the mask should be placed.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
|
||||
premium_animation (:class:`telegram.File`): Optional. For premium regular stickers,
|
||||
premium animation for the sticker.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
custom_emoji_id (:obj:`str`): Optional. For custom emoji stickers, unique identifier of the
|
||||
custom emoji.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Sticker thumbnail in the ``.WEBP`` or
|
||||
``.JPG`` format.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
needs_repainting (:obj:`bool`): Optional. :obj:`True`, if the sticker must be repainted to
|
||||
a text color in messages, the color of the Telegram Premium badge in emoji status,
|
||||
white color on chat photos, or another appropriate color in other places.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"custom_emoji_id",
|
||||
"emoji",
|
||||
"height",
|
||||
"is_animated",
|
||||
"is_video",
|
||||
"mask_position",
|
||||
"needs_repainting",
|
||||
"premium_animation",
|
||||
"set_name",
|
||||
"type",
|
||||
"width",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
is_animated: bool,
|
||||
is_video: bool,
|
||||
type: str, # pylint: disable=redefined-builtin
|
||||
emoji: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
set_name: Optional[str] = None,
|
||||
mask_position: Optional["MaskPosition"] = None,
|
||||
premium_animation: Optional["File"] = None,
|
||||
custom_emoji_id: Optional[str] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
needs_repainting: Optional[bool] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.width: int = width
|
||||
self.height: int = height
|
||||
self.is_animated: bool = is_animated
|
||||
self.is_video: bool = is_video
|
||||
self.type: str = enum.get_member(constants.StickerType, type, type)
|
||||
# Optional
|
||||
self.emoji: Optional[str] = emoji
|
||||
self.set_name: Optional[str] = set_name
|
||||
self.mask_position: Optional[MaskPosition] = mask_position
|
||||
self.premium_animation: Optional[File] = premium_animation
|
||||
self.custom_emoji_id: Optional[str] = custom_emoji_id
|
||||
self.needs_repainting: Optional[bool] = needs_repainting
|
||||
|
||||
REGULAR: Final[str] = constants.StickerType.REGULAR
|
||||
""":const:`telegram.constants.StickerType.REGULAR`"""
|
||||
MASK: Final[str] = constants.StickerType.MASK
|
||||
""":const:`telegram.constants.StickerType.MASK`"""
|
||||
CUSTOM_EMOJI: Final[str] = constants.StickerType.CUSTOM_EMOJI
|
||||
""":const:`telegram.constants.StickerType.CUSTOM_EMOJI`"""
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "Sticker":
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
data["thumbnail"] = de_json_optional(data.get("thumbnail"), PhotoSize, bot)
|
||||
data["mask_position"] = de_json_optional(data.get("mask_position"), MaskPosition, bot)
|
||||
data["premium_animation"] = de_json_optional(data.get("premium_animation"), File, bot)
|
||||
|
||||
api_kwargs = {}
|
||||
# This is a deprecated field that TG still returns for backwards compatibility
|
||||
# Let's filter it out to speed up the de-json process
|
||||
if data.get("thumb") is not None:
|
||||
api_kwargs["thumb"] = data.pop("thumb")
|
||||
|
||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||
|
||||
|
||||
class StickerSet(TelegramObject):
|
||||
"""This object represents a sticker set.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`name` is equal.
|
||||
|
||||
Note:
|
||||
As of v13.11 :paramref:`is_video` is a required argument and therefore the order of the
|
||||
arguments had to be changed. Use keyword arguments to make sure that the arguments are
|
||||
passed correctly.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
The parameter ``contains_masks`` has been removed. Use :paramref:`sticker_type` instead.
|
||||
|
||||
|
||||
.. versionchanged:: 21.1
|
||||
The parameters ``is_video`` and ``is_animated`` are deprecated and now made optional. Thus,
|
||||
the order of the arguments had to be changed.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
.. versionremoved:: 21.2
|
||||
Removed the deprecated arguments and attributes ``is_animated`` and ``is_video``.
|
||||
|
||||
Args:
|
||||
name (:obj:`str`): Sticker set name.
|
||||
title (:obj:`str`): Sticker set title.
|
||||
stickers (Sequence[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
sticker_type (:obj:`str`): Type of stickers in the set, currently one of
|
||||
:attr:`telegram.Sticker.REGULAR`, :attr:`telegram.Sticker.MASK`,
|
||||
:attr:`telegram.Sticker.CUSTOM_EMOJI`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Sticker set thumbnail in the ``.WEBP``,
|
||||
``.TGS``, or ``.WEBM`` format.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
name (:obj:`str`): Sticker set name.
|
||||
title (:obj:`str`): Sticker set title.
|
||||
stickers (tuple[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
sticker_type (:obj:`str`): Type of stickers in the set, currently one of
|
||||
:attr:`telegram.Sticker.REGULAR`, :attr:`telegram.Sticker.MASK`,
|
||||
:attr:`telegram.Sticker.CUSTOM_EMOJI`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Sticker set thumbnail in the ``.WEBP``,
|
||||
``.TGS``, or ``.WEBM`` format.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"name",
|
||||
"sticker_type",
|
||||
"stickers",
|
||||
"thumbnail",
|
||||
"title",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
title: str,
|
||||
stickers: Sequence[Sticker],
|
||||
sticker_type: str,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.name: str = name
|
||||
self.title: str = title
|
||||
self.stickers: tuple[Sticker, ...] = parse_sequence_arg(stickers)
|
||||
self.sticker_type: str = sticker_type
|
||||
# Optional
|
||||
self.thumbnail: Optional[PhotoSize] = thumbnail
|
||||
self._id_attrs = (self.name,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "StickerSet":
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
data["thumbnail"] = de_json_optional(data.get("thumbnail"), PhotoSize, bot)
|
||||
data["stickers"] = de_list_optional(data.get("stickers"), Sticker, bot)
|
||||
|
||||
api_kwargs = {}
|
||||
# These are deprecated fields that TG still returns for backwards compatibility
|
||||
# Let's filter them out to speed up the de-json process
|
||||
for deprecated_field in ("contains_masks", "thumb", "is_animated", "is_video"):
|
||||
if deprecated_field in data:
|
||||
api_kwargs[deprecated_field] = data.pop(deprecated_field)
|
||||
|
||||
return super()._de_json(data=data, bot=bot, api_kwargs=api_kwargs)
|
||||
|
||||
|
||||
class MaskPosition(TelegramObject):
|
||||
"""This object describes the position on faces where a mask should be placed by default.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`point`, :attr:`x_shift`, :attr:`y_shift` and, :attr:`scale`
|
||||
are equal.
|
||||
|
||||
Args:
|
||||
point (:obj:`str`): The part of the face relative to which the mask should be placed.
|
||||
One of :attr:`FOREHEAD`, :attr:`EYES`, :attr:`MOUTH`, or :attr:`CHIN`.
|
||||
x_shift (:obj:`float`): Shift by X-axis measured in widths of the mask scaled to the face
|
||||
size, from left to right. For example, choosing ``-1.0`` will place mask just to the
|
||||
left of the default mask position.
|
||||
y_shift (:obj:`float`): Shift by Y-axis measured in heights of the mask scaled to the face
|
||||
size, from top to bottom. For example, ``1.0`` will place the mask just below the
|
||||
default mask position.
|
||||
scale (:obj:`float`): Mask scaling coefficient. For example, ``2.0`` means double size.
|
||||
|
||||
Attributes:
|
||||
point (:obj:`str`): The part of the face relative to which the mask should be placed.
|
||||
One of :attr:`FOREHEAD`, :attr:`EYES`, :attr:`MOUTH`, or :attr:`CHIN`.
|
||||
x_shift (:obj:`float`): Shift by X-axis measured in widths of the mask scaled to the face
|
||||
size, from left to right. For example, choosing ``-1.0`` will place mask just to the
|
||||
left of the default mask position.
|
||||
y_shift (:obj:`float`): Shift by Y-axis measured in heights of the mask scaled to the face
|
||||
size, from top to bottom. For example, ``1.0`` will place the mask just below the
|
||||
default mask position.
|
||||
scale (:obj:`float`): Mask scaling coefficient. For example, ``2.0`` means double size.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("point", "scale", "x_shift", "y_shift")
|
||||
|
||||
FOREHEAD: Final[str] = constants.MaskPosition.FOREHEAD
|
||||
""":const:`telegram.constants.MaskPosition.FOREHEAD`"""
|
||||
EYES: Final[str] = constants.MaskPosition.EYES
|
||||
""":const:`telegram.constants.MaskPosition.EYES`"""
|
||||
MOUTH: Final[str] = constants.MaskPosition.MOUTH
|
||||
""":const:`telegram.constants.MaskPosition.MOUTH`"""
|
||||
CHIN: Final[str] = constants.MaskPosition.CHIN
|
||||
""":const:`telegram.constants.MaskPosition.CHIN`"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
point: str,
|
||||
x_shift: float,
|
||||
y_shift: float,
|
||||
scale: float,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.point: str = point
|
||||
self.x_shift: float = x_shift
|
||||
self.y_shift: float = y_shift
|
||||
self.scale: float = scale
|
||||
|
||||
self._id_attrs = (self.point, self.x_shift, self.y_shift, self.scale)
|
||||
|
||||
self._freeze()
|
||||
113
.venv/lib/python3.12/site-packages/telegram/_files/venue.py
Normal file
113
.venv/lib/python3.12/site-packages/telegram/_files/venue.py
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram Venue."""
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from telegram._files.location import Location
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import de_json_optional
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class Venue(TelegramObject):
|
||||
"""This object represents a venue.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`location` and :attr:`title` are equal.
|
||||
|
||||
Note:
|
||||
Foursquare details and Google Place details are mutually exclusive. However, this
|
||||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Args:
|
||||
location (:class:`telegram.Location`): Venue location.
|
||||
title (:obj:`str`): Name of the venue.
|
||||
address (:obj:`str`): Address of the venue.
|
||||
foursquare_id (:obj:`str`, optional): Foursquare identifier of the venue.
|
||||
foursquare_type (:obj:`str`, optional): Foursquare type of the venue. (For example,
|
||||
"arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".)
|
||||
google_place_id (:obj:`str`, optional): Google Places identifier of the venue.
|
||||
google_place_type (:obj:`str`, optional): Google Places type of the venue. (See
|
||||
`supported types <https://developers.google.com/maps/documentation/places/web-service\
|
||||
/supported_types>`_.)
|
||||
|
||||
Attributes:
|
||||
location (:class:`telegram.Location`): Venue location.
|
||||
title (:obj:`str`): Name of the venue.
|
||||
address (:obj:`str`): Address of the venue.
|
||||
foursquare_id (:obj:`str`): Optional. Foursquare identifier of the venue.
|
||||
foursquare_type (:obj:`str`): Optional. Foursquare type of the venue. (For example,
|
||||
"arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".)
|
||||
google_place_id (:obj:`str`): Optional. Google Places identifier of the venue.
|
||||
google_place_type (:obj:`str`): Optional. Google Places type of the venue. (See
|
||||
`supported types <https://developers.google.com/maps/documentation/places/web-service\
|
||||
/supported_types>`_.)
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"address",
|
||||
"foursquare_id",
|
||||
"foursquare_type",
|
||||
"google_place_id",
|
||||
"google_place_type",
|
||||
"location",
|
||||
"title",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
location: Location,
|
||||
title: str,
|
||||
address: str,
|
||||
foursquare_id: Optional[str] = None,
|
||||
foursquare_type: Optional[str] = None,
|
||||
google_place_id: Optional[str] = None,
|
||||
google_place_type: Optional[str] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
|
||||
# Required
|
||||
self.location: Location = location
|
||||
self.title: str = title
|
||||
self.address: str = address
|
||||
# Optionals
|
||||
self.foursquare_id: Optional[str] = foursquare_id
|
||||
self.foursquare_type: Optional[str] = foursquare_type
|
||||
self.google_place_id: Optional[str] = google_place_id
|
||||
self.google_place_type: Optional[str] = google_place_type
|
||||
|
||||
self._id_attrs = (self.location, self.title)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "Venue":
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
data["location"] = de_json_optional(data.get("location"), Location, bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
165
.venv/lib/python3.12/site-packages/telegram/_files/video.py
Normal file
165
.venv/lib/python3.12/site-packages/telegram/_files/video.py
Normal file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram Video."""
|
||||
import datetime as dtm
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._utils.argumentparsing import de_list_optional, parse_sequence_arg, to_timedelta
|
||||
from telegram._utils.datetime import get_timedelta_value
|
||||
from telegram._utils.types import JSONDict, TimePeriod
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from telegram import Bot
|
||||
|
||||
|
||||
class Video(_BaseThumbedMedium):
|
||||
"""This object represents a video file.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by the sender.
|
||||
height (:obj:`int`): Video height as defined by the sender.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the video
|
||||
in seconds as defined by the sender.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
file_name (:obj:`str`, optional): Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`, optional): MIME type of a file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Video thumbnail.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
cover (Sequence[:class:`telegram.PhotoSize`], optional): Available sizes of the cover of
|
||||
the video in the message.
|
||||
|
||||
.. versionadded:: 21.11
|
||||
start_timestamp (:obj:`int` | :class:`datetime.timedelta`, optional): Timestamp in seconds
|
||||
from which the video will play in the message
|
||||
.. versionadded:: 21.11
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
width (:obj:`int`): Video width as defined by the sender.
|
||||
height (:obj:`int`): Video height as defined by the sender.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the video in seconds
|
||||
as defined by the sender.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
file_name (:obj:`str`): Optional. Original filename as defined by the sender.
|
||||
mime_type (:obj:`str`): Optional. MIME type of a file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Video thumbnail.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
cover (tuple[:class:`telegram.PhotoSize`]): Optional, Available sizes of the cover of
|
||||
the video in the message.
|
||||
|
||||
.. versionadded:: 21.11
|
||||
start_timestamp (:obj:`int` | :class:`datetime.timedelta`): Optional. Timestamp in seconds
|
||||
from which the video will play in the message
|
||||
.. versionadded:: 21.11
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
"_duration",
|
||||
"_start_timestamp",
|
||||
"cover",
|
||||
"file_name",
|
||||
"height",
|
||||
"mime_type",
|
||||
"width",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
duration: TimePeriod,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
file_name: Optional[str] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
cover: Optional[Sequence[PhotoSize]] = None,
|
||||
start_timestamp: Optional[TimePeriod] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.width: int = width
|
||||
self.height: int = height
|
||||
self._duration: dtm.timedelta = to_timedelta(duration)
|
||||
# Optional
|
||||
self.mime_type: Optional[str] = mime_type
|
||||
self.file_name: Optional[str] = file_name
|
||||
self.cover: Optional[Sequence[PhotoSize]] = parse_sequence_arg(cover)
|
||||
self._start_timestamp: Optional[dtm.timedelta] = to_timedelta(start_timestamp)
|
||||
|
||||
@property
|
||||
def duration(self) -> Union[int, dtm.timedelta]:
|
||||
return get_timedelta_value( # type: ignore[return-value]
|
||||
self._duration, attribute="duration"
|
||||
)
|
||||
|
||||
@property
|
||||
def start_timestamp(self) -> Optional[Union[int, dtm.timedelta]]:
|
||||
return get_timedelta_value(self._start_timestamp, attribute="start_timestamp")
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "Video":
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
data = cls._parse_data(data)
|
||||
|
||||
data["cover"] = de_list_optional(data.get("cover"), PhotoSize, bot)
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
107
.venv/lib/python3.12/site-packages/telegram/_files/videonote.py
Normal file
107
.venv/lib/python3.12/site-packages/telegram/_files/videonote.py
Normal file
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram VideoNote."""
|
||||
|
||||
import datetime as dtm
|
||||
from typing import Optional, Union
|
||||
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._utils.argumentparsing import to_timedelta
|
||||
from telegram._utils.datetime import get_timedelta_value
|
||||
from telegram._utils.types import JSONDict, TimePeriod
|
||||
|
||||
|
||||
class VideoNote(_BaseThumbedMedium):
|
||||
"""This object represents a video message (available in Telegram apps as of v.4.0).
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
.. versionchanged:: 20.5
|
||||
|removed_thumb_note|
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
length (:obj:`int`): Video width and height (diameter of the video message) as defined
|
||||
by sender.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the video in
|
||||
seconds as defined by the sender.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`, optional): Video thumbnail.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
length (:obj:`int`): Video width and height (diameter of the video message) as defined
|
||||
by sender.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the video in seconds as
|
||||
defined by the sender.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
thumbnail (:class:`telegram.PhotoSize`): Optional. Video thumbnail.
|
||||
|
||||
.. versionadded:: 20.2
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("_duration", "length")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
length: int,
|
||||
duration: TimePeriod,
|
||||
file_size: Optional[int] = None,
|
||||
thumbnail: Optional[PhotoSize] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
thumbnail=thumbnail,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.length: int = length
|
||||
self._duration: dtm.timedelta = to_timedelta(duration)
|
||||
|
||||
@property
|
||||
def duration(self) -> Union[int, dtm.timedelta]:
|
||||
return get_timedelta_value( # type: ignore[return-value]
|
||||
self._duration, attribute="duration"
|
||||
)
|
||||
93
.venv/lib/python3.12/site-packages/telegram/_files/voice.py
Normal file
93
.venv/lib/python3.12/site-packages/telegram/_files/voice.py
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2025
|
||||
# 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 that represents a Telegram Voice."""
|
||||
import datetime as dtm
|
||||
from typing import Optional, Union
|
||||
|
||||
from telegram._files._basemedium import _BaseMedium
|
||||
from telegram._utils.argumentparsing import to_timedelta
|
||||
from telegram._utils.datetime import get_timedelta_value
|
||||
from telegram._utils.types import JSONDict, TimePeriod
|
||||
|
||||
|
||||
class Voice(_BaseMedium):
|
||||
"""This object represents a voice note.
|
||||
|
||||
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||
considered equal, if their :attr:`file_unique_id` is equal.
|
||||
|
||||
Args:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the audio in
|
||||
seconds as defined by the sender.
|
||||
|
||||
.. versionchanged:: v22.2
|
||||
|time-period-input|
|
||||
mime_type (:obj:`str`, optional): MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`, optional): File size in bytes.
|
||||
|
||||
Attributes:
|
||||
file_id (:obj:`str`): Identifier for this file, which can be used to download
|
||||
or reuse the file.
|
||||
file_unique_id (:obj:`str`): Unique identifier for this file, which
|
||||
is supposed to be the same over time and for different bots.
|
||||
Can't be used to download or reuse the file.
|
||||
duration (:obj:`int` | :class:`datetime.timedelta`): Duration of the audio in seconds as
|
||||
defined by the sender.
|
||||
|
||||
.. deprecated:: v22.2
|
||||
|time-period-int-deprecated|
|
||||
mime_type (:obj:`str`): Optional. MIME type of the file as defined by the sender.
|
||||
file_size (:obj:`int`): Optional. File size in bytes.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("_duration", "mime_type")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
duration: TimePeriod,
|
||||
mime_type: Optional[str] = None,
|
||||
file_size: Optional[int] = None,
|
||||
*,
|
||||
api_kwargs: Optional[JSONDict] = None,
|
||||
):
|
||||
super().__init__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
file_size=file_size,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self._duration: dtm.timedelta = to_timedelta(duration)
|
||||
# Optional
|
||||
self.mime_type: Optional[str] = mime_type
|
||||
|
||||
@property
|
||||
def duration(self) -> Union[int, dtm.timedelta]:
|
||||
return get_timedelta_value( # type: ignore[return-value]
|
||||
self._duration, attribute="duration"
|
||||
)
|
||||
Reference in New Issue
Block a user