From 8ec73c3baf6fadb6c898cd8933f3c652f4aea3be Mon Sep 17 00:00:00 2001 From: igorbunov Date: Thu, 16 Jul 2026 13:45:34 +0300 Subject: [PATCH 1/3] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C=20=D0=B7=D0=B0=D0=BF=D1=80=D0=B0=D1=88=D0=B8?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D1=8C=20=D1=81=D0=BF=D0=B8=D1=81=D0=BE=D0=BA?= =?UTF-8?q?=20=D1=87=D0=BB=D0=B5=D0=BD=D0=BE=D0=B2=20=D1=87=D0=B0=D1=82?= =?UTF-8?q?=D0=B0/=D0=B3=D1=80=D1=83=D0=BF=D0=BF=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pymax/api/chats/payloads.py | 7 +++++++ src/pymax/api/chats/service.py | 9 +++++++++ src/pymax/infra/chat.py | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/pymax/api/chats/payloads.py b/src/pymax/api/chats/payloads.py index 1adc8be..4d8981d 100644 --- a/src/pymax/api/chats/payloads.py +++ b/src/pymax/api/chats/payloads.py @@ -95,6 +95,13 @@ class GetChatInfoPayload(CamelModel): chat_ids: list[int] +class GetChatMembersPayload(CamelModel): + type: str = "MEMBER" # TODO: ENUMM!!! + chat_id: int + marker: int + count: int = 50 + + class LeaveChatPayload(CamelModel): chat_id: int diff --git a/src/pymax/api/chats/service.py b/src/pymax/api/chats/service.py index 83c5469..26a04e9 100644 --- a/src/pymax/api/chats/service.py +++ b/src/pymax/api/chats/service.py @@ -27,6 +27,7 @@ FetchChatsPayload, FetchJoinRequests, GetChatInfoPayload, + GetChatMembersPayload, InviteUsersPayload, JoinChatPayload, JoinRequestActionPayload, @@ -266,6 +267,14 @@ async def get_chats(self, chat_ids: list[int]) -> list[Chat]: return [cached[chat_id] for chat_id in chat_ids if chat_id in cached] + async def get_chat_members(self, chat_id: int, marker: int | None = None) -> list[Member]: + frame = GetChatMembersPayload(chat_id=chat_id, marker=marker or 0) + response = await self.app.invoke(Opcode.CHAT_MEMBERS, frame.to_payload()) + return bind_api_model( + self.app, + parse_payload_list(response, ChatPayloadKey.MEMBERS, Member), + ) + async def get_chat(self, chat_id: int) -> Chat: chats = await self.get_chats([chat_id]) if not chats: diff --git a/src/pymax/infra/chat.py b/src/pymax/infra/chat.py index 7e13218..873fa8a 100644 --- a/src/pymax/infra/chat.py +++ b/src/pymax/infra/chat.py @@ -211,6 +211,22 @@ async def get_chat(self, chat_id: int) -> Chat: """ return await self._app.api.chats.get_chat(chat_id) + async def get_chat_members(self, chat_id: int, marker: int | None = None) -> list[Member]: + """Возвращает участников чата по ID. + + Args: + chat_id: ID чата. + marker: Маркер пагинации. Если ``None``, запрашивается первая + страница. + + Returns: + Список участников. + + Raises: + PyMaxError: Если сервер не вернул участников. + """ + return await self._app.api.chats.get_chat_members(chat_id, marker) + async def leave_group(self, chat_id: int) -> None: """Выходит из группы. From 64d8ee0ba13abfb833ccf9a4a4b2c63a619d4bc0 Mon Sep 17 00:00:00 2001 From: igorbunov Date: Fri, 17 Jul 2026 11:46:20 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=BC=D0=B0=D1=80=D0=BA=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pymax/api/chats/enums.py | 1 + src/pymax/api/chats/service.py | 12 ++++++++++-- src/pymax/infra/chat.py | 19 +++++++++++-------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/pymax/api/chats/enums.py b/src/pymax/api/chats/enums.py index 4f61325..ffc1275 100644 --- a/src/pymax/api/chats/enums.py +++ b/src/pymax/api/chats/enums.py @@ -22,6 +22,7 @@ class ChatPayloadKey(str, Enum): CHAT = "chat" CHATS = "chats" MEMBERS = "members" + MARKER = "marker" class ChatLinkPrefix(str, Enum): diff --git a/src/pymax/api/chats/service.py b/src/pymax/api/chats/service.py index 26a04e9..fcf7cd1 100644 --- a/src/pymax/api/chats/service.py +++ b/src/pymax/api/chats/service.py @@ -7,6 +7,7 @@ from pymax.api.response import ( parse_payload_item_model, parse_payload_list, + payload_item, require_payload_item_model, require_payload_model, ) @@ -267,13 +268,20 @@ async def get_chats(self, chat_ids: list[int]) -> list[Chat]: return [cached[chat_id] for chat_id in chat_ids if chat_id in cached] - async def get_chat_members(self, chat_id: int, marker: int | None = None) -> list[Member]: + async def get_chat_members( + self, + chat_id: int, + marker: int | None = None, + ) -> tuple[list[Member], int]: frame = GetChatMembersPayload(chat_id=chat_id, marker=marker or 0) response = await self.app.invoke(Opcode.CHAT_MEMBERS, frame.to_payload()) - return bind_api_model( + + members = bind_api_model( self.app, parse_payload_list(response, ChatPayloadKey.MEMBERS, Member), ) + next_marker = payload_item(response, ChatPayloadKey.MARKER, int) or 0 + return members, next_marker async def get_chat(self, chat_id: int) -> Chat: chats = await self.get_chats([chat_id]) diff --git a/src/pymax/infra/chat.py b/src/pymax/infra/chat.py index 873fa8a..689ae99 100644 --- a/src/pymax/infra/chat.py +++ b/src/pymax/infra/chat.py @@ -211,19 +211,22 @@ async def get_chat(self, chat_id: int) -> Chat: """ return await self._app.api.chats.get_chat(chat_id) - async def get_chat_members(self, chat_id: int, marker: int | None = None) -> list[Member]: - """Возвращает участников чата по ID. + async def get_chat_members( + self, + chat_id: int, + marker: int | None = None, + ) -> tuple[list[Member], int]: + """Возвращает страницу участников чата по ID. Args: chat_id: ID чата. - marker: Маркер пагинации. Если ``None``, запрашивается первая - страница. + marker: Маркер страницы. Returns: - Список участников. - - Raises: - PyMaxError: Если сервер не вернул участников. + ``(members, next_marker)``. Если участников больше, чем + уместилось в ответ, ``next_marker`` ненулевой — передайте его в + следующий вызов, чтобы получить следующую страницу. ``0`` + означает, что дальше страниц нет. """ return await self._app.api.chats.get_chat_members(chat_id, marker) From cfb27fdb3639f2d060817ddaf9678812043d621b Mon Sep 17 00:00:00 2001 From: igorbunov Date: Mon, 20 Jul 2026 10:23:06 +0300 Subject: [PATCH 3/3] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20count?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pymax/api/chats/service.py | 3 ++- src/pymax/infra/chat.py | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pymax/api/chats/service.py b/src/pymax/api/chats/service.py index fcf7cd1..a731fce 100644 --- a/src/pymax/api/chats/service.py +++ b/src/pymax/api/chats/service.py @@ -272,8 +272,9 @@ async def get_chat_members( self, chat_id: int, marker: int | None = None, + count: int = 50, ) -> tuple[list[Member], int]: - frame = GetChatMembersPayload(chat_id=chat_id, marker=marker or 0) + frame = GetChatMembersPayload(chat_id=chat_id, marker=marker or 0, count=count) response = await self.app.invoke(Opcode.CHAT_MEMBERS, frame.to_payload()) members = bind_api_model( diff --git a/src/pymax/infra/chat.py b/src/pymax/infra/chat.py index 689ae99..34d908c 100644 --- a/src/pymax/infra/chat.py +++ b/src/pymax/infra/chat.py @@ -215,12 +215,15 @@ async def get_chat_members( self, chat_id: int, marker: int | None = None, + count: int = 50, ) -> tuple[list[Member], int]: """Возвращает страницу участников чата по ID. Args: chat_id: ID чата. - marker: Маркер страницы. + marker: Маркер страницы. Если ``None``, запрашивается первая + страница. + count: Максимальное количество участников в ответе. Returns: ``(members, next_marker)``. Если участников больше, чем @@ -228,7 +231,7 @@ async def get_chat_members( следующий вызов, чтобы получить следующую страницу. ``0`` означает, что дальше страниц нет. """ - return await self._app.api.chats.get_chat_members(chat_id, marker) + return await self._app.api.chats.get_chat_members(chat_id, marker, count) async def leave_group(self, chat_id: int) -> None: """Выходит из группы.