Добавдены закрепы чатов и сообщений в чатах, работа с ними

This commit is contained in:
urec56 2024-02-27 19:19:39 +03:00
parent 049931eb7e
commit 37c7691939
7 changed files with 226 additions and 7 deletions

View file

@ -0,0 +1,40 @@
"""Изменение таблицы закрепов сообщений
Revision ID: 1c938458adf8
Revises: 1a744c9167b9
Create Date: 2024-02-27 18:52:07.747871
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '1c938458adf8'
down_revision: Union[str, None] = '1a744c9167b9'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_foreign_key(None, 'pinnedchats', 'users', ['user_id'], ['id'])
op.create_foreign_key(None, 'pinnedchats', 'chats', ['chat_id'], ['id'])
op.add_column('pinnedmessages', sa.Column('user_id', sa.Integer(), nullable=False))
op.create_foreign_key(None, 'pinnedmessages', 'chats', ['chat_id'], ['id'])
op.create_foreign_key(None, 'pinnedmessages', 'users', ['user_id'], ['id'])
op.create_foreign_key(None, 'pinnedmessages', 'messages', ['message_id'], ['id'])
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'pinnedmessages', type_='foreignkey')
op.drop_constraint(None, 'pinnedmessages', type_='foreignkey')
op.drop_constraint(None, 'pinnedmessages', type_='foreignkey')
op.drop_column('pinnedmessages', 'user_id')
op.drop_constraint(None, 'pinnedchats', type_='foreignkey')
op.drop_constraint(None, 'pinnedchats', type_='foreignkey')
# ### end Alembic commands ###

View file

@ -0,0 +1,30 @@
"""Изменение таблицы закрепов сообщений
Revision ID: 2a201d58011b
Revises: 1c938458adf8
Create Date: 2024-02-27 19:05:46.510556
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '2a201d58011b'
down_revision: Union[str, None] = '1c938458adf8'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###

View file

@ -0,0 +1,30 @@
"""Изменение таблицы закрепов сообщений
Revision ID: e9b02df6e778
Revises: 2a201d58011b
Create Date: 2024-02-27 19:19:00.994364
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'e9b02df6e778'
down_revision: Union[str, None] = '2a201d58011b'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###

View file

@ -4,7 +4,7 @@ from app.dao.base import BaseDAO
from app.database import async_session_maker
from app.exceptions import UserAlreadyInChatException
from app.users.models import Users
from app.users.chat.models import Chats, Messages, UsersXChats
from app.users.chat.models import Chats, Messages, UsersXChats, PinnedChats, PinnedMessages
class ChatDAO(BaseDAO):
@ -122,3 +122,72 @@ class ChatDAO(BaseDAO):
await session.execute(query)
await session.commit()
return True
@staticmethod
async def pinn_chat(chat_id: int, user_id: int):
query = insert(PinnedChats).values(chat_id=chat_id, user_id=user_id)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def unpinn_chat(chat_id: int, user_id: int):
query = delete(PinnedChats).where(PinnedChats.chat_id == chat_id, PinnedChats.user_id == user_id)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def get_pinned_chats(user_id: int):
query = (select(Chats.__table__.columns).select_from(PinnedChats)
.join(Chats, PinnedChats.chat_id == Chats.id, isouter=True)
.where(PinnedChats.user_id == user_id))
async with async_session_maker() as session:
result = await session.execute(query)
result = result.mappings().all()
return result
@staticmethod
async def pinn_message(chat_id: int, message_id: int, user_id: int):
query = insert(PinnedMessages).values(chat_id=chat_id, message_id=message_id, user_id=user_id)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def get_message_pinner(chat_id: int, message_id: int):
query = select(PinnedMessages.user_id).where(
PinnedMessages.chat_id == chat_id, PinnedMessages.message_id == message_id
)
async with async_session_maker() as session:
result = await session.execute(query)
result = result.scalar()
return result
@staticmethod
async def unpinn_message(chat_id: int, message_id: int):
query = delete(PinnedMessages).where(
PinnedMessages.chat_id == chat_id, PinnedMessages.message_id == message_id
)
async with async_session_maker() as session:
await session.execute(query)
await session.commit()
return True
@staticmethod
async def get_pinned_messages(chat_id: int):
query = (select(Messages.message, Messages.image_url,
Messages.chat_id, Messages.user_id,
Messages.created_at, Users.avatar_image,
Users.username).select_from(PinnedMessages)
.join(Messages, PinnedMessages.message_id == Messages.id, isouter=True)
.join(Users, PinnedMessages.user_id == Users.id, isouter=True)
.where(PinnedMessages.chat_id == chat_id)
.order_by(Messages.created_at.desc()))
async with async_session_maker() as session:
result = await session.execute(query)
result = result.mappings().all()
return result

View file

@ -20,6 +20,8 @@ class Chats(Base):
usersxchats = relationship("UsersXChats", back_populates="chat")
user_to_exclude = relationship("Users", primaryjoin='Chats.chat_for == Users.id', back_populates="chat")
user_who_create = relationship("Users", primaryjoin='Chats.created_by == Users.id', back_populates="creator")
pinned_messages = relationship("PinnedMessages", back_populates="chat")
pinned_chats = relationship("PinnedChats", back_populates="chat")
def __str__(self):
return f"Чат #{self.id}. Виден: {self.visibility}. Сделан {self.created_by} для {self.chat_for}"
@ -38,6 +40,7 @@ class Messages(Base):
chat = relationship("Chats", back_populates="message")
user = relationship("Users", back_populates="message")
pinned_messages = relationship("PinnedMessages", back_populates="message")
def __str__(self):
return f"#{self.id} {self.message} от {self.user_id}. Написано {self.created_at}"
@ -61,13 +64,21 @@ class PinnedMessages(Base):
__tablename__ = "pinnedmessages"
id: Mapped[int] = mapped_column(primary_key=True)
chat_id: Mapped[int]
message_id: Mapped[int]
chat_id: Mapped[int] = mapped_column(ForeignKey("chats.id"))
message_id: Mapped[int] = mapped_column(ForeignKey("messages.id"))
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
chat = relationship("Chats", back_populates="pinned_messages")
message = relationship("Messages", back_populates="pinned_messages")
user = relationship("Users", back_populates="pinned_messages")
class PinnedChats(Base):
__tablename__ = "pinnedchats"
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int]
chat_id: Mapped[int]
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
chat_id: Mapped[int] = mapped_column(ForeignKey("chats.id"))
chat = relationship("Chats", back_populates="pinned_chats")
user = relationship("Users", back_populates="pinned_chats")

View file

@ -133,5 +133,42 @@ async def delete_user(chat_id: int, user_id: int, user: Users = Depends(get_curr
@router.post("/pinn_chat")
async def pinn_chat():
pass
async def pinn_chat(chat_id: int, user: Users = Depends(get_current_user)):
await validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
await ChatDAO.pinn_chat(chat_id=chat_id, user_id=user.id)
return {'pinned_chat': chat_id, 'user_id': user.id}
@router.delete("/unpinn_chat")
async def unpinn_chat(chat_id: int, user: Users = Depends(get_current_user)):
await validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
await ChatDAO.unpinn_chat(chat_id=chat_id, user_id=user.id)
return {'unpinned_chat': chat_id, 'user_id': user.id}
@router.get("/get_pinned_chats")
async def get_pinned_chats(user: Users = Depends(get_current_user)):
return await ChatDAO.get_pinned_chats(user_id=user.id)
@router.post("/pinn_message")
async def pinn_message(chat_id: int, message_id: int, user: Users = Depends(get_current_user)):
await validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
await ChatDAO.pinn_message(chat_id=chat_id, message_id=message_id, user_id=user.id)
return {'pinned_message': message_id, 'user_id': user.id}
@router.delete("/unpinn_message")
async def unpinn_message(chat_id: int, message_id: int, user: Users = Depends(get_current_user)):
await validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
message_pinner = await ChatDAO.get_message_pinner(chat_id=chat_id, message_id=message_id)
if message_pinner == user.id:
await ChatDAO.unpinn_message(chat_id=chat_id, message_id=message_id)
return {'message_id': message_id, 'user_id': user.id, 'chat_id': chat_id}
raise UserDontHavePermissionException
@router.get("/pinned_messages/{chat_id}")
async def pinned_messages(chat_id: int, user: Users = Depends(get_current_user)):
await validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
return await ChatDAO.get_pinned_messages(chat_id=chat_id)

View file

@ -27,6 +27,8 @@ class Users(Base):
chat = relationship("Chats", primaryjoin='Chats.chat_for == Users.id', back_populates="user_to_exclude")
creator = relationship("Chats", primaryjoin='Chats.created_by == Users.id', back_populates="user_who_create")
verificationcode = relationship("UsersVerificationCodes", back_populates="user")
pinned_messages = relationship("PinnedMessages", back_populates="user")
pinned_chats = relationship("PinnedChats", back_populates="user")
def __str__(self):
return f"Юзер {self.username}"