Рефакторинг

This commit is contained in:
urec56 2024-05-06 21:21:11 +05:00
parent 73791c3184
commit d9ae2836b3
4 changed files with 81 additions and 25 deletions

View file

@ -0,0 +1,25 @@
from app.users.chat.dao import ChatDAO
from app.users.chat.shemas import SMessage
class MessageService:
@staticmethod
async def send_message(user_id: int, chat_id: int, message: str, image_url: str | None = None) -> SMessage:
new_message = await ChatDAO.send_message(user_id=user_id, chat_id=chat_id, message=message, image_url=image_url)
return new_message
@staticmethod
async def add_answer(self_id: int, answer_id: int) -> SMessage:
new_message = await ChatDAO.add_answer(self_id=self_id, answer_id=answer_id)
return new_message
@staticmethod
async def delete_message(message_id: int) -> bool:
new_message = await ChatDAO.delete_message(message_id=message_id)
return new_message
@staticmethod
async def edit_message(message_id: int, new_message: str, new_image_url: str) -> bool:
new_message = await ChatDAO.edit_message(message_id=message_id, new_message=new_message,
new_image_url=new_image_url)
return new_message

View file

@ -3,6 +3,7 @@ from sqlalchemy import insert, select, update, and_, delete
from app.dao.base import BaseDAO from app.dao.base import BaseDAO
from app.database import async_session_maker, engine # noqa from app.database import async_session_maker, engine # noqa
from app.exceptions import UserAlreadyInChatException, UserAlreadyPinnedChatException from app.exceptions import UserAlreadyInChatException, UserAlreadyPinnedChatException
from app.users.chat.shemas import SMessage
from app.users.models import Users from app.users.models import Users
from app.users.chat.models import Chats, Messages, UsersXChats, PinnedChats, PinnedMessages, Answers from app.users.chat.models import Chats, Messages, UsersXChats, PinnedChats, PinnedMessages, Answers
@ -33,7 +34,7 @@ class ChatDAO(BaseDAO):
return True return True
@staticmethod @staticmethod
async def send_message(user_id: int, chat_id: int, message: str, image_url: str | None = None) -> list[dict]: async def send_message(user_id: int, chat_id: int, message: str, image_url: str | None = None) -> SMessage:
inserted_image = ( inserted_image = (
insert(Messages).values(chat_id=chat_id, user_id=user_id, message=message, image_url=image_url) insert(Messages).values(chat_id=chat_id, user_id=user_id, message=message, image_url=image_url)
.returning(Messages.id, Messages.message, Messages.image_url, Messages.chat_id, .returning(Messages.id, Messages.message, Messages.image_url, Messages.chat_id,
@ -49,7 +50,8 @@ class ChatDAO(BaseDAO):
async with async_session_maker() as session: async with async_session_maker() as session:
result = await session.execute(query) result = await session.execute(query)
await session.commit() await session.commit()
return result.mappings().all() result = result.mappings().one()
return SMessage.model_validate(result, from_attributes=True)
@staticmethod @staticmethod
async def get_message_by_id(message_id: int): async def get_message_by_id(message_id: int):
@ -127,9 +129,10 @@ class ChatDAO(BaseDAO):
return True return True
@staticmethod @staticmethod
async def add_answer(self_id: int, answer_id: int) -> list[dict]: async def add_answer(self_id: int, answer_id: int) -> SMessage:
answer = (insert(Answers).values(self_id=self_id, answer_id=answer_id) answer = (insert(Answers).values(self_id=self_id, answer_id=answer_id)
.returning(Answers.self_id, Answers.answer_id).cte("answer")) .returning(Answers.self_id, Answers.answer_id).cte("answer"))
query = (select(Messages.id, Messages.message, Messages.image_url, query = (select(Messages.id, Messages.message, Messages.image_url,
Messages.chat_id, Messages.user_id, Messages.created_at, Messages.chat_id, Messages.user_id, Messages.created_at,
Users.avatar_image, Users.username, Users.avatar_hex, answer.c.self_id, answer.c.answer_id) Users.avatar_image, Users.username, Users.avatar_hex, answer.c.self_id, answer.c.answer_id)
@ -137,10 +140,12 @@ class ChatDAO(BaseDAO):
.join(Users, Users.id == Messages.user_id) .join(Users, Users.id == Messages.user_id)
.join(answer, answer.c.answer_id == Messages.id, isouter=True) .join(answer, answer.c.answer_id == Messages.id, isouter=True)
.where(Messages.id == answer_id)) .where(Messages.id == answer_id))
async with async_session_maker() as session: async with async_session_maker() as session:
result = await session.execute(query) result = await session.execute(query)
await session.commit() await session.commit()
return result.mappings().all() result = result.scalar_one()
return SMessage.model_validate(result)
@staticmethod @staticmethod
async def delete_chat(chat_id: int) -> bool: async def delete_chat(chat_id: int) -> bool:
@ -256,7 +261,8 @@ class ChatDAO(BaseDAO):
query = (select(Messages.id, Messages.message, Messages.image_url, query = (select(Messages.id, Messages.message, Messages.image_url,
Messages.chat_id, Messages.user_id, Messages.chat_id, Messages.user_id,
Messages.created_at, Users.avatar_image, Messages.created_at, Users.avatar_image,
Users.username, Users.avatar_hex, Answers.self_id, Answers.answer_id).select_from(PinnedMessages) Users.username, Users.avatar_hex, Answers.self_id, Answers.answer_id).select_from(
PinnedMessages)
.join(Messages, PinnedMessages.message_id == Messages.id, isouter=True) .join(Messages, PinnedMessages.message_id == Messages.id, isouter=True)
.join(Users, PinnedMessages.user_id == Users.id, isouter=True) .join(Users, PinnedMessages.user_id == Users.id, isouter=True)
.join(Answers, Answers.self_id == Messages.id, isouter=True) .join(Answers, Answers.self_id == Messages.id, isouter=True)

View file

@ -1,3 +1,5 @@
from datetime import datetime
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
@ -10,7 +12,7 @@ class SMessage(BaseModel):
chat_id: int chat_id: int
user_id: int user_id: int
username: str username: str
created_at: str created_at: datetime
avatar_image: str avatar_image: str
avatar_hex: str avatar_hex: str
self_id: int | None self_id: int | None
@ -57,5 +59,19 @@ class SChat(BaseModel):
class SSendMessage(BaseModel): class SSendMessage(BaseModel):
flag: str flag: str
message: str message: str
image_url: str image_url: str | None
answer: int | None answer: int | None
class SDeleteMessage(BaseModel):
flag: str
user_id: int
id: int
class SEditMessage(BaseModel):
flag: str
user_id: int
id: int
new_message: str
new_image_url: str

View file

@ -1,10 +1,10 @@
from fastapi import WebSocket, WebSocketDisconnect from fastapi import WebSocket, WebSocketDisconnect
from app.exceptions import IncorrectDataException, UserDontHavePermissionException from app.exceptions import IncorrectDataException, UserDontHavePermissionException
from app.users.chat.dao import ChatDAO from app.services.message_service import MessageService
from app.users.auth import validate_user_access_to_chat, check_verificated_user_with_exc from app.users.auth import validate_user_access_to_chat, check_verificated_user_with_exc
from app.users.chat.router import router from app.users.chat.router import router
from app.users.chat.shemas import SSendMessage from app.users.chat.shemas import SSendMessage, SMessage, SDeleteMessage, SEditMessage
class ConnectionManager(WebSocket): class ConnectionManager(WebSocket):
@ -28,20 +28,28 @@ class ConnectionManager(WebSocket):
message = SSendMessage.model_validate(message) message = SSendMessage.model_validate(message)
new_message = await self.add_message_to_database(user_id=user_id, chat_id=chat_id, message=message) new_message = await self.add_message_to_database(user_id=user_id, chat_id=chat_id, message=message)
new_message = dict(new_message) new_message = new_message.model_dump()
new_message["created_at"] = new_message["created_at"].isoformat() new_message["created_at"] = new_message["created_at"].isoformat()
new_message["flag"] = "send" new_message["flag"] = "send"
elif message["flag"] == "delete": elif message["flag"] == "delete":
if message["user_id"] != user_id: message = SDeleteMessage.model_validate(message)
if message.user_id != user_id:
raise UserDontHavePermissionException raise UserDontHavePermissionException
deleted_message = await self.delete_message(message["id"])
new_message = {"deleted_message": deleted_message, "id": message["id"], "flag": "delete"} deleted_message = await self.delete_message(message.id)
new_message = {"deleted_message": deleted_message, "id": message.id, "flag": "delete"}
elif message["flag"] == "edit": elif message["flag"] == "edit":
if message["user_id"] != user_id: message = SEditMessage.model_validate(message)
if message.user_id != user_id:
raise UserDontHavePermissionException raise UserDontHavePermissionException
edited_message = await self.edit_message(message["id"], message["new_message"], message["new_image_url"])
new_message = {"edited_message": edited_message, "flag": "edit", "id": message["id"], edited_message = await self.edit_message(message.id, message.new_message, message.new_image_url)
"new_message": message["new_message"], "new_image_url": message["new_image_url"]} new_message = {"edited_message": edited_message, "flag": "edit", "id": message.id,
"new_message": message.new_message, "new_image_url": message.new_image_url}
else: else:
raise IncorrectDataException raise IncorrectDataException
@ -49,21 +57,23 @@ class ConnectionManager(WebSocket):
await websocket.send_json(new_message) await websocket.send_json(new_message)
@staticmethod @staticmethod
async def add_message_to_database(user_id: int, chat_id: int, message: SSendMessage) -> dict: async def add_message_to_database(user_id: int, chat_id: int, message: SSendMessage) -> SMessage:
new_message = await ChatDAO.send_message( new_message = await MessageService.send_message(
user_id=user_id, chat_id=chat_id, message=message.message, image_url=message.image_url) user_id=user_id, chat_id=chat_id, message=message.message, image_url=message.image_url
)
if message.answer: if message.answer:
new_message = await ChatDAO.add_answer(self_id=new_message[0]["id"], answer_id=message.answer) new_message = await MessageService.add_answer(self_id=new_message.id, answer_id=message.answer)
return new_message[0] return new_message
@staticmethod @staticmethod
async def delete_message(message_id: int) -> bool: async def delete_message(message_id: int) -> bool:
new_message = await ChatDAO.delete_message(message_id) new_message = await MessageService.delete_message(message_id)
return new_message return new_message
@staticmethod @staticmethod
async def edit_message(message_id: int, new_message: str, image_url: str) -> bool: async def edit_message(message_id: int, new_message: str, image_url: str) -> bool:
new_message = await ChatDAO.edit_message(message_id=message_id, new_message=new_message, new_image_url=image_url) new_message = await MessageService.edit_message(message_id=message_id, new_message=new_message,
new_image_url=image_url)
return new_message return new_message
@ -82,4 +92,3 @@ async def websocket_endpoint(chat_id: int, user_id: int, websocket: WebSocket):
await manager.broadcast(user_id=user_id, chat_id=chat_id, message=data) await manager.broadcast(user_id=user_id, chat_id=chat_id, message=data)
except WebSocketDisconnect: except WebSocketDisconnect:
manager.disconnect(chat_id, websocket) manager.disconnect(chat_id, websocket)