2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-29 05:18:10 +00:00

Replace integer timestamps with datetime objects

This commit is contained in:
Dan 2022-04-24 11:56:06 +02:00
parent bbad58a83f
commit b697826b5a
48 changed files with 359 additions and 333 deletions

View File

@ -18,7 +18,6 @@
import os import os
import sys import sys
from datetime import datetime
sys.path.insert(0, os.path.abspath("../..")) sys.path.insert(0, os.path.abspath("../.."))
@ -38,9 +37,14 @@ extensions = [
"sphinx.ext.autodoc", "sphinx.ext.autodoc",
"sphinx.ext.napoleon", "sphinx.ext.napoleon",
"sphinx.ext.autosummary", "sphinx.ext.autosummary",
"sphinx.ext.intersphinx",
"sphinx_copybutton" "sphinx_copybutton"
] ]
intersphinx_mapping = {
"python": ("https://docs.python.org/3", None)
}
master_doc = "index" master_doc = "index"
source_suffix = ".rst" source_suffix = ".rst"
autodoc_member_order = "bysource" autodoc_member_order = "bysource"

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union from typing import Union
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.scaffold import Scaffold from pyrogram.scaffold import Scaffold
@ -28,7 +29,7 @@ class BanChatMember(Scaffold):
self, self,
chat_id: Union[int, str], chat_id: Union[int, str],
user_id: Union[int, str], user_id: Union[int, str],
until_date: int = 0 until_date: datetime = datetime.fromtimestamp(0)
) -> Union["types.Message", bool]: ) -> Union["types.Message", bool]:
"""Ban a user from a group, a supergroup or a channel. """Ban a user from a group, a supergroup or a channel.
In the case of supergroups and channels, the user will not be able to return to the group on their own using In the case of supergroups and channels, the user will not be able to return to the group on their own using
@ -48,10 +49,10 @@ class BanChatMember(Scaffold):
Unique identifier (int) or username (str) of the target user. Unique identifier (int) or username (str) of the target user.
For a contact that exists in your Telegram address book you can use his phone number (str). For a contact that exists in your Telegram address book you can use his phone number (str).
until_date (``int``, *optional*): until_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the user will be unbanned, unix time. Date when the user will be unbanned.
If user is banned for more than 366 days or less than 30 seconds from the current time they are If user is banned for more than 366 days or less than 30 seconds from the current time they are
considered to be banned forever. Defaults to 0 (ban forever). considered to be banned forever. Defaults to epoch (ban forever).
Returns: Returns:
:obj:`~pyrogram.types.Message` | ``bool``: On success, a service message will be returned (when applicable), :obj:`~pyrogram.types.Message` | ``bool``: On success, a service message will be returned (when applicable),
@ -60,13 +61,13 @@ class BanChatMember(Scaffold):
Example: Example:
.. code-block:: python .. code-block:: python
from time import time from datetime import datetime, timedelta
# Ban chat member forever # Ban chat member forever
app.ban_chat_member(chat_id, user_id) app.ban_chat_member(chat_id, user_id)
# Ban chat member and automatically unban after 24h # Ban chat member and automatically unban after 24h
app.ban_chat_member(chat_id, user_id, int(time.time() + 86400)) app.ban_chat_member(chat_id, user_id, datetime.now() + timedelta(days=1))
""" """
chat_peer = await self.resolve_peer(chat_id) chat_peer = await self.resolve_peer(chat_id)
user_peer = await self.resolve_peer(user_id) user_peer = await self.resolve_peer(user_id)
@ -77,7 +78,7 @@ class BanChatMember(Scaffold):
channel=chat_peer, channel=chat_peer,
participant=user_peer, participant=user_peer,
banned_rights=raw.types.ChatBannedRights( banned_rights=raw.types.ChatBannedRights(
until_date=until_date, until_date=utils.datetime_to_timestamp(until_date),
view_messages=True, view_messages=True,
send_messages=True, send_messages=True,
send_media=True, send_media=True,

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from datetime import datetime
from typing import List from typing import List
from pyrogram import raw from pyrogram import raw
@ -30,7 +31,7 @@ log = logging.getLogger(__name__)
class GetDialogs(Scaffold): class GetDialogs(Scaffold):
async def get_dialogs( async def get_dialogs(
self, self,
offset_date: int = 0, offset_date: datetime = datetime.fromtimestamp(0),
limit: int = 100, limit: int = 100,
pinned_only: bool = False pinned_only: bool = False
) -> List["types.Dialog"]: ) -> List["types.Dialog"]:
@ -40,9 +41,9 @@ class GetDialogs(Scaffold):
For a more convenient way of getting a user's dialogs see :meth:`~pyrogram.Client.iter_dialogs`. For a more convenient way of getting a user's dialogs see :meth:`~pyrogram.Client.iter_dialogs`.
Parameters: Parameters:
offset_date (``int``): offset_date (:py:obj:`~datetime.datetime`):
The offset date in Unix time taken from the top message of a :obj:`~pyrogram.types.Dialog`. The offset date taken from the top message of a :obj:`~pyrogram.types.Dialog`.
Defaults to 0. Valid for non-pinned dialogs only. Defaults to epoch. Valid for non-pinned dialogs only.
limit (``str``, *optional*): limit (``str``, *optional*):
Limits the number of dialogs to be retrieved. Limits the number of dialogs to be retrieved.
@ -73,7 +74,7 @@ class GetDialogs(Scaffold):
else: else:
r = await self.send( r = await self.send(
raw.functions.messages.GetDialogs( raw.functions.messages.GetDialogs(
offset_date=offset_date, offset_date=utils.datetime_to_timestamp(offset_date),
offset_id=0, offset_id=0,
offset_peer=raw.types.InputPeerEmpty(), offset_peer=raw.types.InputPeerEmpty(),
limit=limit, limit=limit,

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union from typing import Union
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.scaffold import Scaffold from pyrogram.scaffold import Scaffold
@ -29,7 +30,7 @@ class RestrictChatMember(Scaffold):
chat_id: Union[int, str], chat_id: Union[int, str],
user_id: Union[int, str], user_id: Union[int, str],
permissions: "types.ChatPermissions", permissions: "types.ChatPermissions",
until_date: int = 0 until_date: datetime = datetime.fromtimestamp(0)
) -> "types.Chat": ) -> "types.Chat":
"""Restrict a user in a supergroup. """Restrict a user in a supergroup.
@ -47,10 +48,10 @@ class RestrictChatMember(Scaffold):
permissions (:obj:`~pyrogram.types.ChatPermissions`): permissions (:obj:`~pyrogram.types.ChatPermissions`):
New user permissions. New user permissions.
until_date (``int``, *optional*): until_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the user will be unbanned, unix time. Date when the user will be unbanned.
If user is banned for more than 366 days or less than 30 seconds from the current time they are If user is banned for more than 366 days or less than 30 seconds from the current time they are
considered to be banned forever. Defaults to 0 (ban forever). considered to be banned forever. Defaults to epoch (ban forever).
Returns: Returns:
:obj:`~pyrogram.types.Chat`: On success, a chat object is returned. :obj:`~pyrogram.types.Chat`: On success, a chat object is returned.
@ -58,7 +59,7 @@ class RestrictChatMember(Scaffold):
Example: Example:
.. code-block:: python .. code-block:: python
from time import time from datetime import datetime, timedelta
from pyrogram.types import ChatPermissions from pyrogram.types import ChatPermissions
@ -66,7 +67,7 @@ class RestrictChatMember(Scaffold):
app.restrict_chat_member(chat_id, user_id, ChatPermissions()) app.restrict_chat_member(chat_id, user_id, ChatPermissions())
# Chat member muted for 24h # Chat member muted for 24h
app.restrict_chat_member(chat_id, user_id, ChatPermissions(), int(time() + 86400)) app.restrict_chat_member(chat_id, user_id, ChatPermissions(), datetime.now() + timedelta(days=1))
# Chat member can only send text messages # Chat member can only send text messages
app.restrict_chat_member(chat_id, user_id, ChatPermissions(can_send_messages=True)) app.restrict_chat_member(chat_id, user_id, ChatPermissions(can_send_messages=True))
@ -76,7 +77,7 @@ class RestrictChatMember(Scaffold):
channel=await self.resolve_peer(chat_id), channel=await self.resolve_peer(chat_id),
participant=await self.resolve_peer(user_id), participant=await self.resolve_peer(user_id),
banned_rights=raw.types.ChatBannedRights( banned_rights=raw.types.ChatBannedRights(
until_date=until_date, until_date=utils.datetime_to_timestamp(until_date),
send_messages=not permissions.can_send_messages, send_messages=not permissions.can_send_messages,
send_media=not permissions.can_send_media_messages, send_media=not permissions.can_send_media_messages,
send_stickers=not permissions.can_send_other_messages, send_stickers=not permissions.can_send_other_messages,

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union from typing import Union
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.scaffold import Scaffold from pyrogram.scaffold import Scaffold
@ -28,7 +29,7 @@ class CreateChatInviteLink(Scaffold):
self, self,
chat_id: Union[int, str], chat_id: Union[int, str],
name: str = None, name: str = None,
expire_date: int = None, expire_date: datetime = None,
member_limit: int = None, member_limit: int = None,
creates_join_request: bool = None creates_join_request: bool = None
) -> "types.ChatInviteLink": ) -> "types.ChatInviteLink":
@ -46,8 +47,8 @@ class CreateChatInviteLink(Scaffold):
name (``str``, *optional*): name (``str``, *optional*):
Invite link name. Invite link name.
expire_date (``int``, *optional*): expire_date (:py:obj:`~datetime.datetime`, *optional*):
Point in time (Unix timestamp) when the link will expire. Point in time when the link will expire.
Defaults to None (no expiration date). Defaults to None (no expiration date).
member_limit (``int``, *optional*): member_limit (``int``, *optional*):
@ -74,7 +75,7 @@ class CreateChatInviteLink(Scaffold):
r = await self.send( r = await self.send(
raw.functions.messages.ExportChatInvite( raw.functions.messages.ExportChatInvite(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
expire_date=expire_date, expire_date=utils.datetime_to_timestamp(expire_date),
usage_limit=member_limit, usage_limit=member_limit,
title=name, title=name,
request_needed=creates_join_request request_needed=creates_join_request

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union from typing import Union
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.scaffold import Scaffold from pyrogram.scaffold import Scaffold
@ -29,7 +30,7 @@ class EditChatInviteLink(Scaffold):
chat_id: Union[int, str], chat_id: Union[int, str],
invite_link: str, invite_link: str,
name: str = None, name: str = None,
expire_date: int = None, expire_date: datetime = None,
member_limit: int = None, member_limit: int = None,
creates_join_request: bool = None creates_join_request: bool = None
) -> "types.ChatInviteLink": ) -> "types.ChatInviteLink":
@ -48,9 +49,9 @@ class EditChatInviteLink(Scaffold):
name (``str``, *optional*): name (``str``, *optional*):
Invite link name. Invite link name.
expire_date (``int``, *optional*): expire_date (:py:obj:`~datetime.datetime`, *optional*):
Point in time (Unix timestamp) when the link will expire. Point in time when the link will expire.
Defaults to None (no change), pass 0 to set no expiration date. Defaults to None (no change), pass ``datetime.fromtimestamp(0)`` to set no expiration date.
member_limit (``int``, *optional*): member_limit (``int``, *optional*):
Maximum number of users that can be members of the chat simultaneously after joining the chat via this Maximum number of users that can be members of the chat simultaneously after joining the chat via this
@ -77,7 +78,7 @@ class EditChatInviteLink(Scaffold):
raw.functions.messages.EditExportedChatInvite( raw.functions.messages.EditExportedChatInvite(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
link=invite_link, link=invite_link,
expire_date=expire_date, expire_date=utils.datetime_to_timestamp(expire_date),
usage_limit=member_limit, usage_limit=member_limit,
title=name, title=name,
request_needed=creates_join_request request_needed=creates_join_request

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union, List from typing import Union, List
from pyrogram import types, utils, raw from pyrogram import types, utils, raw
@ -31,7 +32,7 @@ class CopyMediaGroup(Scaffold):
captions: Union[List[str], str] = None, captions: Union[List[str], str] = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
) -> List["types.Message"]: ) -> List["types.Message"]:
"""Copy a media group by providing one of the message ids. """Copy a media group by providing one of the message ids.
@ -65,8 +66,8 @@ class CopyMediaGroup(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
Returns: Returns:
List of :obj:`~pyrogram.types.Message`: On success, a list of copied messages is returned. List of :obj:`~pyrogram.types.Message`: On success, a list of copied messages is returned.
@ -114,7 +115,7 @@ class CopyMediaGroup(Scaffold):
multi_media=multi_media, multi_media=multi_media,
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
schedule_date=schedule_date schedule_date=utils.datetime_to_timestamp(schedule_date)
), ),
sleep_threshold=60 sleep_threshold=60
) )

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from datetime import datetime
from typing import Union, List, Optional from typing import Union, List, Optional
from pyrogram import types, enums from pyrogram import types, enums
@ -36,7 +37,7 @@ class CopyMessage(Scaffold):
caption_entities: List["types.MessageEntity"] = None, caption_entities: List["types.MessageEntity"] = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -83,8 +84,8 @@ class CopyMessage(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.

View File

@ -16,9 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union, Iterable, List from typing import Union, Iterable, List
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.scaffold import Scaffold from pyrogram.scaffold import Scaffold
@ -30,7 +31,7 @@ class ForwardMessages(Scaffold):
from_chat_id: Union[int, str], from_chat_id: Union[int, str],
message_ids: Union[int, Iterable[int]], message_ids: Union[int, Iterable[int]],
disable_notification: bool = None, disable_notification: bool = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None protect_content: bool = None
) -> Union["types.Message", List["types.Message"]]: ) -> Union["types.Message", List["types.Message"]]:
"""Forward messages of any kind. """Forward messages of any kind.
@ -54,8 +55,8 @@ class ForwardMessages(Scaffold):
Sends the message silently. Sends the message silently.
Users will receive a notification with no sound. Users will receive a notification with no sound.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -85,7 +86,7 @@ class ForwardMessages(Scaffold):
id=message_ids, id=message_ids,
silent=disable_notification or None, silent=disable_notification or None,
random_id=[self.rnd_id() for _ in message_ids], random_id=[self.rnd_id() for _ in message_ids],
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content noforwards=protect_content
) )
) )

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from datetime import datetime
from typing import Union, List from typing import Union, List
from pyrogram import raw from pyrogram import raw
@ -34,7 +35,7 @@ class GetHistory(Scaffold):
limit: int = 100, limit: int = 100,
offset: int = 0, offset: int = 0,
offset_id: int = 0, offset_id: int = 0,
offset_date: int = 0, offset_date: datetime = datetime.fromtimestamp(0),
reverse: bool = False reverse: bool = False
) -> List["types.Message"]: ) -> List["types.Message"]:
"""Retrieve a chunk of the history of a chat. """Retrieve a chunk of the history of a chat.
@ -59,8 +60,8 @@ class GetHistory(Scaffold):
offset_id (``int``, *optional*): offset_id (``int``, *optional*):
Pass a message identifier as offset to retrieve only older messages starting from that message. Pass a message identifier as offset to retrieve only older messages starting from that message.
offset_date (``int``, *optional*): offset_date (:py:obj:`~datetime.datetime`, *optional*):
Pass a date in Unix time as offset to retrieve only older messages starting from that date. Pass a date as offset to retrieve only older messages starting from that date.
reverse (``bool``, *optional*): reverse (``bool``, *optional*):
Pass True to retrieve the messages in reversed order (from older to most recent). Pass True to retrieve the messages in reversed order (from older to most recent).
@ -89,7 +90,7 @@ class GetHistory(Scaffold):
raw.functions.messages.GetHistory( raw.functions.messages.GetHistory(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
offset_id=offset_id, offset_id=offset_id,
offset_date=offset_date, offset_date=utils.datetime_to_timestamp(offset_date),
add_offset=offset * (-1 if reverse else 1) - (limit if reverse else 0), add_offset=offset * (-1 if reverse else 1) - (limit if reverse else 0),
limit=limit, limit=limit,
max_id=0, max_id=0,

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union, Optional, AsyncGenerator from typing import Union, Optional, AsyncGenerator
from pyrogram import types from pyrogram import types
@ -29,7 +30,7 @@ class IterHistory(Scaffold):
limit: int = 0, limit: int = 0,
offset: int = 0, offset: int = 0,
offset_id: int = 0, offset_id: int = 0,
offset_date: int = 0, offset_date: datetime = datetime.fromtimestamp(0),
reverse: bool = False reverse: bool = False
) -> Optional[AsyncGenerator["types.Message", None]]: ) -> Optional[AsyncGenerator["types.Message", None]]:
"""Iterate through a chat history sequentially. """Iterate through a chat history sequentially.
@ -55,8 +56,8 @@ class IterHistory(Scaffold):
offset_id (``int``, *optional*): offset_id (``int``, *optional*):
Identifier of the first message to be returned. Identifier of the first message to be returned.
offset_date (``int``, *optional*): offset_date (:py:obj:`~datetime.datetime`, *optional*):
Pass a date in Unix time as offset to retrieve only older messages starting from that date. Pass a date as offset to retrieve only older messages starting from that date.
reverse (``bool``, *optional*): reverse (``bool``, *optional*):
Pass True to retrieve the messages in reversed order (from older to most recent). Pass True to retrieve the messages in reversed order (from older to most recent).

View File

@ -18,6 +18,7 @@
import os import os
import re import re
from datetime import datetime
from typing import Union, BinaryIO, List, Optional from typing import Union, BinaryIO, List, Optional
from pyrogram import StopTransmission, enums from pyrogram import StopTransmission, enums
@ -45,7 +46,7 @@ class SendAnimation(Scaffold):
file_name: str = None, file_name: str = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -111,8 +112,8 @@ class SendAnimation(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -222,7 +223,7 @@ class SendAnimation(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities) **await utils.parse_text_entities(self, caption, parse_mode, caption_entities)

View File

@ -27,6 +27,7 @@ from pyrogram import utils
from pyrogram.errors import FilePartMissing from pyrogram.errors import FilePartMissing
from pyrogram.file_id import FileType from pyrogram.file_id import FileType
from pyrogram.scaffold import Scaffold from pyrogram.scaffold import Scaffold
from datetime import datetime
class SendAudio(Scaffold): class SendAudio(Scaffold):
@ -44,7 +45,7 @@ class SendAudio(Scaffold):
file_name: str = None, file_name: str = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -108,8 +109,8 @@ class SendAudio(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -216,7 +217,7 @@ class SendAudio(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities) **await utils.parse_text_entities(self, caption, parse_mode, caption_entities)

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union, List, Optional from typing import Union, List, Optional
from pyrogram import raw, enums from pyrogram import raw, enums
@ -34,7 +35,7 @@ class SendCachedMedia(Scaffold):
caption_entities: List["types.MessageEntity"] = None, caption_entities: List["types.MessageEntity"] = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -76,8 +77,8 @@ class SendCachedMedia(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -102,7 +103,7 @@ class SendCachedMedia(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities) **await utils.parse_text_entities(self, caption, parse_mode, caption_entities)

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union from typing import Union
from pyrogram import raw from pyrogram import raw
@ -33,7 +34,7 @@ class SendContact(Scaffold):
vcard: str = None, vcard: str = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -69,8 +70,8 @@ class SendContact(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -100,7 +101,7 @@ class SendContact(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None reply_markup=await reply_markup.write(self) if reply_markup else None
) )

View File

@ -21,6 +21,7 @@ from typing import Union, Optional
from pyrogram import raw from pyrogram import raw
from pyrogram import types from pyrogram import types
from pyrogram.scaffold import Scaffold from pyrogram.scaffold import Scaffold
from datetime import datetime
class SendDice(Scaffold): class SendDice(Scaffold):
@ -30,7 +31,7 @@ class SendDice(Scaffold):
emoji: str = "🎲", emoji: str = "🎲",
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -61,8 +62,8 @@ class SendDice(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -94,7 +95,7 @@ class SendDice(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
message="" message=""

View File

@ -18,6 +18,7 @@
import os import os
import re import re
from datetime import datetime
from typing import Union, BinaryIO, List, Optional from typing import Union, BinaryIO, List, Optional
from pyrogram import StopTransmission, enums from pyrogram import StopTransmission, enums
@ -42,7 +43,7 @@ class SendDocument(Scaffold):
force_document: bool = None, force_document: bool = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -100,8 +101,8 @@ class SendDocument(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -194,7 +195,7 @@ class SendDocument(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities) **await utils.parse_text_entities(self, caption, parse_mode, caption_entities)

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union from typing import Union
from pyrogram import raw from pyrogram import raw
@ -31,7 +32,7 @@ class SendLocation(Scaffold):
longitude: float, longitude: float,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -61,8 +62,8 @@ class SendLocation(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message If the message is a reply, ID of the original message
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -92,7 +93,7 @@ class SendLocation(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None reply_markup=await reply_markup.write(self) if reply_markup else None
) )

View File

@ -19,6 +19,7 @@
import logging import logging
import os import os
import re import re
from datetime import datetime
from typing import Union, List from typing import Union, List
from pyrogram import raw from pyrogram import raw
@ -43,7 +44,7 @@ class SendMediaGroup(Scaffold):
]], ]],
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
) -> List["types.Message"]: ) -> List["types.Message"]:
"""Send a group of photos or videos as an album. """Send a group of photos or videos as an album.
@ -64,8 +65,8 @@ class SendMediaGroup(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -381,7 +382,7 @@ class SendMediaGroup(Scaffold):
multi_media=multi_media, multi_media=multi_media,
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content noforwards=protect_content
), ),
sleep_threshold=60 sleep_threshold=60

View File

@ -22,6 +22,8 @@ from pyrogram import raw, utils, enums
from pyrogram import types from pyrogram import types
from pyrogram.scaffold import Scaffold from pyrogram.scaffold import Scaffold
from datetime import datetime
class SendMessage(Scaffold): class SendMessage(Scaffold):
async def send_message( async def send_message(
@ -33,7 +35,7 @@ class SendMessage(Scaffold):
disable_web_page_preview: bool = None, disable_web_page_preview: bool = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -70,8 +72,8 @@ class SendMessage(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -129,7 +131,7 @@ class SendMessage(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
message=message, message=message,
entities=entities, entities=entities,
@ -150,11 +152,11 @@ class SendMessage(Scaffold):
message_id=r.id, message_id=r.id,
chat=types.Chat( chat=types.Chat(
id=peer_id, id=peer_id,
type="private", type=enums.ChatType.PRIVATE,
client=self client=self
), ),
text=message, text=message,
date=r.date, date=utils.timestamp_to_datetime(r.date),
outgoing=r.out, outgoing=r.out,
reply_markup=reply_markup, reply_markup=reply_markup,
entities=[ entities=[

View File

@ -18,6 +18,7 @@
import os import os
import re import re
from datetime import datetime
from typing import Union, BinaryIO, List, Optional from typing import Union, BinaryIO, List, Optional
import pyrogram import pyrogram
@ -40,7 +41,7 @@ class SendPhoto(Scaffold):
ttl_seconds: int = None, ttl_seconds: int = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -88,8 +89,8 @@ class SendPhoto(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -172,7 +173,7 @@ class SendPhoto(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities) **await utils.parse_text_entities(self, caption, parse_mode, caption_entities)

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union, List from typing import Union, List
from pyrogram import raw from pyrogram import raw
@ -35,7 +36,7 @@ class SendPoll(Scaffold):
correct_option_id: int = None, correct_option_id: int = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -81,8 +82,8 @@ class SendPoll(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -120,7 +121,7 @@ class SendPoll(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None reply_markup=await reply_markup.write(self) if reply_markup else None
) )

View File

@ -18,6 +18,7 @@
import os import os
import re import re
from datetime import datetime
from typing import Union, BinaryIO, Optional from typing import Union, BinaryIO, Optional
from pyrogram import StopTransmission from pyrogram import StopTransmission
@ -36,7 +37,7 @@ class SendSticker(Scaffold):
sticker: Union[str, BinaryIO], sticker: Union[str, BinaryIO],
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -69,8 +70,8 @@ class SendSticker(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -153,7 +154,7 @@ class SendSticker(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
message="" message=""

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union from typing import Union
from pyrogram import raw from pyrogram import raw
@ -35,7 +36,7 @@ class SendVenue(Scaffold):
foursquare_type: str = "", foursquare_type: str = "",
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -78,8 +79,8 @@ class SendVenue(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message If the message is a reply, ID of the original message
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -116,7 +117,7 @@ class SendVenue(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None reply_markup=await reply_markup.write(self) if reply_markup else None
) )

View File

@ -18,6 +18,7 @@
import os import os
import re import re
from datetime import datetime
from typing import Union, BinaryIO, List, Optional from typing import Union, BinaryIO, List, Optional
from pyrogram import StopTransmission, enums from pyrogram import StopTransmission, enums
@ -46,7 +47,7 @@ class SendVideo(Scaffold):
supports_streaming: bool = True, supports_streaming: bool = True,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -117,8 +118,8 @@ class SendVideo(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -228,7 +229,7 @@ class SendVideo(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities) **await utils.parse_text_entities(self, caption, parse_mode, caption_entities)

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import os import os
from datetime import datetime
from typing import Union, BinaryIO, Optional from typing import Union, BinaryIO, Optional
from pyrogram import StopTransmission from pyrogram import StopTransmission
@ -38,7 +39,7 @@ class SendVideoNote(Scaffold):
thumb: Union[str, BinaryIO] = None, thumb: Union[str, BinaryIO] = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -83,8 +84,8 @@ class SendVideoNote(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message If the message is a reply, ID of the original message
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -177,7 +178,7 @@ class SendVideoNote(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
message="" message=""

View File

@ -18,6 +18,7 @@
import os import os
import re import re
from datetime import datetime
from typing import Union, BinaryIO, List, Optional from typing import Union, BinaryIO, List, Optional
from pyrogram import StopTransmission, enums from pyrogram import StopTransmission, enums
@ -40,7 +41,7 @@ class SendVoice(Scaffold):
duration: int = 0, duration: int = 0,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -86,8 +87,8 @@ class SendVoice(Scaffold):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message If the message is a reply, ID of the original message
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -178,7 +179,7 @@ class SendVoice(Scaffold):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date, schedule_date=utils.datetime_to_timestamp(schedule_date),
noforwards=protect_content, noforwards=protect_content,
reply_markup=await reply_markup.write(self) if reply_markup else None, reply_markup=await reply_markup.write(self) if reply_markup else None,
**await utils.parse_text_entities(self, caption, parse_mode, caption_entities) **await utils.parse_text_entities(self, caption, parse_mode, caption_entities)

View File

@ -30,7 +30,7 @@ class Parser:
self.html = HTML(client) self.html = HTML(client)
self.markdown = Markdown(client) self.markdown = Markdown(client)
async def parse(self, text: str, mode: Optional[str] = None): async def parse(self, text: str, mode: Optional[enums.ParseMode] = None):
text = str(text if text else "").strip() text = str(text if text else "").strip()
if mode is None: if mode is None:

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import List from typing import List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object from ..object import Object
@ -54,8 +55,8 @@ class Animation(Object):
file_size (``int``, *optional*): file_size (``int``, *optional*):
File size. File size.
date (``int``, *optional*): date (:py:obj:`~datetime.datetime`, *optional*):
Date the animation was sent in Unix time. Date the animation was sent.
thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*): thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*):
Animation thumbnails. Animation thumbnails.
@ -73,7 +74,7 @@ class Animation(Object):
file_name: str = None, file_name: str = None,
mime_type: str = None, mime_type: str = None,
file_size: int = None, file_size: int = None,
date: int = None, date: datetime = None,
thumbs: List["types.Thumbnail"] = None thumbs: List["types.Thumbnail"] = None
): ):
super().__init__(client) super().__init__(client)
@ -114,7 +115,7 @@ class Animation(Object):
mime_type=animation.mime_type, mime_type=animation.mime_type,
file_size=animation.size, file_size=animation.size,
file_name=file_name, file_name=file_name,
date=animation.date, date=utils.timestamp_to_datetime(animation.date),
thumbs=types.Thumbnail._parse(client, animation), thumbs=types.Thumbnail._parse(client, animation),
client=client client=client
) )

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import List from typing import List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object from ..object import Object
@ -54,8 +55,8 @@ class Audio(Object):
file_size (``int``, *optional*): file_size (``int``, *optional*):
File size. File size.
date (``int``, *optional*): date (:py:obj:`~datetime.datetime`, *optional*):
Date the audio was originally sent, in Unix time. Date the audio was originally sent.
thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*): thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*):
Thumbnails of the music file album cover. Thumbnails of the music file album cover.
@ -73,7 +74,7 @@ class Audio(Object):
file_name: str = None, file_name: str = None,
mime_type: str = None, mime_type: str = None,
file_size: int = None, file_size: int = None,
date: int = None, date: datetime = None,
thumbs: List["types.Thumbnail"] = None thumbs: List["types.Thumbnail"] = None
): ):
super().__init__(client) super().__init__(client)
@ -114,7 +115,7 @@ class Audio(Object):
mime_type=audio.mime_type, mime_type=audio.mime_type,
file_size=audio.size, file_size=audio.size,
file_name=file_name, file_name=file_name,
date=audio.date, date=utils.timestamp_to_datetime(audio.date),
thumbs=types.Thumbnail._parse(client, audio), thumbs=types.Thumbnail._parse(client, audio),
client=client client=client
) )

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import List from typing import List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object from ..object import Object
@ -45,8 +46,8 @@ class Document(Object):
file_size (``int``, *optional*): file_size (``int``, *optional*):
File size. File size.
date (``int``, *optional*): date (:py:obj:`~datetime.datetime`, *optional*):
Date the document was sent in Unix time. Date the document was sent.
thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*): thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*):
Document thumbnails as defined by sender. Document thumbnails as defined by sender.
@ -61,7 +62,7 @@ class Document(Object):
file_name: str = None, file_name: str = None,
mime_type: str = None, mime_type: str = None,
file_size: int = None, file_size: int = None,
date: int = None, date: datetime = None,
thumbs: List["types.Thumbnail"] = None thumbs: List["types.Thumbnail"] = None
): ):
super().__init__(client) super().__init__(client)
@ -91,7 +92,7 @@ class Document(Object):
file_name=file_name, file_name=file_name,
mime_type=document.mime_type, mime_type=document.mime_type,
file_size=document.size, file_size=document.size,
date=document.date, date=utils.timestamp_to_datetime(document.date),
thumbs=types.Thumbnail._parse(client, document), thumbs=types.Thumbnail._parse(client, document),
client=client client=client
) )

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
from datetime import datetime
from functools import partial from functools import partial
from typing import List, Match, Union, BinaryIO, Optional from typing import List, Match, Union, BinaryIO, Optional
@ -71,8 +72,8 @@ class Message(Object, Update):
The supergroup itself for messages from anonymous group administrators. The supergroup itself for messages from anonymous group administrators.
The linked channel for messages automatically forwarded to the discussion group. The linked channel for messages automatically forwarded to the discussion group.
date (``int``, *optional*): date (:py:obj:`~datetime.datetime`, *optional*):
Date the message was sent in Unix time. Date the message was sent.
chat (:obj:`~pyrogram.types.Chat`, *optional*): chat (:obj:`~pyrogram.types.Chat`, *optional*):
Conversation the message belongs to. Conversation the message belongs to.
@ -92,8 +93,8 @@ class Message(Object, Update):
forward_signature (``str``, *optional*): forward_signature (``str``, *optional*):
For messages forwarded from channels, signature of the post author if present. For messages forwarded from channels, signature of the post author if present.
forward_date (``int``, *optional*): forward_date (:py:obj:`~datetime.datetime`, *optional*):
For forwarded messages, date the original message was sent in Unix time. For forwarded messages, date the original message was sent.
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
The id of the message which this message directly replied to. The id of the message which this message directly replied to.
@ -122,8 +123,8 @@ class Message(Object, Update):
This field will contain the enumeration type of the media message. This field will contain the enumeration type of the media message.
You can use ``media = getattr(message, message.media.value)`` to access the media message. You can use ``media = getattr(message, message.media.value)`` to access the media message.
edit_date (``int``, *optional*): edit_date (:py:obj:`~datetime.datetime`, *optional*):
Date the message was last edited in Unix time. Date the message was last edited.
media_group_id (``str``, *optional*): media_group_id (``str``, *optional*):
The unique identifier of a media message group this message belongs to. The unique identifier of a media message group this message belongs to.
@ -304,14 +305,14 @@ class Message(Object, Update):
message_id: int, message_id: int,
from_user: "types.User" = None, from_user: "types.User" = None,
sender_chat: "types.Chat" = None, sender_chat: "types.Chat" = None,
date: int = None, date: datetime = None,
chat: "types.Chat" = None, chat: "types.Chat" = None,
forward_from: "types.User" = None, forward_from: "types.User" = None,
forward_sender_name: str = None, forward_sender_name: str = None,
forward_from_chat: "types.Chat" = None, forward_from_chat: "types.Chat" = None,
forward_from_message_id: int = None, forward_from_message_id: int = None,
forward_signature: str = None, forward_signature: str = None,
forward_date: int = None, forward_date: datetime = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_to_top_message_id: int = None, reply_to_top_message_id: int = None,
reply_to_message: "Message" = None, reply_to_message: "Message" = None,
@ -321,7 +322,7 @@ class Message(Object, Update):
scheduled: bool = None, scheduled: bool = None,
from_scheduled: bool = None, from_scheduled: bool = None,
media: str = None, media: str = None,
edit_date: int = None, edit_date: datetime = None,
media_group_id: str = None, media_group_id: str = None,
author_signature: str = None, author_signature: str = None,
has_protected_content: bool = None, has_protected_content: bool = None,
@ -542,7 +543,7 @@ class Message(Object, Update):
parsed_message = Message( parsed_message = Message(
message_id=message.id, message_id=message.id,
date=message.date, date=utils.timestamp_to_datetime(message.date),
chat=types.Chat._parse(client, message, users, chats, is_chat=True), chat=types.Chat._parse(client, message, users, chats, is_chat=True),
from_user=from_user, from_user=from_user,
sender_chat=sender_chat, sender_chat=sender_chat,
@ -607,7 +608,7 @@ class Message(Object, Update):
forward_header = message.fwd_from # type: raw.types.MessageFwdHeader forward_header = message.fwd_from # type: raw.types.MessageFwdHeader
if forward_header: if forward_header:
forward_date = forward_header.date forward_date = utils.timestamp_to_datetime(forward_header.date)
if forward_header.from_id: if forward_header.from_id:
raw_peer_id = utils.get_raw_peer_id(forward_header.from_id) raw_peer_id = utils.get_raw_peer_id(forward_header.from_id)
@ -739,7 +740,7 @@ class Message(Object, Update):
parsed_message = Message( parsed_message = Message(
message_id=message.id, message_id=message.id,
date=message.date, date=utils.timestamp_to_datetime(message.date),
chat=types.Chat._parse(client, message, users, chats, is_chat=True), chat=types.Chat._parse(client, message, users, chats, is_chat=True),
from_user=from_user, from_user=from_user,
sender_chat=sender_chat, sender_chat=sender_chat,
@ -775,7 +776,7 @@ class Message(Object, Update):
scheduled=is_scheduled, scheduled=is_scheduled,
from_scheduled=message.from_scheduled, from_scheduled=message.from_scheduled,
media=media_type, media=media_type,
edit_date=message.edit_date, edit_date=utils.timestamp_to_datetime(message.edit_date),
media_group_id=message.grouped_id, media_group_id=message.grouped_id,
photo=photo, photo=photo,
location=location, location=location,
@ -864,7 +865,7 @@ class Message(Object, Update):
disable_web_page_preview: bool = None, disable_web_page_preview: bool = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup = None reply_markup = None
) -> "Message": ) -> "Message":
@ -913,8 +914,8 @@ class Message(Object, Update):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.
@ -1449,7 +1450,7 @@ class Message(Object, Update):
force_document: bool = None, force_document: bool = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
"types.ReplyKeyboardMarkup", "types.ReplyKeyboardMarkup",
@ -1519,8 +1520,8 @@ class Message(Object, Update):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.ForceReply`, *optional*): reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
@ -1982,7 +1983,7 @@ class Message(Object, Update):
correct_option_id: int = None, correct_option_id: int = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
"types.ReplyKeyboardMarkup", "types.ReplyKeyboardMarkup",
@ -2042,8 +2043,8 @@ class Message(Object, Update):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.ForceReply`, *optional*): reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
@ -2859,7 +2860,7 @@ class Message(Object, Update):
self, self,
chat_id: Union[int, str], chat_id: Union[int, str],
disable_notification: bool = None, disable_notification: bool = None,
schedule_date: int = None schedule_date: datetime = None
) -> Union["types.Message", List["types.Message"]]: ) -> Union["types.Message", List["types.Message"]]:
"""Bound method *forward* of :obj:`~pyrogram.types.Message`. """Bound method *forward* of :obj:`~pyrogram.types.Message`.
@ -2888,8 +2889,8 @@ class Message(Object, Update):
Sends the message silently. Sends the message silently.
Users will receive a notification with no sound. Users will receive a notification with no sound.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
Returns: Returns:
On success, the forwarded Message is returned. On success, the forwarded Message is returned.
@ -2913,7 +2914,7 @@ class Message(Object, Update):
caption_entities: List["types.MessageEntity"] = None, caption_entities: List["types.MessageEntity"] = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: datetime = None,
protect_content: bool = None, protect_content: bool = None,
reply_markup: Union[ reply_markup: Union[
"types.InlineKeyboardMarkup", "types.InlineKeyboardMarkup",
@ -2964,8 +2965,8 @@ class Message(Object, Update):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*): schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent. Unix time. Date when the message will be automatically sent.
protect_content (``bool``, *optional*): protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving. Protects the contents of the sent message from forwarding and saving.

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import List from typing import List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType, ThumbnailSource from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType, ThumbnailSource
from ..object import Object from ..object import Object
@ -45,8 +46,8 @@ class Photo(Object):
file_size (``int``): file_size (``int``):
File size. File size.
date (``int``): date (:py:obj:`~datetime.datetime`):
Date the photo was sent in Unix time. Date the photo was sent.
ttl_seconds (``int``, *optional*): ttl_seconds (``int``, *optional*):
Time-to-live seconds, for secret photos. Time-to-live seconds, for secret photos.
@ -64,7 +65,7 @@ class Photo(Object):
width: int, width: int,
height: int, height: int,
file_size: int, file_size: int,
date: int, date: datetime,
ttl_seconds: int = None, ttl_seconds: int = None,
thumbs: List["types.Thumbnail"] = None thumbs: List["types.Thumbnail"] = None
): ):
@ -122,7 +123,7 @@ class Photo(Object):
width=main.w, width=main.w,
height=main.h, height=main.h,
file_size=main.size, file_size=main.size,
date=photo.date, date=utils.timestamp_to_datetime(photo.date),
ttl_seconds=ttl_seconds, ttl_seconds=ttl_seconds,
thumbs=types.Thumbnail._parse(client, photo), thumbs=types.Thumbnail._parse(client, photo),
client=client client=client

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import List from typing import List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.errors import StickersetInvalid from pyrogram.errors import StickersetInvalid
from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
@ -58,8 +59,8 @@ class Sticker(Object):
file_size (``int``, *optional*): file_size (``int``, *optional*):
File size. File size.
date (``int``, *optional*): date (:py:obj:`~datetime.datetime`, *optional*):
Date the sticker was sent in Unix time. Date the sticker was sent.
emoji (``str``, *optional*): emoji (``str``, *optional*):
Emoji associated with the sticker. Emoji associated with the sticker.
@ -86,7 +87,7 @@ class Sticker(Object):
file_name: str = None, file_name: str = None,
mime_type: str = None, mime_type: str = None,
file_size: int = None, file_size: int = None,
date: int = None, date: datetime = None,
emoji: str = None, emoji: str = None,
set_name: str = None, set_name: str = None,
thumbs: List["types.Thumbnail"] = None thumbs: List["types.Thumbnail"] = None
@ -179,7 +180,7 @@ class Sticker(Object):
file_size=sticker.size, file_size=sticker.size,
mime_type=sticker.mime_type, mime_type=sticker.mime_type,
file_name=file_name, file_name=file_name,
date=sticker.date, date=utils.timestamp_to_datetime(sticker.date),
thumbs=types.Thumbnail._parse(client, sticker), thumbs=types.Thumbnail._parse(client, sticker),
client=client client=client
) )

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import List from typing import List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object from ..object import Object
@ -60,8 +61,8 @@ class Video(Object):
ttl_seconds (``int``. *optional*): ttl_seconds (``int``. *optional*):
Time-to-live seconds, for secret photos. Time-to-live seconds, for secret photos.
date (``int``, *optional*): date (:py:obj:`~datetime.datetime`, *optional*):
Date the video was sent in Unix time. Date the video was sent.
thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*): thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*):
Video thumbnails. Video thumbnails.
@ -81,7 +82,7 @@ class Video(Object):
file_size: int = None, file_size: int = None,
supports_streaming: bool = None, supports_streaming: bool = None,
ttl_seconds: int = None, ttl_seconds: int = None,
date: int = None, date: datetime = None,
thumbs: List["types.Thumbnail"] = None thumbs: List["types.Thumbnail"] = None
): ):
super().__init__(client) super().__init__(client)
@ -126,7 +127,7 @@ class Video(Object):
mime_type=video.mime_type, mime_type=video.mime_type,
supports_streaming=video_attributes.supports_streaming, supports_streaming=video_attributes.supports_streaming,
file_size=video.size, file_size=video.size,
date=video.date, date=utils.timestamp_to_datetime(video.date),
ttl_seconds=ttl_seconds, ttl_seconds=ttl_seconds,
thumbs=types.Thumbnail._parse(client, video), thumbs=types.Thumbnail._parse(client, video),
client=client client=client

View File

@ -19,10 +19,11 @@
from typing import List from typing import List
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object from ..object import Object
from datetime import datetime
class VideoNote(Object): class VideoNote(Object):
@ -48,8 +49,8 @@ class VideoNote(Object):
file_size (``int``, *optional*): file_size (``int``, *optional*):
File size. File size.
date (``int``, *optional*): date (:py:obj:`~datetime.datetime`, *optional*):
Date the video note was sent in Unix time. Date the video note was sent.
thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*): thumbs (List of :obj:`~pyrogram.types.Thumbnail`, *optional*):
Video thumbnails. Video thumbnails.
@ -66,7 +67,7 @@ class VideoNote(Object):
thumbs: List["types.Thumbnail"] = None, thumbs: List["types.Thumbnail"] = None,
mime_type: str = None, mime_type: str = None,
file_size: int = None, file_size: int = None,
date: int = None date: datetime = None
): ):
super().__init__(client) super().__init__(client)
@ -101,7 +102,7 @@ class VideoNote(Object):
duration=video_attributes.duration, duration=video_attributes.duration,
file_size=video_note.size, file_size=video_note.size,
mime_type=video_note.mime_type, mime_type=video_note.mime_type,
date=video_note.date, date=utils.timestamp_to_datetime(video_note.date),
thumbs=types.Thumbnail._parse(client, video_note), thumbs=types.Thumbnail._parse(client, video_note),
client=client client=client
) )

View File

@ -16,8 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType from pyrogram.file_id import FileId, FileType, FileUniqueId, FileUniqueType
from ..object import Object from ..object import Object
@ -45,8 +47,8 @@ class Voice(Object):
file_size (``int``, *optional*): file_size (``int``, *optional*):
File size. File size.
date (``int``, *optional*): date (:py:obj:`~datetime.datetime`, *optional*):
Date the voice was sent in Unix time. Date the voice was sent.
""" """
def __init__( def __init__(
@ -59,7 +61,7 @@ class Voice(Object):
waveform: bytes = None, waveform: bytes = None,
mime_type: str = None, mime_type: str = None,
file_size: int = None, file_size: int = None,
date: int = None date: datetime = None
): ):
super().__init__(client) super().__init__(client)
@ -89,6 +91,6 @@ class Voice(Object):
mime_type=voice.mime_type, mime_type=voice.mime_type,
file_size=voice.size, file_size=voice.size,
waveform=attributes.waveform, waveform=attributes.waveform,
date=voice.date, date=utils.timestamp_to_datetime(voice.date),
client=client client=client
) )

View File

@ -56,14 +56,14 @@ class Object(metaclass=Meta):
if isinstance(obj, Enum): if isinstance(obj, Enum):
return str(obj) return str(obj)
if isinstance(obj, datetime):
return str(obj)
return { return {
"_": obj.__class__.__name__, "_": obj.__class__.__name__,
**{ **{
attr: ( attr: (
"*" * 9 "*" * 9 if attr == "phone_number" else
if attr == "phone_number" else
str(datetime.fromtimestamp(getattr(obj, attr)))
if attr.endswith("date") else
getattr(obj, attr) getattr(obj, attr)
) )
for attr in filter(lambda x: not x.startswith("_"), obj.__dict__) for attr in filter(lambda x: not x.startswith("_"), obj.__dict__)

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union, List, Generator, Optional from typing import Union, List, Generator, Optional
import pyrogram import pyrogram
@ -513,7 +514,7 @@ class Chat(Object):
async def ban_member( async def ban_member(
self, self,
user_id: Union[int, str], user_id: Union[int, str],
until_date: int = 0 until_date: datetime = datetime.fromtimestamp(0)
) -> Union["types.Message", bool]: ) -> Union["types.Message", bool]:
"""Bound method *ban_member* of :obj:`~pyrogram.types.Chat`. """Bound method *ban_member* of :obj:`~pyrogram.types.Chat`.
@ -541,10 +542,10 @@ class Chat(Object):
Unique identifier (int) or username (str) of the target user. Unique identifier (int) or username (str) of the target user.
For a contact that exists in your Telegram address book you can use his phone number (str). For a contact that exists in your Telegram address book you can use his phone number (str).
until_date (``int``, *optional*): until_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the user will be unbanned, unix time. Date when the user will be unbanned.
If user is banned for more than 366 days or less than 30 seconds from the current time they are If user is banned for more than 366 days or less than 30 seconds from the current time they are
considered to be banned forever. Defaults to 0 (ban forever). considered to be banned forever. Defaults to epoch (ban forever).
Returns: Returns:
:obj:`~pyrogram.types.Message` | ``bool``: On success, a service message will be returned (when applicable), otherwise, in :obj:`~pyrogram.types.Message` | ``bool``: On success, a service message will be returned (when applicable), otherwise, in
@ -601,7 +602,7 @@ class Chat(Object):
self, self,
user_id: Union[int, str], user_id: Union[int, str],
permissions: "types.ChatPermissions", permissions: "types.ChatPermissions",
until_date: int = 0, until_date: datetime = datetime.fromtimestamp(0),
) -> "types.Chat": ) -> "types.Chat":
"""Bound method *unban_member* of :obj:`~pyrogram.types.Chat`. """Bound method *unban_member* of :obj:`~pyrogram.types.Chat`.
@ -628,10 +629,10 @@ class Chat(Object):
permissions (:obj:`~pyrogram.types.ChatPermissions`): permissions (:obj:`~pyrogram.types.ChatPermissions`):
New user permissions. New user permissions.
until_date (``int``, *optional*): until_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the user will be unbanned, unix time. Date when the user will be unbanned.
If user is banned for more than 366 days or less than 30 seconds from the current time they are If user is banned for more than 366 days or less than 30 seconds from the current time they are
considered to be banned forever. Defaults to 0 (ban forever). considered to be banned forever. Defaults to epoch (ban forever).
Returns: Returns:
:obj:`~pyrogram.types.Chat`: On success, a chat object is returned. :obj:`~pyrogram.types.Chat`: On success, a chat object is returned.

View File

@ -16,57 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from enum import Enum, auto from datetime import datetime
from typing import List, Optional from typing import List, Optional
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw
from pyrogram import types from pyrogram import types, utils, enums
from ..object import Object from ..object import Object
class AutoName(Enum):
def _generate_next_value_(self, *args):
return self.lower()
class ChatEventAction(AutoName):
DESCRIPTION_CHANGED = auto()
HISTORY_TTL_CHANGED = auto()
LINKED_CHAT_CHANGED = auto()
# LOCATION_CHANGED = auto()
PHOTO_CHANGED = auto()
# STICKER_SET_CHANGED = auto()
TITLE_CHANGED = auto()
USERNAME_CHANGED = auto()
CHAT_PERMISSIONS_CHANGED = auto()
MESSAGE_DELETED = auto()
# VOICE_CHAT_DISCARDED = auto()
MESSAGE_EDITED = auto()
INVITE_LINK_EDITED = auto()
INVITE_LINK_REVOKED = auto()
INVITE_LINK_DELETED = auto()
MEMBER_INVITED = auto()
MEMBER_JOINED = auto()
# MEMBER_JOINED_BY_LINK = auto()
MEMBER_LEFT = auto()
# MEMBER_MUTED = auto()
ADMIN_RIGHTS_CHANGED = auto()
MEMBER_PERMISSIONS_CHANGED = auto()
# MEMBER_UNMUTED = auto()
# MEMBER_VOLUME_CHANGED = auto()
# VOICE_CHAT_STARTED = auto()
POLL_STOPPED = auto()
# VOICE_CHAT_SETTINGS_CHANGED = auto()
INVITES_ENABLED = auto()
HISTORY_HIDDEN = auto()
SIGNATURES_ENABLED = auto()
SLOW_MODE_CHANGED = auto()
MESSAGE_PINNED = auto()
MESSAGE_UNPINNED = auto()
UNKNOWN = auto()
class ChatEvent(Object): class ChatEvent(Object):
"""A chat event from the recent actions log (also known as admin log). """A chat event from the recent actions log (also known as admin log).
@ -76,8 +34,8 @@ class ChatEvent(Object):
id (``int``): id (``int``):
Chat event identifier. Chat event identifier.
date (``int``): date (:py:obj:`~datetime.datetime`):
Date of the event. Unix time. Date of the event.
action (:obj:`~pyrogram.enums.ChatEventAction`): action (:obj:`~pyrogram.enums.ChatEventAction`):
Event action. Event action.
@ -177,7 +135,7 @@ class ChatEvent(Object):
def __init__( def __init__(
self, *, self, *,
id: int, id: int,
date: int, date: datetime,
user: "types.User", user: "types.User",
action: str, action: str,
@ -232,7 +190,7 @@ class ChatEvent(Object):
old_invite_link: "types.ChatInviteLink" = None, old_invite_link: "types.ChatInviteLink" = None,
new_invite_link: "types.ChatInviteLink" = None, new_invite_link: "types.ChatInviteLink" = None,
revoked_invite_link: "types.ChatInviteLink" = None, revoked_invite_link: "types.ChatInviteLink" = None,
deleted_invite_link: "types.ChatInviteLink" = None, deleted_invite_link: "types.ChatInviteLink" = None
): ):
super().__init__() super().__init__()
@ -363,117 +321,117 @@ class ChatEvent(Object):
if isinstance(action, raw.types.ChannelAdminLogEventActionChangeAbout): if isinstance(action, raw.types.ChannelAdminLogEventActionChangeAbout):
old_description = action.prev_value old_description = action.prev_value
new_description = action.new_value new_description = action.new_value
action = ChatEventAction.DESCRIPTION_CHANGED action = enums.ChatEventAction.DESCRIPTION_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionChangeHistoryTTL): elif isinstance(action, raw.types.ChannelAdminLogEventActionChangeHistoryTTL):
old_history_ttl = action.prev_value old_history_ttl = action.prev_value
new_history_ttl = action.new_value new_history_ttl = action.new_value
action = ChatEventAction.HISTORY_TTL_CHANGED action = enums.ChatEventAction.HISTORY_TTL_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionChangeLinkedChat): elif isinstance(action, raw.types.ChannelAdminLogEventActionChangeLinkedChat):
old_linked_chat = types.Chat._parse_chat(client, chats[action.prev_value]) old_linked_chat = types.Chat._parse_chat(client, chats[action.prev_value])
new_linked_chat = types.Chat._parse_chat(client, chats[action.new_value]) new_linked_chat = types.Chat._parse_chat(client, chats[action.new_value])
action = ChatEventAction.LINKED_CHAT_CHANGED action = enums.ChatEventAction.LINKED_CHAT_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionChangePhoto): elif isinstance(action, raw.types.ChannelAdminLogEventActionChangePhoto):
old_photo = types.Photo._parse(client, action.prev_photo) old_photo = types.Photo._parse(client, action.prev_photo)
new_photo = types.Photo._parse(client, action.new_photo) new_photo = types.Photo._parse(client, action.new_photo)
action = ChatEventAction.PHOTO_CHANGED action = enums.ChatEventAction.PHOTO_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionChangeTitle): elif isinstance(action, raw.types.ChannelAdminLogEventActionChangeTitle):
old_title = action.prev_value old_title = action.prev_value
new_title = action.new_value new_title = action.new_value
action = ChatEventAction.TITLE_CHANGED action = enums.ChatEventAction.TITLE_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionChangeUsername): elif isinstance(action, raw.types.ChannelAdminLogEventActionChangeUsername):
old_username = action.prev_value old_username = action.prev_value
new_username = action.new_value new_username = action.new_value
action = ChatEventAction.USERNAME_CHANGED action = enums.ChatEventAction.USERNAME_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionDefaultBannedRights): elif isinstance(action, raw.types.ChannelAdminLogEventActionDefaultBannedRights):
old_chat_permissions = types.ChatPermissions._parse(action.prev_banned_rights) old_chat_permissions = types.ChatPermissions._parse(action.prev_banned_rights)
new_chat_permissions = types.ChatPermissions._parse(action.new_banned_rights) new_chat_permissions = types.ChatPermissions._parse(action.new_banned_rights)
action = ChatEventAction.CHAT_PERMISSIONS_CHANGED action = enums.ChatEventAction.CHAT_PERMISSIONS_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionDeleteMessage): elif isinstance(action, raw.types.ChannelAdminLogEventActionDeleteMessage):
deleted_message = await types.Message._parse(client, action.message, users, chats) deleted_message = await types.Message._parse(client, action.message, users, chats)
action = ChatEventAction.MESSAGE_DELETED action = enums.ChatEventAction.MESSAGE_DELETED
elif isinstance(action, raw.types.ChannelAdminLogEventActionEditMessage): elif isinstance(action, raw.types.ChannelAdminLogEventActionEditMessage):
old_message = await types.Message._parse(client, action.prev_message, users, chats) old_message = await types.Message._parse(client, action.prev_message, users, chats)
new_message = await types.Message._parse(client, action.new_message, users, chats) new_message = await types.Message._parse(client, action.new_message, users, chats)
action = ChatEventAction.MESSAGE_EDITED action = enums.ChatEventAction.MESSAGE_EDITED
elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantInvite): elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantInvite):
invited_member = types.ChatMember._parse(client, action.participant, users, chats) invited_member = types.ChatMember._parse(client, action.participant, users, chats)
action = ChatEventAction.MEMBER_INVITED action = enums.ChatEventAction.MEMBER_INVITED
elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantToggleAdmin): elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantToggleAdmin):
old_administrator_privileges = types.ChatMember._parse(client, action.prev_participant, users, chats) old_administrator_privileges = types.ChatMember._parse(client, action.prev_participant, users, chats)
new_administrator_privileges = types.ChatMember._parse(client, action.new_participant, users, chats) new_administrator_privileges = types.ChatMember._parse(client, action.new_participant, users, chats)
action = ChatEventAction.ADMIN_RIGHTS_CHANGED action = enums.ChatEventAction.ADMIN_RIGHTS_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantToggleBan): elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantToggleBan):
old_member_permissions = types.ChatMember._parse(client, action.prev_participant, users, chats) old_member_permissions = types.ChatMember._parse(client, action.prev_participant, users, chats)
new_member_permissions = types.ChatMember._parse(client, action.new_participant, users, chats) new_member_permissions = types.ChatMember._parse(client, action.new_participant, users, chats)
action = ChatEventAction.MEMBER_PERMISSIONS_CHANGED action = enums.ChatEventAction.MEMBER_PERMISSIONS_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionStopPoll): elif isinstance(action, raw.types.ChannelAdminLogEventActionStopPoll):
stopped_poll = await types.Message._parse(client, action.message, users, chats) stopped_poll = await types.Message._parse(client, action.message, users, chats)
action = ChatEventAction.POLL_STOPPED action = enums.ChatEventAction.POLL_STOPPED
elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantJoin): elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantJoin):
action = ChatEventAction.MEMBER_JOINED action = enums.ChatEventAction.MEMBER_JOINED
elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantLeave): elif isinstance(action, raw.types.ChannelAdminLogEventActionParticipantLeave):
action = ChatEventAction.MEMBER_LEFT action = enums.ChatEventAction.MEMBER_LEFT
elif isinstance(action, raw.types.ChannelAdminLogEventActionToggleInvites): elif isinstance(action, raw.types.ChannelAdminLogEventActionToggleInvites):
invites_enabled = action.new_value invites_enabled = action.new_value
action = ChatEventAction.INVITES_ENABLED action = enums.ChatEventAction.INVITES_ENABLED
elif isinstance(action, raw.types.ChannelAdminLogEventActionTogglePreHistoryHidden): elif isinstance(action, raw.types.ChannelAdminLogEventActionTogglePreHistoryHidden):
history_hidden = action.new_value history_hidden = action.new_value
action = ChatEventAction.HISTORY_HIDDEN action = enums.ChatEventAction.HISTORY_HIDDEN
elif isinstance(action, raw.types.ChannelAdminLogEventActionToggleSignatures): elif isinstance(action, raw.types.ChannelAdminLogEventActionToggleSignatures):
signatures_enabled = action.new_value signatures_enabled = action.new_value
action = ChatEventAction.SIGNATURES_ENABLED action = enums.ChatEventAction.SIGNATURES_ENABLED
elif isinstance(action, raw.types.ChannelAdminLogEventActionToggleSlowMode): elif isinstance(action, raw.types.ChannelAdminLogEventActionToggleSlowMode):
old_slow_mode = action.prev_value old_slow_mode = action.prev_value
new_slow_mode = action.new_value new_slow_mode = action.new_value
action = ChatEventAction.SLOW_MODE_CHANGED action = enums.ChatEventAction.SLOW_MODE_CHANGED
elif isinstance(action, raw.types.ChannelAdminLogEventActionUpdatePinned): elif isinstance(action, raw.types.ChannelAdminLogEventActionUpdatePinned):
message = action.message message = action.message
if message.pinned: if message.pinned:
pinned_message = await types.Message._parse(client, message, users, chats) pinned_message = await types.Message._parse(client, message, users, chats)
action = ChatEventAction.MESSAGE_PINNED action = enums.ChatEventAction.MESSAGE_PINNED
else: else:
unpinned_message = await types.Message._parse(client, message, users, chats) unpinned_message = await types.Message._parse(client, message, users, chats)
action = ChatEventAction.MESSAGE_UNPINNED action = enums.ChatEventAction.MESSAGE_UNPINNED
elif isinstance(action, raw.types.ChannelAdminLogEventActionExportedInviteEdit): elif isinstance(action, raw.types.ChannelAdminLogEventActionExportedInviteEdit):
old_invite_link = types.ChatInviteLink._parse(client, action.prev_invite, users) old_invite_link = types.ChatInviteLink._parse(client, action.prev_invite, users)
new_invite_link = types.ChatInviteLink._parse(client, action.new_invite, users) new_invite_link = types.ChatInviteLink._parse(client, action.new_invite, users)
action = ChatEventAction.INVITE_LINK_EDITED action = enums.ChatEventAction.INVITE_LINK_EDITED
elif isinstance(action, raw.types.ChannelAdminLogEventActionExportedInviteRevoke): elif isinstance(action, raw.types.ChannelAdminLogEventActionExportedInviteRevoke):
revoked_invite_link = types.ChatInviteLink._parse(client, action.invite, users) revoked_invite_link = types.ChatInviteLink._parse(client, action.invite, users)
action = ChatEventAction.INVITE_LINK_REVOKED action = enums.ChatEventAction.INVITE_LINK_REVOKED
elif isinstance(action, raw.types.ChannelAdminLogEventActionExportedInviteDelete): elif isinstance(action, raw.types.ChannelAdminLogEventActionExportedInviteDelete):
deleted_invite_link = types.ChatInviteLink._parse(client, action.invite, users) deleted_invite_link = types.ChatInviteLink._parse(client, action.invite, users)
action = ChatEventAction.INVITE_LINK_DELETED action = enums.ChatEventAction.INVITE_LINK_DELETED
else: else:
action = f"{ChatEventAction.UNKNOWN}-{action.QUALNAME}" action = f"{enums.ChatEventAction.UNKNOWN}-{action.QUALNAME}"
return ChatEvent( return ChatEvent(
id=event.id, id=event.id,
date=event.date, date=utils.timestamp_to_datetime(event.date),
user=user, user=user,
action=action, action=action,
old_description=old_description, old_description=old_description,

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Dict from typing import Dict
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from ..object import Object from ..object import Object
@ -32,8 +33,8 @@ class ChatInviteLink(Object):
The invite link. If the link was created by another chat administrator, then the second part of the The invite link. If the link was created by another chat administrator, then the second part of the
link will be replaced with "...". link will be replaced with "...".
date (``int``): date (:py:obj:`~datetime.datetime`):
The date in Unix timestamp when the link was created. The date when the link was created.
is_primary (``bool``): is_primary (``bool``):
True, if the link is primary. True, if the link is primary.
@ -50,8 +51,11 @@ class ChatInviteLink(Object):
creates_join_request (``bool``, *optional*): creates_join_request (``bool``, *optional*):
True, if users joining the chat via the link need to be approved by chat administrators. True, if users joining the chat via the link need to be approved by chat administrators.
expire_date (``int``, *optional*): start_date (:py:obj:`~datetime.datetime`, *optional*):
Point in time (Unix timestamp) when the link will expire or has been expired. Point in time when the link has been edited.
expire_date (:py:obj:`~datetime.datetime`, *optional*):
Point in time when the link will expire or has been expired.
member_limit (``int``, *optional*): member_limit (``int``, *optional*):
Maximum number of users that can be members of the chat simultaneously after joining the chat via this Maximum number of users that can be members of the chat simultaneously after joining the chat via this
@ -67,14 +71,14 @@ class ChatInviteLink(Object):
def __init__( def __init__(
self, *, self, *,
invite_link: str, invite_link: str,
date: int, date: datetime,
is_primary: bool = None, is_primary: bool = None,
is_revoked: bool = None, is_revoked: bool = None,
creator: "types.User" = None, creator: "types.User" = None,
name: str = None, name: str = None,
creates_join_request: bool = None, creates_join_request: bool = None,
start_date: int = None, start_date: datetime = None,
expire_date: int = None, expire_date: datetime = None,
member_limit: int = None, member_limit: int = None,
member_count: int = None, member_count: int = None,
pending_join_request_count: int = None pending_join_request_count: int = None
@ -108,13 +112,14 @@ class ChatInviteLink(Object):
return ChatInviteLink( return ChatInviteLink(
invite_link=invite.link, invite_link=invite.link,
date=invite.date, date=utils.timestamp_to_datetime(invite.date),
is_primary=invite.permanent, is_primary=invite.permanent,
is_revoked=invite.revoked, is_revoked=invite.revoked,
creator=creator, creator=creator,
name=invite.title, name=invite.title,
creates_join_request=invite.request_needed, creates_join_request=invite.request_needed,
expire_date=invite.expire_date, start_date=utils.timestamp_to_datetime(invite.start_date),
expire_date=utils.timestamp_to_datetime(invite.expire_date),
member_limit=invite.usage_limit, member_limit=invite.usage_limit,
member_count=invite.usage, member_count=invite.usage,
pending_join_request_count=invite.requested pending_join_request_count=invite.requested

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Dict from typing import Dict
import pyrogram import pyrogram
@ -35,8 +36,8 @@ class ChatJoinRequest(Object, Update):
from_user (:obj:`~pyrogram.types.User`): from_user (:obj:`~pyrogram.types.User`):
User that sent the join request. User that sent the join request.
date (``int``): date (:py:obj:`~datetime.datetime`):
Date the request was sent in Unix time Date the request was sent.
bio (``str``, *optional*): bio (``str``, *optional*):
Bio of the user. Bio of the user.
@ -51,7 +52,7 @@ class ChatJoinRequest(Object, Update):
client: "pyrogram.Client" = None, client: "pyrogram.Client" = None,
chat: "types.Chat", chat: "types.Chat",
from_user: "types.User", from_user: "types.User",
date: int, date: datetime,
bio: str = None, bio: str = None,
invite_link: "types.ChatInviteLink" = None invite_link: "types.ChatInviteLink" = None
): ):
@ -75,7 +76,7 @@ class ChatJoinRequest(Object, Update):
return ChatJoinRequest( return ChatJoinRequest(
chat=types.Chat._parse_chat(client, chats[chat_id]), chat=types.Chat._parse_chat(client, chats[chat_id]),
from_user=types.User._parse(client, users[update.user_id]), from_user=types.User._parse(client, users[update.user_id]),
date=update.date, date=utils.timestamp_to_datetime(update.date),
bio=update.about, bio=update.about,
invite_link=types.ChatInviteLink._parse(client, update.invite, users), invite_link=types.ChatInviteLink._parse(client, update.invite, users),
client=client client=client

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union, Dict from typing import Union, Dict
import pyrogram import pyrogram
@ -36,17 +37,17 @@ class ChatMember(Object):
chat (:obj:`~pyrogram.types.Chat`, *optional*): chat (:obj:`~pyrogram.types.Chat`, *optional*):
Information about the chat (useful in case of banned channel senders). Information about the chat (useful in case of banned channel senders).
joined_date (``int``, *optional*): joined_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the user joined, unix time. Date when the user joined..
Not available for the owner. Not available for the owner.
custom_title (``str``, *optional*): custom_title (``str``, *optional*):
A custom title that will be shown to all members instead of "Owner" or "Admin". A custom title that will be shown to all members instead of "Owner" or "Admin".
Creator (owner) and administrators only. Can be None in case there's no custom title set. Creator (owner) and administrators only. Can be None in case there's no custom title set.
until_date (``int``, *optional*): until_date (:py:obj:`~datetime.datetime`, *optional*):
Restricted and banned only. Restricted and banned only.
Date when restrictions will be lifted for this user; unix time. Date when restrictions will be lifted for this user.
invited_by (:obj:`~pyrogram.types.User`, *optional*): invited_by (:obj:`~pyrogram.types.User`, *optional*):
Administrators and self member only. Information about the user who invited this member. Administrators and self member only. Information about the user who invited this member.
@ -79,8 +80,8 @@ class ChatMember(Object):
user: "types.User" = None, user: "types.User" = None,
chat: "types.Chat" = None, chat: "types.Chat" = None,
custom_title: str = None, custom_title: str = None,
until_date: int = None, until_date: datetime = None,
joined_date: int = None, joined_date: datetime = None,
invited_by: "types.User" = None, invited_by: "types.User" = None,
promoted_by: "types.User" = None, promoted_by: "types.User" = None,
restricted_by: "types.User" = None, restricted_by: "types.User" = None,
@ -117,7 +118,7 @@ class ChatMember(Object):
return ChatMember( return ChatMember(
status=enums.ChatMemberStatus.MEMBER, status=enums.ChatMemberStatus.MEMBER,
user=types.User._parse(client, users[member.user_id]), user=types.User._parse(client, users[member.user_id]),
joined_date=member.date, joined_date=utils.timestamp_to_datetime(member.date),
invited_by=types.User._parse(client, users[member.inviter_id]), invited_by=types.User._parse(client, users[member.inviter_id]),
client=client client=client
) )
@ -125,7 +126,7 @@ class ChatMember(Object):
return ChatMember( return ChatMember(
status=enums.ChatMemberStatus.ADMINISTRATOR, status=enums.ChatMemberStatus.ADMINISTRATOR,
user=types.User._parse(client, users[member.user_id]), user=types.User._parse(client, users[member.user_id]),
joined_date=member.date, joined_date=utils.timestamp_to_datetime(member.date),
invited_by=types.User._parse(client, users[member.inviter_id]), invited_by=types.User._parse(client, users[member.inviter_id]),
client=client client=client
) )
@ -141,14 +142,14 @@ class ChatMember(Object):
return ChatMember( return ChatMember(
status=enums.ChatMemberStatus.MEMBER, status=enums.ChatMemberStatus.MEMBER,
user=types.User._parse(client, users[member.user_id]), user=types.User._parse(client, users[member.user_id]),
joined_date=member.date, joined_date=utils.timestamp_to_datetime(member.date),
client=client client=client
) )
elif isinstance(member, raw.types.ChannelParticipantAdmin): elif isinstance(member, raw.types.ChannelParticipantAdmin):
return ChatMember( return ChatMember(
status=enums.ChatMemberStatus.ADMINISTRATOR, status=enums.ChatMemberStatus.ADMINISTRATOR,
user=types.User._parse(client, users[member.user_id]), user=types.User._parse(client, users[member.user_id]),
joined_date=member.date, joined_date=utils.timestamp_to_datetime(member.date),
promoted_by=types.User._parse(client, users[member.promoted_by]), promoted_by=types.User._parse(client, users[member.promoted_by]),
invited_by=types.User._parse(client, users[member.inviter_id]), invited_by=types.User._parse(client, users[member.inviter_id]),
custom_title=member.rank, custom_title=member.rank,
@ -178,8 +179,8 @@ class ChatMember(Object):
), ),
user=user, user=user,
chat=chat, chat=chat,
until_date=member.banned_rights.until_date, until_date=utils.timestamp_to_datetime(member.banned_rights.until_date),
joined_date=member.date, joined_date=utils.timestamp_to_datetime(member.date),
is_member=not member.left, is_member=not member.left,
restricted_by=types.User._parse(client, users[member.kicked_by]), restricted_by=types.User._parse(client, users[member.kicked_by]),
permissions=types.ChatPermissions._parse(member.banned_rights), permissions=types.ChatPermissions._parse(member.banned_rights),
@ -217,7 +218,7 @@ class ChatMember(Object):
return ChatMember( return ChatMember(
status=enums.ChatMemberStatus.MEMBER, status=enums.ChatMemberStatus.MEMBER,
user=types.User._parse(client, users[member.user_id]), user=types.User._parse(client, users[member.user_id]),
joined_date=member.date, joined_date=utils.timestamp_to_datetime(member.date),
invited_by=types.User._parse(client, users[member.inviter_id]), invited_by=types.User._parse(client, users[member.inviter_id]),
client=client client=client
) )

View File

@ -16,10 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Dict, Union from typing import Dict, Union
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from ..object import Object from ..object import Object
from ..update import Update from ..update import Update
@ -35,8 +36,8 @@ class ChatMemberUpdated(Object, Update):
from_user (:obj:`~pyrogram.types.User`): from_user (:obj:`~pyrogram.types.User`):
Performer of the action, which resulted in the change. Performer of the action, which resulted in the change.
date (``int``): date (:py:obj:`~datetime.datetime`):
Date the change was done in Unix time. Date the change was done.
old_chat_member (:obj:`~pyrogram.types.ChatMember`, *optional*): old_chat_member (:obj:`~pyrogram.types.ChatMember`, *optional*):
Previous information about the chat member. Previous information about the chat member.
@ -54,7 +55,7 @@ class ChatMemberUpdated(Object, Update):
client: "pyrogram.Client" = None, client: "pyrogram.Client" = None,
chat: "types.Chat", chat: "types.Chat",
from_user: "types.User", from_user: "types.User",
date: int, date: datetime,
old_chat_member: "types.ChatMember", old_chat_member: "types.ChatMember",
new_chat_member: "types.ChatMember", new_chat_member: "types.ChatMember",
invite_link: "types.ChatInviteLink" = None, invite_link: "types.ChatInviteLink" = None,
@ -93,7 +94,7 @@ class ChatMemberUpdated(Object, Update):
return ChatMemberUpdated( return ChatMemberUpdated(
chat=types.Chat._parse_chat(client, chats[chat_id]), chat=types.Chat._parse_chat(client, chats[chat_id]),
from_user=types.User._parse(client, users[update.actor_id]), from_user=types.User._parse(client, users[update.actor_id]),
date=update.date, date=utils.timestamp_to_datetime(update.date),
old_chat_member=old_chat_member, old_chat_member=old_chat_member,
new_chat_member=new_chat_member, new_chat_member=new_chat_member,
invite_link=invite_link, invite_link=invite_link,

View File

@ -16,7 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram import raw from datetime import datetime
from pyrogram import raw, utils
from pyrogram import types from pyrogram import types
from ..object import Object from ..object import Object
@ -25,14 +27,18 @@ class InviteLinkImporter(Object):
"""The date and user of when someone has joined with an invite link. """The date and user of when someone has joined with an invite link.
Parameters: Parameters:
date (``int``): date (:py:obj:`~datetime.datetime`):
The unix time of when this user used the given link The time of when this user used the given link
user (:obj:`~pyrogram.types.User`): user (:obj:`~pyrogram.types.User`):
The user that has used the given invite link The user that has used the given invite link
""" """
def __init__(self, *, date, user): def __init__(
self, *,
date: datetime,
user: "types.User"
):
super().__init__(None) super().__init__(None)
self.date = date self.date = date
@ -47,7 +53,7 @@ class InviteLinkImporter(Object):
for j in invite_importers.importers: for j in invite_importers.importers:
importers.append( importers.append(
InviteLinkImporter( InviteLinkImporter(
date=j.date, date=utils.timestamp_to_datetime(j.date),
user=types.User._parse(client=None, user=d[j.user_id]) user=types.User._parse(client=None, user=d[j.user_id])
) )
) )

View File

@ -17,10 +17,11 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import html import html
from datetime import datetime
from typing import List, Optional from typing import List, Optional
import pyrogram import pyrogram
from pyrogram import enums from pyrogram import enums, utils
from pyrogram import raw from pyrogram import raw
from pyrogram import types from pyrogram import types
from ..object import Object from ..object import Object
@ -103,13 +104,13 @@ class User(Object, Update):
User's or bot's last name. User's or bot's last name.
status (:obj:`~pyrogram.enums.UserStatus`, *optional*): status (:obj:`~pyrogram.enums.UserStatus`, *optional*):
User's last seen & online status. *None*, for bots. User's last seen & online status. ``None``, for bots.
last_online_date (``int``, *optional*): last_online_date (:py:obj:`~datetime.datetime`, *optional*):
Last online date of a user, unix time. Only available in case status is "*offline*". Last online date of a user. Only available in case status is :obj:`~pyrogram.enums.UserStatus.OFFLINE`.
next_offline_date (``int``, *optional*): next_offline_date (:py:obj:`~datetime.datetime`, *optional*):
Date when a user will automatically go offline, unix time. Only available in case status is "*online*". Date when a user will automatically go offline. Only available in case status is :obj:`~pyrogram.enums.UserStatus.ONLINE`.
username (``str``, *optional*): username (``str``, *optional*):
User's or bot's username. User's or bot's username.
@ -158,8 +159,8 @@ class User(Object, Update):
first_name: str = None, first_name: str = None,
last_name: str = None, last_name: str = None,
status: str = None, status: str = None,
last_online_date: int = None, last_online_date: datetime = None,
next_offline_date: int = None, next_offline_date: datetime = None,
username: str = None, username: str = None,
language_code: str = None, language_code: str = None,
dc_id: int = None, dc_id: int = None,
@ -247,10 +248,10 @@ class User(Object, Update):
status = None status = None
if status == enums.UserStatus.ONLINE: if status == enums.UserStatus.ONLINE:
next_offline_date = date next_offline_date = utils.timestamp_to_datetime(date)
if status == enums.UserStatus.OFFLINE: if status == enums.UserStatus.OFFLINE:
last_online_date = date last_online_date = utils.timestamp_to_datetime(date)
return { return {
"status": status, "status": status,

View File

@ -16,7 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram import raw from datetime import datetime
from pyrogram import raw, utils
from ..object import Object from ..object import Object
@ -24,13 +26,13 @@ class VoiceChatScheduled(Object):
"""A service message about a voice chat scheduled in the chat. """A service message about a voice chat scheduled in the chat.
Parameters: Parameters:
start_date (``int``): start_date (:py:obj:`~datetime.datetime`):
Point in time (Unix timestamp) when the voice chat is supposed to be started by a chat administrator. Point in time when the voice chat is supposed to be started by a chat administrator.
""" """
def __init__( def __init__(
self, *, self, *,
start_date: int start_date: datetime
): ):
super().__init__() super().__init__()
@ -38,4 +40,4 @@ class VoiceChatScheduled(Object):
@staticmethod @staticmethod
def _parse(action: "raw.types.MessageActionGroupCallScheduled") -> "VoiceChatScheduled": def _parse(action: "raw.types.MessageActionGroupCallScheduled") -> "VoiceChatScheduled":
return VoiceChatScheduled(start_date=action.schedule_date) return VoiceChatScheduled(start_date=utils.timestamp_to_datetime(action.schedule_date))

View File

@ -23,11 +23,12 @@ import hashlib
import os import os
import struct import struct
from concurrent.futures.thread import ThreadPoolExecutor from concurrent.futures.thread import ThreadPoolExecutor
from datetime import datetime
from getpass import getpass from getpass import getpass
from typing import Union, List, Dict, Optional from typing import Union, List, Dict, Optional
import pyrogram import pyrogram
from pyrogram import raw from pyrogram import raw, enums
from pyrogram import types from pyrogram import types
from pyrogram.file_id import FileId, FileType, PHOTO_TYPES, DOCUMENT_TYPES from pyrogram.file_id import FileId, FileType, PHOTO_TYPES, DOCUMENT_TYPES
@ -294,7 +295,7 @@ def compute_password_check(r: raw.types.account.Password, password: str) -> raw.
async def parse_text_entities( async def parse_text_entities(
client: "pyrogram.Client", client: "pyrogram.Client",
text: str, text: str,
parse_mode: str, parse_mode: enums.ParseMode,
entities: List["types.MessageEntity"] entities: List["types.MessageEntity"]
) -> Dict[str, raw.base.MessageEntity]: ) -> Dict[str, raw.base.MessageEntity]:
if entities: if entities:
@ -310,3 +311,11 @@ async def parse_text_entities(
"message": text, "message": text,
"entities": entities "entities": entities
} }
def timestamp_to_datetime(ts: Optional[int]) -> Optional[datetime]:
return datetime.fromtimestamp(ts) if ts else None
def datetime_to_timestamp(dt: Optional[datetime]) -> Optional[int]:
return int(dt.timestamp()) if dt else None