Skip to content
Closed
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
38 changes: 32 additions & 6 deletions src/pymax/api/chats/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
from functools import reduce
from operator import or_
from typing import TYPE_CHECKING
from datetime import datetime, timedelta

from pymax.api.messages import DateTimeUnion

from pymax.api.binding import bind_api_model
from pymax.api.response import (
Expand Down Expand Up @@ -82,6 +85,19 @@ def _remove_cached_chat(self, chat_id: int) -> None:

self.app.chats = [chat for chat in self.app.chats if chat.id != chat_id]

def _convert_period(self, period: DateTimeUnion) -> int:
if isinstance(period, timedelta):
return int(period.total_seconds())
if isinstance(period, datetime):
raise ValueError("Period cannot be a datetime")
return int(period)

def _convert_time(self, time_: DateTimeUnion) -> int:
if isinstance(time_, datetime):
return int(time_.timestamp() * 1000)
if isinstance(time_, timedelta):
return int((datetime.now() + time_).timestamp() * 1000)

@staticmethod
def _process_chat_join_link(link: str) -> str | None:
idx = link.find(ChatLinkPrefix.JOIN)
Expand Down Expand Up @@ -164,12 +180,12 @@ async def remove_users_from_group(
self,
chat_id: int,
user_ids: list[int],
clean_msg_period: int,
clean_msg_period: DateTimeUnion,
) -> bool:
frame = RemoveUsersPayload(
chat_id=chat_id,
user_ids=user_ids,
clean_msg_period=clean_msg_period,
clean_msg_period=self._convert_period(clean_msg_period),
)

response = await self.app.invoke(
Expand Down Expand Up @@ -309,8 +325,16 @@ async def leave_group(self, chat_id: int) -> None:
async def leave_channel(self, chat_id: int) -> None:
await self.leave_group(chat_id)

async def fetch_chats(self, marker: int | None = None) -> list[Chat]:
frame = FetchChatsPayload(marker=marker or int(time.time() * 1000))
async def fetch_chats(self, marker: DateTimeUnion | None = None) -> list[Chat]:
frame = FetchChatsPayload(
marker=(
self._convert_time(marker)
if isinstance(marker, (datetime, timedelta))
# Если marker=0, он будет перезаписан текущим временем (т.к. 0 расценивается как False).
# Чтобы это исправить, можно заменить на: else (int(marker) if marker is not None else int(time.time() * 1000))
else (marker or int(time.time() * 1000))
)
)
response = await self.app.invoke(Opcode.CHATS_LIST, frame.to_payload())

chats = [
Expand Down Expand Up @@ -395,13 +419,15 @@ async def decline_join_request(
async def delete_chat(
self,
chat_id: int,
last_event_time: int | None = None,
last_event_time: DateTimeUnion | None = None,
for_all: bool = True,
) -> None:
frame = DeleteChatPayload(
chat_id=chat_id,
last_event_time=(
last_event_time if last_event_time is not None else int(time.time() * 1000)
self._convert_time(last_event_time)
if isinstance(last_event_time, (datetime, timedelta))
else (int(last_event_time) if last_event_time is not None else int(time.time() * 1000))
),
for_all=for_all,
)
Expand Down
27 changes: 20 additions & 7 deletions src/pymax/api/messages/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,14 @@ def _convert_time(self, time: DateTimeUnion) -> int:
if isinstance(time, timedelta):
return int((datetime.now() + time).timestamp() * 1000)

return time * 1000
return int(time) * 1000

def _convert_period(self, period: DateTimeUnion) -> int:
if isinstance(period, timedelta):
return int(period.total_seconds() * 1000)
if isinstance(period, datetime):
raise ValueError("Period cannot be a datetime")
return int(period)

async def send_message(
self,
Expand Down Expand Up @@ -284,9 +291,9 @@ async def fetch_history(
chat_id: int,
forward: int = 0,
backward: int = 40,
backward_time: int = 0,
forward_time: int = 0,
from_: int | None = None,
backward_time: DateTimeUnion = 0,
forward_time: DateTimeUnion = 0,
from_: DateTimeUnion | None = None,
item_type: ItemType = ItemType.REGULAR,
get_chat: bool = False,
get_messages: bool = True,
Expand All @@ -296,9 +303,15 @@ async def fetch_history(
chat_id=chat_id,
forward=forward,
backward=backward,
backward_time=backward_time,
forward_time=forward_time,
from_=from_ or int(time.time() * 1000),
backward_time=self._convert_period(backward_time),
forward_time=self._convert_period(forward_time),
from_=(
self._convert_time(from_)
if isinstance(from_, (datetime, timedelta))
# Если from_=0, он будет перезаписан текущим временем (т.к. 0 расценивается как False).
# Чтобы это исправить, можно заменить на: else (int(from_) if from_ is not None else int(time.time() * 1000))
else (from_ or int(time.time() * 1000))
),
item_type=item_type,
get_chat=get_chat,
get_messages=get_messages,
Expand Down
6 changes: 3 additions & 3 deletions src/pymax/infra/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ async def remove_users_from_group(
self,
chat_id: int,
user_ids: list[int],
clean_msg_period: int,
clean_msg_period: DateTimeUnion,
) -> bool:
"""Удаляет пользователей из группы.

Expand Down Expand Up @@ -254,7 +254,7 @@ async def leave_channel(self, chat_id: int) -> None:
async def delete_chat(
self,
chat_id: int,
last_event_time: int | None = None,
last_event_time: DateTimeUnion | None = None,
for_all: bool = True,
) -> None:
"""Удаляет чат.
Expand All @@ -272,7 +272,7 @@ async def delete_chat(
for_all=for_all,
)

async def fetch_chats(self, marker: int | None = None) -> list[Chat]:
async def fetch_chats(self, marker: DateTimeUnion | None = None) -> list[Chat]:
"""Загружает список чатов с сервера и обновляет кеш клиента.

Args:
Expand Down
6 changes: 3 additions & 3 deletions src/pymax/infra/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ async def fetch_history(
chat_id: int,
forward: int = 0,
backward: int = 40,
backward_time: int = 0,
forward_time: int = 0,
from_time: int | None = None,
backward_time: DateTimeUnion = 0,
forward_time: DateTimeUnion = 0,
from_time: DateTimeUnion | None = None,
item_type: ItemType = ItemType.REGULAR,
get_chat: bool = False,
get_messages: bool = True,
Expand Down
18 changes: 9 additions & 9 deletions src/pymax/types/domain/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

if TYPE_CHECKING:
from pymax.api.chats import ChatService
from pymax.api.messages import MessageService
from pymax.api.messages import MessageService, DateTimeUnion
from pymax.api.messages.enums import ItemType


Expand Down Expand Up @@ -190,9 +190,9 @@ async def history(
self,
forward: int = 0,
backward: int = 40,
backward_time: int = 0,
forward_time: int = 0,
from_time: int | None = None,
backward_time: DateTimeUnion = 0,
forward_time: DateTimeUnion = 0,
from_time: DateTimeUnion | None = None,
item_type: ItemType | None = None,
get_chat: bool = False,
get_messages: bool = True,
Expand All @@ -209,12 +209,12 @@ async def history(
:param backward: Сколько сообщений загрузить назад от ``from_time``.
:type backward: int
:param backward_time: Временное окно назад в миллисекундах.
:type backward_time: int
:type backward_time: DateTimeUnion
:param forward_time: Временное окно вперед в миллисекундах.
:type forward_time: int
:type forward_time: DateTimeUnion
:param from_time: Точка отсчета в миллисекундах Unix time. Если
``None``, используется текущий момент.
:type from_time: int | None
:type from_time: DateTimeUnion | None
:param item_type: Тип элементов истории: обычные или отложенные.
:type item_type: ItemType | None
:param get_chat: Запросить данные чата вместе с историей.
Expand Down Expand Up @@ -365,14 +365,14 @@ async def invite(
async def remove_users(
self,
user_ids: list[int],
clean_msg_period: int = 0,
clean_msg_period: DateTimeUnion = 0,
) -> bool:
"""Удаляет пользователей из группы.

:param user_ids: ID пользователей, которых нужно удалить.
:type user_ids: list[int]
:param clean_msg_period: Период удаления сообщений пользователей.
:type clean_msg_period: int
:type clean_msg_period: DateTimeUnion
:returns: ``True``, если сервер принял запрос.
:rtype: bool
:raises RuntimeError: Если чат не привязан к клиенту.
Expand Down
Loading