From 465dcac630fd07990225e55761a69862fb1ce28d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Oct 2018 17:08:49 +0200 Subject: [PATCH 01/17] Create LastSeen class --- compiler/api/compiler.py | 1 + pyrogram/__init__.py | 2 +- pyrogram/client/types/__init__.py | 2 +- .../client/types/user_and_chats/__init__.py | 1 + .../client/types/user_and_chats/last_seen.py | 46 +++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 pyrogram/client/types/user_and_chats/last_seen.py diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index bcb96ea4..4cce310a 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -506,6 +506,7 @@ def start(): f.write("\n 0xb0700028: \"pyrogram.client.types.Dialog\",") f.write("\n 0xb0700029: \"pyrogram.client.types.Dialogs\",") f.write("\n 0xb0700030: \"pyrogram.client.types.ChatMembers\",") + f.write("\n 0xb0700031: \"pyrogram.client.types.LastSeen\"") f.write("\n}\n") diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 6fb6fff4..cc6e9899 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -29,7 +29,7 @@ from .api.errors import Error from .client.types import ( Audio, Chat, ChatMember, ChatMembers, ChatPhoto, Contact, Document, InputMediaPhoto, InputMediaVideo, InputMediaDocument, InputMediaAudio, InputMediaAnimation, InputPhoneContact, - Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, + Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, LastSeen, UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove ) diff --git a/pyrogram/client/types/__init__.py b/pyrogram/client/types/__init__.py index 230d5e5d..a4b33e40 100644 --- a/pyrogram/client/types/__init__.py +++ b/pyrogram/client/types/__init__.py @@ -36,5 +36,5 @@ from .messages_and_media import ( from .update import Update from .user_and_chats import ( Chat, ChatMember, ChatMembers, ChatPhoto, - Dialog, Dialogs, User + Dialog, Dialogs, User, LastSeen ) diff --git a/pyrogram/client/types/user_and_chats/__init__.py b/pyrogram/client/types/user_and_chats/__init__.py index 45915edc..6711ab2c 100644 --- a/pyrogram/client/types/user_and_chats/__init__.py +++ b/pyrogram/client/types/user_and_chats/__init__.py @@ -22,4 +22,5 @@ from .chat_members import ChatMembers from .chat_photo import ChatPhoto from .dialog import Dialog from .dialogs import Dialogs +from .last_seen import LastSeen from .user import User diff --git a/pyrogram/client/types/user_and_chats/last_seen.py b/pyrogram/client/types/user_and_chats/last_seen.py new file mode 100644 index 00000000..7403039b --- /dev/null +++ b/pyrogram/client/types/user_and_chats/last_seen.py @@ -0,0 +1,46 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from pyrogram.api.core import Object + + +class LastSeen(Object): + """This object represents a User last seen status + """ + + ID = 0xb0700031 + + def __init__( + self, + online: bool = None, + offline: bool = None, + recently: bool = None, + within_week: bool = None, + within_month: bool = None, + long_time_ago: bool = None, + bot: bool = None, + date: int = None, + ): + self.online = online + self.offline = offline + self.recently = recently + self.within_week = within_week + self.within_month = within_month + self.long_time_ago = long_time_ago + self.bot = bot + self.date = date From d2f47d7e5976da9d10de0447d85219be6984b28a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Oct 2018 17:11:01 +0200 Subject: [PATCH 02/17] Add last_seen field to User parse_last_seen --- pyrogram/client/types/user_and_chats/user.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index 9ae5dab2..fd4730c3 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -70,6 +70,7 @@ class User(Object): is_mutual_contact: bool, is_deleted: bool, is_bot: bool, + last_seen, first_name: str, last_name: str = None, username: str = None, @@ -83,6 +84,7 @@ class User(Object): self.is_mutual_contact = is_mutual_contact self.is_deleted = is_deleted self.is_bot = is_bot + self.last_seen = last_seen self.first_name = first_name self.last_name = last_name self.username = username From 7b369a73bbcc80061eae73eabe7bbc3aef721d96 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Oct 2018 17:11:27 +0200 Subject: [PATCH 03/17] Add parse_last_seen util method --- pyrogram/client/ext/utils.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index a497e3c9..82322d07 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -129,6 +129,30 @@ def parse_chat_photo(photo): ) +def parse_last_seen(user: types.User) -> pyrogram_types.LastSeen: + status = user.status + last_seen = pyrogram_types.LastSeen() + + if isinstance(status, types.UserStatusOnline): + last_seen.online = True + last_seen.date = status.expires + elif isinstance(status, types.UserStatusOffline): + last_seen.offline = True + last_seen.date = status.was_online + elif isinstance(status, types.UserStatusRecently): + last_seen.recently = True + elif isinstance(status, types.UserStatusLastWeek): + last_seen.within_week = True + elif isinstance(status, types.UserStatusLastMonth): + last_seen.within_month = True + elif user.bot: + last_seen.bot = True + else: + last_seen.long_time_ago = True + + return last_seen + + def parse_user(user: types.User) -> pyrogram_types.User or None: return pyrogram_types.User( id=user.id, @@ -142,7 +166,8 @@ def parse_user(user: types.User) -> pyrogram_types.User or None: username=user.username, language_code=user.lang_code, phone_number=user.phone, - photo=parse_chat_photo(user.photo) + photo=parse_chat_photo(user.photo), + last_seen=parse_last_seen(user), ) if user else None From 69c1532eaebfedcd369e1d7271621b4f5e350e8f Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Oct 2018 17:17:50 +0200 Subject: [PATCH 04/17] Rename LastSeen to UserStatus It will make more sense later on when I add UserStatus updates handler. --- compiler/api/compiler.py | 2 +- pyrogram/__init__.py | 2 +- pyrogram/client/ext/utils.py | 4 ++-- pyrogram/client/types/__init__.py | 2 +- pyrogram/client/types/user_and_chats/__init__.py | 2 +- .../types/user_and_chats/{last_seen.py => user_status.py} | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) rename pyrogram/client/types/user_and_chats/{last_seen.py => user_status.py} (98%) diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 4cce310a..cacd9342 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -506,7 +506,7 @@ def start(): f.write("\n 0xb0700028: \"pyrogram.client.types.Dialog\",") f.write("\n 0xb0700029: \"pyrogram.client.types.Dialogs\",") f.write("\n 0xb0700030: \"pyrogram.client.types.ChatMembers\",") - f.write("\n 0xb0700031: \"pyrogram.client.types.LastSeen\"") + f.write("\n 0xb0700031: \"pyrogram.client.types.UserStatus\"") f.write("\n}\n") diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index cc6e9899..1f717a84 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -29,7 +29,7 @@ from .api.errors import Error from .client.types import ( Audio, Chat, ChatMember, ChatMembers, ChatPhoto, Contact, Document, InputMediaPhoto, InputMediaVideo, InputMediaDocument, InputMediaAudio, InputMediaAnimation, InputPhoneContact, - Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, LastSeen, + Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, UserStatus, UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove ) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 82322d07..5c80264b 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -129,9 +129,9 @@ def parse_chat_photo(photo): ) -def parse_last_seen(user: types.User) -> pyrogram_types.LastSeen: +def parse_last_seen(user: types.User) -> pyrogram_types.UserStatus: status = user.status - last_seen = pyrogram_types.LastSeen() + last_seen = pyrogram_types.UserStatus() if isinstance(status, types.UserStatusOnline): last_seen.online = True diff --git a/pyrogram/client/types/__init__.py b/pyrogram/client/types/__init__.py index a4b33e40..74c97ca1 100644 --- a/pyrogram/client/types/__init__.py +++ b/pyrogram/client/types/__init__.py @@ -36,5 +36,5 @@ from .messages_and_media import ( from .update import Update from .user_and_chats import ( Chat, ChatMember, ChatMembers, ChatPhoto, - Dialog, Dialogs, User, LastSeen + Dialog, Dialogs, User, UserStatus ) diff --git a/pyrogram/client/types/user_and_chats/__init__.py b/pyrogram/client/types/user_and_chats/__init__.py index 6711ab2c..f4742d83 100644 --- a/pyrogram/client/types/user_and_chats/__init__.py +++ b/pyrogram/client/types/user_and_chats/__init__.py @@ -22,5 +22,5 @@ from .chat_members import ChatMembers from .chat_photo import ChatPhoto from .dialog import Dialog from .dialogs import Dialogs -from .last_seen import LastSeen +from .user_status import UserStatus from .user import User diff --git a/pyrogram/client/types/user_and_chats/last_seen.py b/pyrogram/client/types/user_and_chats/user_status.py similarity index 98% rename from pyrogram/client/types/user_and_chats/last_seen.py rename to pyrogram/client/types/user_and_chats/user_status.py index 7403039b..bb42dc45 100644 --- a/pyrogram/client/types/user_and_chats/last_seen.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -19,7 +19,7 @@ from pyrogram.api.core import Object -class LastSeen(Object): +class UserStatus(Object): """This object represents a User last seen status """ From c9ce188bbe9c898dc1988f9c21b0fdb9ff7a7f6d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Oct 2018 17:56:10 +0200 Subject: [PATCH 05/17] Remove "bot" property from UserStatus --- pyrogram/client/ext/utils.py | 5 +++-- pyrogram/client/types/user_and_chats/user_status.py | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 5c80264b..15db2e73 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -130,6 +130,9 @@ def parse_chat_photo(photo): def parse_last_seen(user: types.User) -> pyrogram_types.UserStatus: + if user.bot: + return None + status = user.status last_seen = pyrogram_types.UserStatus() @@ -145,8 +148,6 @@ def parse_last_seen(user: types.User) -> pyrogram_types.UserStatus: last_seen.within_week = True elif isinstance(status, types.UserStatusLastMonth): last_seen.within_month = True - elif user.bot: - last_seen.bot = True else: last_seen.long_time_ago = True diff --git a/pyrogram/client/types/user_and_chats/user_status.py b/pyrogram/client/types/user_and_chats/user_status.py index bb42dc45..90399f43 100644 --- a/pyrogram/client/types/user_and_chats/user_status.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -33,7 +33,6 @@ class UserStatus(Object): within_week: bool = None, within_month: bool = None, long_time_ago: bool = None, - bot: bool = None, date: int = None, ): self.online = online @@ -42,5 +41,4 @@ class UserStatus(Object): self.within_week = within_week self.within_month = within_month self.long_time_ago = long_time_ago - self.bot = bot self.date = date From 2d65eb3dc7e3e12904f1c7c0f79807ebb0b99ba1 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Oct 2018 17:56:51 +0200 Subject: [PATCH 06/17] Add UserStatus docstrings --- .../types/user_and_chats/user_status.py | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/types/user_and_chats/user_status.py b/pyrogram/client/types/user_and_chats/user_status.py index 90399f43..8792a4df 100644 --- a/pyrogram/client/types/user_and_chats/user_status.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -20,7 +20,42 @@ from pyrogram.api.core import Object class UserStatus(Object): - """This object represents a User last seen status + """This object represents a User status (Last Seen privacy) + + .. note:: + + You won't see exact last seen timestamps for people with whom you don't share your own. Instead, you get + "recently", "within_week", "within_month" or "long_time_ago" fields set. + + Args: + online (``bool``): + True if the user is online in this moment, None otherwise. + If True, the "date" field will be also set containing the online expiration date (i.e.: the date when a + user will automatically go offline in case of no action by his client). + + offline (``bool``): + True if the user is offline and has the Last Seen privacy setting visible for everybody, None otherwise. + If True, the "date" field will be also set containing the last seen date (i.e.: the date when a user + was online the last time). + + recently (``bool``): + True for users with hidden Last Seen privacy that have been online between 1 second and 2-3 days ago, + None otherwise. + + within_week (``bool``): + True for users with hidden Last Seen privacy that have been online between 2-3 and seven days ago, + None otherwise. + + within_month (``bool``): + True for users with hidden Last Seen privacy that have been online between 6-7 days and a month ago, + None otherwise. + + long_time_ago (``bool``): + True for users with hidden Last Seen privacy that have been online more than a month ago (this is also + always shown to blocked users), None otherwise. + + date (``int``): + Exact date in unix time. Available only in case "online" or "offline" equals to True. """ ID = 0xb0700031 From b00604dbc93ab5c5f17d6b4dc63db70fbf899d25 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Oct 2018 18:00:31 +0200 Subject: [PATCH 07/17] Move date field --- pyrogram/client/types/user_and_chats/user_status.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/user_status.py b/pyrogram/client/types/user_and_chats/user_status.py index 8792a4df..24b30d68 100644 --- a/pyrogram/client/types/user_and_chats/user_status.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -38,6 +38,9 @@ class UserStatus(Object): If True, the "date" field will be also set containing the last seen date (i.e.: the date when a user was online the last time). + date (``int``): + Exact date in unix time. Available only in case "online" or "offline" equals to True. + recently (``bool``): True for users with hidden Last Seen privacy that have been online between 1 second and 2-3 days ago, None otherwise. @@ -53,9 +56,6 @@ class UserStatus(Object): long_time_ago (``bool``): True for users with hidden Last Seen privacy that have been online more than a month ago (this is also always shown to blocked users), None otherwise. - - date (``int``): - Exact date in unix time. Available only in case "online" or "offline" equals to True. """ ID = 0xb0700031 @@ -64,16 +64,16 @@ class UserStatus(Object): self, online: bool = None, offline: bool = None, + date: int = None, recently: bool = None, within_week: bool = None, within_month: bool = None, - long_time_ago: bool = None, - date: int = None, + long_time_ago: bool = None ): self.online = online self.offline = offline + self.date = date self.recently = recently self.within_week = within_week self.within_month = within_month self.long_time_ago = long_time_ago - self.date = date From 7ff4c340f767c06662c0abd080345cb86e7119c0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sun, 14 Oct 2018 18:00:41 +0200 Subject: [PATCH 08/17] Add UserStatus to docs --- docs/source/pyrogram/Types.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/source/pyrogram/Types.rst b/docs/source/pyrogram/Types.rst index e8dc709c..8763c0e1 100644 --- a/docs/source/pyrogram/Types.rst +++ b/docs/source/pyrogram/Types.rst @@ -10,6 +10,7 @@ Users & Chats :nosignatures: User + UserStatus Chat ChatPhoto ChatMember @@ -73,6 +74,9 @@ Input Media .. autoclass:: User :members: +.. autoclass:: UserStatus + :members: + .. autoclass:: Chat :members: From 86e4fc4e62786cbd0632f196be7eeb22dec05e4b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 09:20:13 +0200 Subject: [PATCH 09/17] Rename last_seen field to status in User class Also add docstrings for status --- pyrogram/client/types/user_and_chats/user.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/types/user_and_chats/user.py b/pyrogram/client/types/user_and_chats/user.py index fd4730c3..9c7eec1f 100644 --- a/pyrogram/client/types/user_and_chats/user.py +++ b/pyrogram/client/types/user_and_chats/user.py @@ -41,6 +41,9 @@ class User(Object): is_bot (``bool``): True, if this user is a bot. + status (:obj:`UserStatus `): + User's Last Seen status. Empty for bots. + first_name (``str``): User's or bot's first name. @@ -70,7 +73,7 @@ class User(Object): is_mutual_contact: bool, is_deleted: bool, is_bot: bool, - last_seen, + status, first_name: str, last_name: str = None, username: str = None, @@ -84,7 +87,7 @@ class User(Object): self.is_mutual_contact = is_mutual_contact self.is_deleted = is_deleted self.is_bot = is_bot - self.last_seen = last_seen + self.status = status self.first_name = first_name self.last_name = last_name self.username = username From b2b599e211cade878e4d4dc8267bf9f636ecd9ba Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 09:47:47 +0200 Subject: [PATCH 10/17] Rework user status parsing to also accommodate user_status updates --- pyrogram/client/ext/utils.py | 41 +++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 15db2e73..c169f54f 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -129,29 +129,32 @@ def parse_chat_photo(photo): ) -def parse_last_seen(user: types.User) -> pyrogram_types.UserStatus: - if user.bot: +def parse_update_user_status(update: types.UpdateUserStatus) -> pyrogram_types.User: + return pyrogram_types.User(id=update.user_id, status=parse_user_status(update.status)) + + +def parse_user_status(user_status, is_bot: bool = False) -> pyrogram_types.UserStatus or None: + if is_bot: return None - status = user.status - last_seen = pyrogram_types.UserStatus() + status = pyrogram_types.UserStatus() - if isinstance(status, types.UserStatusOnline): - last_seen.online = True - last_seen.date = status.expires - elif isinstance(status, types.UserStatusOffline): - last_seen.offline = True - last_seen.date = status.was_online - elif isinstance(status, types.UserStatusRecently): - last_seen.recently = True - elif isinstance(status, types.UserStatusLastWeek): - last_seen.within_week = True - elif isinstance(status, types.UserStatusLastMonth): - last_seen.within_month = True + if isinstance(user_status, types.UserStatusOnline): + status.online = True + status.date = user_status.expires + elif isinstance(user_status, types.UserStatusOffline): + status.offline = True + status.date = user_status.was_online + elif isinstance(user_status, types.UserStatusRecently): + status.recently = True + elif isinstance(user_status, types.UserStatusLastWeek): + status.within_week = True + elif isinstance(user_status, types.UserStatusLastMonth): + status.within_month = True else: - last_seen.long_time_ago = True + status.long_time_ago = True - return last_seen + return status def parse_user(user: types.User) -> pyrogram_types.User or None: @@ -168,7 +171,7 @@ def parse_user(user: types.User) -> pyrogram_types.User or None: language_code=user.lang_code, phone_number=user.phone, photo=parse_chat_photo(user.photo), - last_seen=parse_last_seen(user), + status=parse_user_status(user.status, user.bot), ) if user else None From 79a9ddfab5d67e5927a237cf2e2bcd3094ad4719 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:07:46 +0200 Subject: [PATCH 11/17] Some more changed in order to enhance UserStatus API design --- pyrogram/client/ext/utils.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index c169f54f..c7a10db9 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -129,15 +129,11 @@ def parse_chat_photo(photo): ) -def parse_update_user_status(update: types.UpdateUserStatus) -> pyrogram_types.User: - return pyrogram_types.User(id=update.user_id, status=parse_user_status(update.status)) - - -def parse_user_status(user_status, is_bot: bool = False) -> pyrogram_types.UserStatus or None: +def parse_user_status(user_status, user_id: int = None, is_bot: bool = False) -> pyrogram_types.UserStatus or None: if is_bot: return None - status = pyrogram_types.UserStatus() + status = pyrogram_types.UserStatus(user_id) if isinstance(user_status, types.UserStatusOnline): status.online = True @@ -171,7 +167,7 @@ def parse_user(user: types.User) -> pyrogram_types.User or None: language_code=user.lang_code, phone_number=user.phone, photo=parse_chat_photo(user.photo), - status=parse_user_status(user.status, user.bot), + status=parse_user_status(user.status, is_bot=user.bot), ) if user else None From 4b04910197a320a4b6f81f441bf553e917d1731b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:08:56 +0200 Subject: [PATCH 12/17] Add user_id field to UserStatus --- pyrogram/client/types/user_and_chats/user_status.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyrogram/client/types/user_and_chats/user_status.py b/pyrogram/client/types/user_and_chats/user_status.py index 24b30d68..17b73ea1 100644 --- a/pyrogram/client/types/user_and_chats/user_status.py +++ b/pyrogram/client/types/user_and_chats/user_status.py @@ -28,6 +28,9 @@ class UserStatus(Object): "recently", "within_week", "within_month" or "long_time_ago" fields set. Args: + user_id (``int``): + User's id. Only available for UserStatus updates. + online (``bool``): True if the user is online in this moment, None otherwise. If True, the "date" field will be also set containing the online expiration date (i.e.: the date when a @@ -62,6 +65,7 @@ class UserStatus(Object): def __init__( self, + user_id: int = None, online: bool = None, offline: bool = None, date: int = None, @@ -70,6 +74,7 @@ class UserStatus(Object): within_month: bool = None, long_time_ago: bool = None ): + self.user_id = user_id self.online = online self.offline = offline self.date = date From 471b5c33340604348ebc67a8ba23f68a0987ce94 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:10:49 +0200 Subject: [PATCH 13/17] Add user_status field to Update class --- pyrogram/client/types/update.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/types/update.py b/pyrogram/client/types/update.py index c8959708..748108de 100644 --- a/pyrogram/client/types/update.py +++ b/pyrogram/client/types/update.py @@ -58,6 +58,9 @@ class Update(Object): pre_checkout_query (:obj:`PreCheckoutQuery `, *optional*): New incoming pre-checkout query. Contains full information about checkout. + + user_status (:obj:`UserStatus `, *optional*): + User status (last seen date) update. """ ID = 0xb0700000 @@ -74,7 +77,8 @@ class Update(Object): chosen_inline_result=None, callback_query=None, shipping_query=None, - pre_checkout_query=None + pre_checkout_query=None, + user_status=None ): self.message = message self.edited_message = edited_message @@ -87,3 +91,4 @@ class Update(Object): self.callback_query = callback_query self.shipping_query = shipping_query self.pre_checkout_query = pre_checkout_query + self.user_status = user_status From ff9be53a95def291b363ba877a73830b48656437 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:14:40 +0200 Subject: [PATCH 14/17] Add UserStatusHandler class --- .../client/handlers/user_status_handler.py | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 pyrogram/client/handlers/user_status_handler.py diff --git a/pyrogram/client/handlers/user_status_handler.py b/pyrogram/client/handlers/user_status_handler.py new file mode 100644 index 00000000..2442d7eb --- /dev/null +++ b/pyrogram/client/handlers/user_status_handler.py @@ -0,0 +1,54 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from .handler import Handler + + +class UserStatusHandler(Handler): + """The UserStatus handler class. Used to handle user status updates (user going online or offline). + It is intended to be used with :meth:`add_handler() ` + + For a nicer way to register this handler, have a look at the + :meth:`on_user_status() ` decorator. + + Args: + callback (``callable``): + Pass a function that will be called when a new UserStatus update arrives. It takes *(client, user_status)* + as positional arguments (look at the section below for a detailed description). + + filters (:obj:`Filters `): + Pass one or more filters to allow only a subset of messages to be passed + in your callback function. + + Other parameters: + client (:obj:`Client `): + The Client itself, useful when you want to call other API methods inside the user status handler. + + user_status (:obj:`UserStatus `): + The received UserStatus update. + """ + + def __init__(self, callback: callable, filters=None): + super().__init__(callback, filters) + + def check(self, user_status): + return ( + self.filters(user_status) + if callable(self.filters) + else True + ) From 2eae08aaa642d742cfc888b543501316188f2bad Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:16:19 +0200 Subject: [PATCH 15/17] Add on_user_status decorator --- .../methods/decorators/on_user_status.py | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 pyrogram/client/methods/decorators/on_user_status.py diff --git a/pyrogram/client/methods/decorators/on_user_status.py b/pyrogram/client/methods/decorators/on_user_status.py new file mode 100644 index 00000000..81367c3e --- /dev/null +++ b/pyrogram/client/methods/decorators/on_user_status.py @@ -0,0 +1,41 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2018 Dan Tès +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import pyrogram +from ...ext import BaseClient + + +class OnUserStatus(BaseClient): + def on_user_status(self, filters=None, group: int = 0): + """Use this decorator to automatically register a function for handling + user status updates. This does the same thing as :meth:`add_handler` using the + :class:`UserStatusHandler`. + + Args: + filters (:obj:`Filters `): + Pass one or more filters to allow only a subset of UserStatus updated to be passed in your function. + + group (``int``, *optional*): + The group identifier, defaults to 0. + """ + + def decorator(func): + self.add_handler(pyrogram.UserStatusHandler(func, filters), group) + return func + + return decorator From d567b878b1b70528c9cb22718c1faccfefd78148 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:17:00 +0200 Subject: [PATCH 16/17] Expose UserStatusHandler and on_user_status --- pyrogram/__init__.py | 2 +- pyrogram/client/__init__.py | 2 +- pyrogram/client/handlers/__init__.py | 3 ++- pyrogram/client/methods/decorators/__init__.py | 12 ++++++++++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 1f717a84..12f181c3 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -36,5 +36,5 @@ from .client.types import ( from .client import ( Client, ChatAction, ParseMode, Emoji, MessageHandler, DeletedMessagesHandler, CallbackQueryHandler, - RawUpdateHandler, DisconnectHandler, Filters + RawUpdateHandler, DisconnectHandler, UserStatusHandler, Filters ) diff --git a/pyrogram/client/__init__.py b/pyrogram/client/__init__.py index b345de94..00b9905a 100644 --- a/pyrogram/client/__init__.py +++ b/pyrogram/client/__init__.py @@ -22,5 +22,5 @@ from .filters import Filters from .handlers import ( MessageHandler, DeletedMessagesHandler, CallbackQueryHandler, RawUpdateHandler, - DisconnectHandler + DisconnectHandler, UserStatusHandler ) diff --git a/pyrogram/client/handlers/__init__.py b/pyrogram/client/handlers/__init__.py index d06b2a76..ff1ead7a 100644 --- a/pyrogram/client/handlers/__init__.py +++ b/pyrogram/client/handlers/__init__.py @@ -17,7 +17,8 @@ # along with Pyrogram. If not, see . from .callback_query_handler import CallbackQueryHandler +from .deleted_messages_handler import DeletedMessagesHandler from .disconnect_handler import DisconnectHandler from .message_handler import MessageHandler -from .deleted_messages_handler import DeletedMessagesHandler from .raw_update_handler import RawUpdateHandler +from .user_status_handler import UserStatusHandler diff --git a/pyrogram/client/methods/decorators/__init__.py b/pyrogram/client/methods/decorators/__init__.py index f84a922c..6cf9940a 100644 --- a/pyrogram/client/methods/decorators/__init__.py +++ b/pyrogram/client/methods/decorators/__init__.py @@ -17,11 +17,19 @@ # along with Pyrogram. If not, see . from .on_callback_query import OnCallbackQuery +from .on_deleted_messages import OnDeletedMessages from .on_disconnect import OnDisconnect from .on_message import OnMessage -from .on_deleted_messages import OnDeletedMessages from .on_raw_update import OnRawUpdate +from .on_user_status import OnUserStatus -class Decorators(OnMessage, OnDeletedMessages, OnCallbackQuery, OnRawUpdate, OnDisconnect): +class Decorators( + OnMessage, + OnDeletedMessages, + OnCallbackQuery, + OnRawUpdate, + OnDisconnect, + OnUserStatus +): pass From 5b173768013a5ee7d50fa3cfd955bdad913eec16 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Mon, 15 Oct 2018 10:18:22 +0200 Subject: [PATCH 17/17] Enable dispatching of user status updates --- pyrogram/client/dispatcher/dispatcher.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index 5506cbdd..a0c5e365 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -25,7 +25,7 @@ from threading import Thread import pyrogram from pyrogram.api import types from ..ext import utils -from ..handlers import RawUpdateHandler, CallbackQueryHandler, MessageHandler, DeletedMessagesHandler +from ..handlers import RawUpdateHandler, CallbackQueryHandler, MessageHandler, DeletedMessagesHandler, UserStatusHandler log = logging.getLogger(__name__) @@ -108,6 +108,8 @@ class Dispatcher: callback_query = update.callback_query + user_status = update.user_status + if message and isinstance(handler, MessageHandler): if not handler.check(message): continue @@ -123,6 +125,11 @@ class Dispatcher: continue args = (self.client, callback_query) + elif user_status and isinstance(handler, UserStatusHandler): + if not handler.check(user_status): + continue + + args = (self.client, user_status) else: continue @@ -209,6 +216,14 @@ class Dispatcher: ) ) ) + elif isinstance(update, types.UpdateUserStatus): + self.dispatch( + pyrogram.Update( + user_status=utils.parse_user_status( + update.status, update.user_id + ) + ) + ) else: continue except Exception as e: