Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyrogram/methods/chats/set_chat_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ async def set_chat_permissions(
# Completely restrict chat
await app.set_chat_permissions(chat_id, ChatPermissions())

# Chat members can only send text messages and media messages
# Chat members can only send text messages and documents
await app.set_chat_permissions(
chat_id,
ChatPermissions(
can_send_messages=True,
can_send_media_messages=True
can_send_documents=True
)
)
"""
Expand Down
99 changes: 52 additions & 47 deletions pyrogram/methods/users/get_chat_photos.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,15 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.

from asyncio import sleep
from typing import Union, AsyncGenerator, Optional

import pyrogram
from pyrogram import types, raw

from typing import Union, AsyncGenerator
from pyrogram import types, raw, utils

class GetChatPhotos:
async def get_chat_photos(
self: "pyrogram.Client",
chat_id: Union[int, str],
limit: int = 0,
) -> Optional[
Union[
AsyncGenerator["types.Photo", None],
AsyncGenerator["types.Animation", None],
]
]:
) -> AsyncGenerator[Union["types.Photo", "types.Animation"], None]:
"""Get a chat or a user profile photos sequentially.

.. include:: /_includes/usable-by/users-bots.rst
Expand All @@ -57,20 +49,35 @@ async def get_chat_photos(
async for photo in app.get_chat_photos("me"):
print(photo)
"""

def get_unique_file_id(media_obj):
"""Отримати унікальний file_id для медіа об'єкта"""
if isinstance(media_obj, types.Animation):
return media_obj.file_unique_id
elif isinstance(media_obj, types.Photo) and media_obj.sizes:
return media_obj.sizes[-1].file_unique_id
return None

total = limit or (1 << 31)
limit = min(100, total)
chunk_limit = min(100, total)

peer_id = await self.resolve_peer(chat_id)
seen: set[str] = set()

if isinstance(peer_id, raw.types.InputPeerChannel):
r = await self.invoke(raw.functions.channels.GetFullChannel(channel=peer_id))

chat_icons = []
_animation = types.Animation._parse_chat_animation(self, r.full_chat.chat_photo)
_photo = types.Photo._parse(self, r.full_chat.chat_photo)
chat_icons = [_animation or _photo]

if _animation:
chat_icons.append(_animation)
elif _photo:
chat_icons.append(_photo)

if not (self.me and self.me.is_bot):
r = await self.invoke(
r_messages = await self.invoke(
raw.functions.messages.Search(
peer=peer_id,
q="",
Expand All @@ -79,60 +86,57 @@ async def get_chat_photos(
max_date=0,
offset_id=0,
add_offset=0,
limit=limit,
limit=chunk_limit,
max_id=0,
min_id=0,
hash=0,
)
)
if _icon := chat_icons[0]:
_first_file_id = _icon.file_id if _animation else _icon.sizes[0].file_id
else:
_first_file_id = None

for m in getattr(r, "messages", []):
if not isinstance(getattr(m, "action", None), raw.types.MessageActionChatEditPhoto):
continue

_c_animation = types.Animation._parse_chat_animation(self, m.action.photo)
_c_photo = types.Photo._parse(self, m.action.photo)

_current_file_id = (_c_animation and _c_animation.file_id) or (_c_photo and _c_photo.sizes[0].file_id)

if (_c_animation or _c_photo) and _first_file_id != _current_file_id:
chat_icons.append(_c_animation or _c_photo)
messages = await utils.parse_messages(self, r_messages)
for m in messages:
if isinstance(m.new_chat_photo, (types.Animation, types.Photo)):
chat_icons.append(m.new_chat_photo)

current = 0

for icon in chat_icons:
await sleep(0)

if not icon:
continue

file_unique_id = get_unique_file_id(icon)

if not file_unique_id or file_unique_id in seen:
continue

seen.add(file_unique_id)
yield icon

current += 1

if current >= limit:
if current >= total:
return

else:
current = 0
offset = 0

while True:
r = await self.invoke(
raw.functions.photos.GetUserPhotos(
user_id=peer_id, offset=offset, max_id=0, limit=limit
user_id=peer_id,
offset=offset,
max_id=0,
limit=chunk_limit
)
)

photos = []
for photo in r.photos:
photos.append(
types.Animation._parse_chat_animation(self, photo)
or types.Photo._parse(self, photo)
)
for p in r.photos:
_animation = types.Animation._parse_chat_animation(self, p)
_photo = types.Photo._parse(self, p)

if _animation:
photos.append(_animation)
elif _photo:
photos.append(_photo)

if not photos:
return
Expand All @@ -141,13 +145,14 @@ async def get_chat_photos(

for photo in photos:
await sleep(0)

if not photo:

file_unique_id = get_unique_file_id(photo)

if not file_unique_id or file_unique_id in seen:
continue


seen.add(file_unique_id)
yield photo

current += 1

if current >= total:
return
6 changes: 6 additions & 0 deletions pyrogram/types/user_and_chats/chat_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class ChatPermissions(Object):
def __init__(
self,
*,
can_send_plain: bool = None,
can_send_messages: bool = None, # Text, contacts, giveaways, giveaway winners, invoices, locations and venues
can_send_audios: bool = None,
can_send_documents: bool = None,
Expand All @@ -96,6 +97,7 @@ def __init__(
):
super().__init__(None)

self.can_send_plain = can_send_plain
self.can_send_messages = can_send_messages
self.can_send_audios = can_send_audios
self.can_send_documents = can_send_documents
Expand All @@ -114,6 +116,7 @@ def __init__(

@staticmethod
def _parse(denied_permissions: "raw.base.ChatBannedRights") -> "ChatPermissions":
can_send_plain = False
can_send_messages = False
can_send_audios = False
can_send_documents = False
Expand All @@ -131,6 +134,7 @@ def _parse(denied_permissions: "raw.base.ChatBannedRights") -> "ChatPermissions"
can_send_media_messages = False

if isinstance(denied_permissions, raw.types.ChatBannedRights):
can_send_plain = not denied_permissions.send_plain
can_send_messages = not denied_permissions.send_messages
can_send_polls = not denied_permissions.send_polls
can_send_other_messages = any([
Expand Down Expand Up @@ -171,6 +175,7 @@ def _parse(denied_permissions: "raw.base.ChatBannedRights") -> "ChatPermissions"
can_send_voice_notes = can_send_media_messages

return ChatPermissions(
can_send_plain=can_send_plain,
can_send_messages=can_send_messages,
can_send_audios=can_send_audios,
can_send_documents=can_send_documents,
Expand Down Expand Up @@ -217,5 +222,6 @@ def write(
send_videos=not permissions.can_send_videos,# TODO
send_roundvideos=not permissions.can_send_video_notes,# TODO
send_voices=not permissions.can_send_voice_notes,# TODO
send_plain=not permissions.can_send_plain# TODO
# send_plain=# TODO
)