chat_back/app/services/chat_service.py

124 lines
4.9 KiB
Python

from datetime import timedelta
from urllib.parse import urljoin
from pydantic import ValidationError
from app.chat.exceptions import UserDontHavePermissionException, UserCanNotReadThisChatException
from app.chat.shemas import SAllowedChats, SChangeData, SPinnedChats, SChat
from app.config import settings
from app.services.redis_service import RedisService
from app.services import user_service, auth_service
from app.utils.unit_of_work import UnitOfWork
from app.users.schemas import SInvitationData
async def find_chat(uow: UnitOfWork, chat_id: int, user_id: int) -> SChat:
async with uow:
chat = await uow.chat.find_chat(chat_id=chat_id, user_id=user_id)
return chat
async def find_one(uow: UnitOfWork, chat_id: int) -> SChat:
async with uow:
chat = await uow.chat.find_one(chat_id=chat_id)
return chat
async def get_all_chats(uow: UnitOfWork, user_id: int) -> SAllowedChats:
try:
async with RedisService() as redis:
allowed_chats = await redis.get_value(key=f"user_allowed_chats: {user_id}", model=SAllowedChats)
return allowed_chats
except ValidationError:
async with uow:
allowed_chats = await uow.user.get_user_allowed_chats(user_id=user_id)
async with RedisService() as redis:
await redis.set_key(
key=f"user_allowed_chats: {user_id}",
expire_time=timedelta(minutes=30),
value=allowed_chats.model_dump_json(),
)
return allowed_chats
async def create_chat(uow: UnitOfWork, user_id: int, user_to_exclude_id: int, chat_name: str) -> int:
if user_id == user_to_exclude_id:
raise UserCanNotReadThisChatException
user_chat_for = await user_service.find_user(uow=uow, id=user_to_exclude_id)
async with uow:
chat_id = await uow.chat.create_chat(
user_id=user_to_exclude_id,
chat_name=chat_name,
created_by=user_id,
avatar_image=user_chat_for.avatar_image,
)
await uow.chat.add_user_to_chat(user_id, chat_id)
if user_id != settings.ADMIN_USER_ID:
await uow.chat.add_user_to_chat(settings.ADMIN_USER_ID, chat_id)
async with RedisService(is_raise=True) as redis:
await redis.delete_key(key=f"user_allowed_chats: {user_id}")
await uow.commit()
return chat_id
async def change_chat_data(uow: UnitOfWork, user_id: int, user_data: SChangeData) -> None:
chat = await find_chat(uow=uow, chat_id=user_data.chat_id, user_id=user_id)
if chat.created_by != user_id:
raise UserDontHavePermissionException
async with uow:
await uow.chat.change_data(
chat_id=user_data.chat_id,
chat_name=user_data.chat_name,
avatar_image=user_data.avatar_image,
)
async with RedisService(is_raise=True) as redis:
await redis.delete_key(key=f"user_allowed_chats: {user_id}")
await uow.commit()
def create_invitation_link(chat_id: int) -> str:
invitation_data = SInvitationData.model_validate({"chat_id": chat_id})
invitation_token = auth_service.encode_invitation_token(invitation_data)
invitation_link = urljoin(settings.INVITATION_LINK_HOST, f"/submitNewChat#code={invitation_token}")
return invitation_link
async def invite_to_chat(uow: UnitOfWork, user_id: int, invitation_token: str) -> None:
invitation_data = auth_service.decode_invitation_token(invitation_token)
chat = await find_one(uow=uow, chat_id=invitation_data.chat_id)
if user_id == chat.chat_for:
raise UserCanNotReadThisChatException
async with uow:
await uow.chat.add_user_to_chat(chat_id=invitation_data.chat_id, user_id=user_id)
async with RedisService(is_raise=True) as redis:
await redis.delete_key(key=f"user_allowed_chats: {user_id}")
await uow.commit()
async def delete_chat(uow: UnitOfWork, user_id: int, chat_id: int) -> None:
chat = await find_chat(uow=uow, chat_id=chat_id, user_id=user_id)
if not user_id == chat.created_by:
raise UserDontHavePermissionException
async with uow:
await uow.chat.delete_chat(chat_id)
async with RedisService(is_raise=True) as redis:
await redis.delete_key(key=f"user_allowed_chats: {user_id}")
await uow.commit()
async def delete_user_from_chat(uow: UnitOfWork, user_id: int, chat_id: int, user_id_for_delete: int) -> None:
chat = await find_chat(uow=uow, chat_id=chat_id, user_id=user_id)
if not user_id == chat.created_by:
raise UserDontHavePermissionException
async with uow:
await uow.chat.delete_user_from_chat(chat_id=chat_id, user_id=user_id_for_delete)
async with RedisService(is_raise=True) as redis:
await redis.delete_key(key=f"user_allowed_chats: {user_id_for_delete}")
await uow.commit()
async def pin_chat(uow: UnitOfWork, user_id: int, chat_id: int) -> None:
async with uow:
await uow.chat.pin_chat(chat_id=chat_id, user_id=user_id)
await uow.commit()
async def unpin_chat(uow: UnitOfWork, user_id: int, chat_id: int) -> None:
async with uow:
await uow.chat.unpin_chat(chat_id=chat_id, user_id=user_id)
await uow.commit()
async def get_pinned_chats(uow: UnitOfWork, user_id: int) -> SPinnedChats:
async with uow:
pinned_chats = await uow.chat.get_pinned_chats(user_id=user_id)
return pinned_chats