137 lines
4.1 KiB
Python
137 lines
4.1 KiB
Python
from datetime import UTC, datetime, timedelta
|
|
from uuid import UUID
|
|
|
|
from app.chat.shemas import (
|
|
SMessage,
|
|
SMessageList,
|
|
SMessageRaw,
|
|
SMessageRawList,
|
|
SPinnedMessages,
|
|
SSendMessage,
|
|
)
|
|
from app.services import user_service
|
|
from app.users.schemas import SUser
|
|
from app.utils.unit_of_work import UnitOfWork
|
|
|
|
_users: dict[int, tuple[SUser, datetime]] = {}
|
|
|
|
async def _get_cached_user(uow: UnitOfWork, user_id: int) -> SUser:
|
|
if user_id in _users and _users[user_id][1] > datetime.now(UTC):
|
|
return _users[user_id][0]
|
|
|
|
user = await user_service.find_user(uow=uow, id=user_id)
|
|
_users[user_id] = user, datetime.now(UTC) + timedelta(minutes=5)
|
|
return user
|
|
|
|
|
|
async def _add_avatar_image_and_username_to_message(uow: UnitOfWork, message: SMessageRaw) -> SMessage:
|
|
user = await _get_cached_user(uow=uow, user_id=message.user_id)
|
|
message = message.model_dump()
|
|
message["avatar_image"] = str(user.avatar_image)
|
|
message["username"] = user.username
|
|
return SMessage.model_validate(message)
|
|
|
|
|
|
async def _add_avatar_image_and_username_to_message_list(
|
|
uow: UnitOfWork,
|
|
messages: SMessageRawList,
|
|
) -> SMessageList:
|
|
return SMessageList.model_validate(
|
|
{
|
|
"messages": [
|
|
await _add_avatar_image_and_username_to_message(uow=uow, message=message)
|
|
for message in messages.message_raw_list
|
|
] if messages.message_raw_list else None
|
|
}
|
|
)
|
|
|
|
async def send_message(
|
|
uow: UnitOfWork,
|
|
user_id: int,
|
|
chat_id: int,
|
|
message: SSendMessage,
|
|
) -> SMessage:
|
|
async with uow:
|
|
if message.answer:
|
|
answer_message = await uow.message.get_message_by_id(message_id=message.answer)
|
|
message_id = await uow.message.send_message(
|
|
user_id=user_id,
|
|
chat_id=chat_id,
|
|
message=message.message,
|
|
image_url=message.image_url,
|
|
answer_id=answer_message.id,
|
|
answer_message=answer_message.message,
|
|
answer_image_url=answer_message.answer_image_url,
|
|
)
|
|
else:
|
|
message_id = await uow.message.send_message(
|
|
user_id=user_id,
|
|
chat_id=chat_id,
|
|
message=message.message,
|
|
image_url=message.image_url,
|
|
)
|
|
|
|
new_message = await get_message_by_id(uow=uow, message_id=message_id)
|
|
|
|
return new_message
|
|
|
|
async def delete_message(uow: UnitOfWork, message_id: UUID) -> None:
|
|
async with uow:
|
|
await uow.message.delete_message(message_id=message_id)
|
|
|
|
async def edit_message(uow: UnitOfWork, message_id: UUID, new_message: str, new_image_url: str) -> None:
|
|
async with uow:
|
|
await uow.message.edit_message(
|
|
message_id=message_id,
|
|
new_message=new_message,
|
|
new_image_url=new_image_url,
|
|
)
|
|
|
|
|
|
async def pin_message(uow: UnitOfWork, chat_id: int, user_id: int, message_id: UUID) -> SMessage:
|
|
async with uow:
|
|
await uow.chat.pin_message(chat_id=chat_id, message_id=message_id, user_id=user_id)
|
|
await uow.commit()
|
|
|
|
pinned_message = await get_message_by_id(uow=uow, message_id=message_id)
|
|
|
|
return pinned_message
|
|
|
|
|
|
async def unpin_message(uow: UnitOfWork, chat_id: int, message_id: UUID) -> None:
|
|
async with uow:
|
|
await uow.chat.unpin_message(chat_id=chat_id, message_id=message_id)
|
|
await uow.commit()
|
|
|
|
|
|
async def get_message_by_id(uow: UnitOfWork, message_id: UUID) -> SMessage:
|
|
async with uow:
|
|
raw_message = await uow.message.get_message_by_id(message_id=message_id)
|
|
message = await _add_avatar_image_and_username_to_message(uow=uow, message=raw_message)
|
|
return message
|
|
|
|
|
|
async def get_pinned_messages(uow: UnitOfWork, chat_id: int) -> SPinnedMessages:
|
|
async with uow:
|
|
pinned_messages_ids = await uow.chat.get_pinned_messages_ids(chat_id=chat_id)
|
|
raw_messages = await uow.message.get_messages_by_ids(messages_ids=pinned_messages_ids)
|
|
|
|
pinned_messages = await _add_avatar_image_and_username_to_message_list(uow=uow, messages=raw_messages)
|
|
return SPinnedMessages.model_validate({"pinned_messages": pinned_messages.messages})
|
|
|
|
|
|
async def get_some_messages(
|
|
uow: UnitOfWork,
|
|
chat_id: int,
|
|
message_number_from: int,
|
|
messages_to_get: int,
|
|
) -> SMessageList:
|
|
async with uow:
|
|
messages = await uow.message.get_some_messages(
|
|
chat_id=chat_id,
|
|
message_number_from=message_number_from,
|
|
messages_to_get=messages_to_get,
|
|
)
|
|
|
|
messages = await _add_avatar_image_and_username_to_message_list(uow=uow, messages=messages)
|
|
return messages
|