mirror of
https://github.com/lorsanstand/Aether.git
synced 2026-06-19 12:05:16 +03:00
Add edit message
This commit is contained in:
@@ -77,7 +77,7 @@ class MessageDAO(BaseDAO[MessageModel, MessageCreateDB, MessageUpdateDB]):
|
||||
model = MessageModel
|
||||
|
||||
@classmethod
|
||||
async def find_all_asc(
|
||||
async def find_all_desc(
|
||||
cls,
|
||||
session: AsyncSession,
|
||||
offset: Optional[int],
|
||||
@@ -85,7 +85,7 @@ class MessageDAO(BaseDAO[MessageModel, MessageCreateDB, MessageUpdateDB]):
|
||||
*filter,
|
||||
**filter_by
|
||||
) -> List[MessageModel]:
|
||||
stmt = select(MessageModel).filter(*filter).filter_by(**filter_by).order_by(MessageModel.created_at.asc())
|
||||
stmt = select(MessageModel).filter(*filter).filter_by(**filter_by).order_by(MessageModel.created_at.desc())
|
||||
|
||||
if offset is not None:
|
||||
stmt = stmt.offset(offset)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import uuid
|
||||
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from sqlalchemy import ForeignKey, UUID, UniqueConstraint
|
||||
from sqlalchemy import ForeignKey, UUID, UniqueConstraint, text
|
||||
|
||||
from app.core.database import Base
|
||||
|
||||
@@ -14,6 +14,7 @@ class MessageModel(Base):
|
||||
chat_id: Mapped[uuid.UUID] = mapped_column(UUID, ForeignKey("chat.id", ondelete="CASCADE"), index=True)
|
||||
content: Mapped[str] = mapped_column()
|
||||
is_read: Mapped[bool] = mapped_column(default=False)
|
||||
is_edited: Mapped[bool] = mapped_column(default=False, server_default=text("false"))
|
||||
|
||||
|
||||
class ChatModel(Base):
|
||||
|
||||
@@ -6,7 +6,7 @@ from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect
|
||||
from app.chats.service import ChatService
|
||||
from app.auth.dependencies import get_current_verified_user
|
||||
from app.users.models import UserModel
|
||||
from app.chats.schemas import Chat, MessageCreate, Message
|
||||
from app.chats.schemas import Chat, MessageCreate, Message, MessageUpdate
|
||||
|
||||
router = APIRouter(prefix="/chats", tags=["chats"])
|
||||
|
||||
@@ -19,7 +19,7 @@ async def get_chats(
|
||||
return await ChatService.get_chats(user, offset, limit)
|
||||
|
||||
@router.get("/{chat_id}")
|
||||
async def get_chat(
|
||||
async def get_messages(
|
||||
chat_id: uuid.UUID,
|
||||
offset: int = 0,
|
||||
limit: int = 10,
|
||||
@@ -31,6 +31,10 @@ async def get_chat(
|
||||
async def send_message(message: MessageCreate, user: UserModel = Depends(get_current_verified_user)) -> Message:
|
||||
return await ChatService.send_message(user, message)
|
||||
|
||||
@router.put("/message")
|
||||
async def edit_message(message_update: MessageUpdate, user: UserModel = Depends(get_current_verified_user)) -> Message:
|
||||
return await ChatService.update_message(user, message_update)
|
||||
|
||||
|
||||
@router.websocket("/ws")
|
||||
async def websocket_endpoint(ws: WebSocket, user: UserModel = Depends(get_current_verified_user)):
|
||||
|
||||
@@ -2,7 +2,7 @@ from datetime import datetime
|
||||
from typing import Optional
|
||||
import uuid
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
|
||||
class MessageCreate(BaseModel):
|
||||
@@ -21,10 +21,13 @@ class MessageCreateDB(BaseModel):
|
||||
chat_id: Optional[uuid.UUID]
|
||||
content: Optional[str]
|
||||
is_read: Optional[bool] = False
|
||||
is_edited: Optional[bool] = False
|
||||
|
||||
|
||||
class MessageUpdateDB(BaseModel):
|
||||
content: Optional[str]
|
||||
is_edited: Optional[bool] = False
|
||||
|
||||
|
||||
|
||||
class Message(BaseModel):
|
||||
@@ -32,9 +35,12 @@ class Message(BaseModel):
|
||||
sender_id: int
|
||||
chat_id: uuid.UUID
|
||||
content: str
|
||||
is_edited: Optional[bool] = False
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class ChatBase(BaseModel):
|
||||
is_group: Optional[bool] = False
|
||||
|
||||
@@ -9,7 +9,7 @@ from sqlalchemy import and_
|
||||
from app.core.database import async_session_maker
|
||||
from app.chats.dao import ChatDAO, MessageDAO, ParticipantDAO
|
||||
from app.chats.models import ChatModel, MessageModel, ParticipantModel
|
||||
from app.chats.schemas import Chat, MessageCreate, MessageCreateDB, ChatCreateDB, ParticipantCreateDB, Message
|
||||
from app.chats.schemas import Chat, MessageCreate, MessageCreateDB, ChatCreateDB, ParticipantCreateDB, Message, MessageUpdateDB, MessageUpdate
|
||||
from app.users.models import UserModel
|
||||
from app.core.redis import get_redis
|
||||
|
||||
@@ -92,14 +92,7 @@ class ChatService:
|
||||
)
|
||||
)
|
||||
|
||||
await cls._send_ws_message(members_ids, Message(
|
||||
id=message_db.id,
|
||||
sender_id=message_db.sender_id,
|
||||
chat_id=message_db.chat_id,
|
||||
content=message_db.content,
|
||||
created_at=message_db.created_at,
|
||||
updated_at=message_db.updated_at
|
||||
))
|
||||
await cls._send_ws_message(members_ids, Message.model_validate(message_db))
|
||||
|
||||
await ChatDAO.update(
|
||||
session,
|
||||
@@ -124,7 +117,7 @@ class ChatService:
|
||||
log.warning("Access denied to chat", extra={"user_id": user.id, "chat_id": chat_id})
|
||||
raise HTTPException(status.HTTP_403_FORBIDDEN, detail="Access denied")
|
||||
|
||||
messages = await MessageDAO.find_all_asc(
|
||||
messages = await MessageDAO.find_all_desc(
|
||||
session,
|
||||
offset,
|
||||
limit,
|
||||
@@ -180,4 +173,45 @@ class ChatService:
|
||||
"message": message.model_dump(mode='json')
|
||||
}
|
||||
await redis_client.publish("messenger_updates", json.dumps(payload))
|
||||
log.debug(f"Published message for user_id: {user_id}")
|
||||
log.debug(f"Published message for user_id: {user_id}")
|
||||
|
||||
|
||||
@classmethod
|
||||
async def update_message(cls, user: UserModel, message_update: MessageUpdate) -> Message:
|
||||
async with async_session_maker() as session:
|
||||
message_exist = await MessageDAO.find_one_or_none(
|
||||
session,
|
||||
and_(
|
||||
MessageModel.id==message_update.id,
|
||||
MessageModel.sender_id==user.id
|
||||
)
|
||||
)
|
||||
|
||||
if message_exist is None:
|
||||
log.warning("Message not found", extra={"user_id": user.id, "message_id": message_update.id})
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Message not found")
|
||||
|
||||
|
||||
message_update_db = await MessageDAO.update(
|
||||
session,
|
||||
MessageModel.id==message_update.id,
|
||||
obj_in=MessageUpdateDB(
|
||||
content=message_update.content,
|
||||
is_edited=True
|
||||
)
|
||||
)
|
||||
|
||||
members = await ParticipantDAO.find_all(
|
||||
session,
|
||||
None,
|
||||
None,
|
||||
ParticipantModel.chat_id==message_exist.chat_id
|
||||
)
|
||||
|
||||
member_ids = [member.user_id for member in members]
|
||||
|
||||
await cls._send_ws_message(member_ids, Message.model_validate(message_update_db))
|
||||
|
||||
await session.commit()
|
||||
log.info("Message update successfully", extra={"user_id": user.id, "message_id": message_update.id})
|
||||
return message_update_db
|
||||
|
||||
Reference in New Issue
Block a user