From 9eed55164a9d9b90926db8817c9bd7a40257b626 Mon Sep 17 00:00:00 2001 From: htylight Date: Sun, 27 Aug 2023 10:18:57 +0800 Subject: [PATCH] change group chat profile v1 --- src/crud/group_chat_crud.py | 146 ++++++++++++++++++++- src/database/db.py | 2 +- src/main.py | 2 +- src/response_models/group_chat_response.py | 5 + src/routers/group_chat.py | 107 ++++++++++++++- 5 files changed, 250 insertions(+), 12 deletions(-) diff --git a/src/crud/group_chat_crud.py b/src/crud/group_chat_crud.py index f9e71d3..a924ce1 100644 --- a/src/crud/group_chat_crud.py +++ b/src/crud/group_chat_crud.py @@ -1,6 +1,7 @@ import random +from typing import Tuple -from sqlalchemy import select, insert, ScalarResult +from sqlalchemy import select, insert, ScalarResult, update, delete from sqlalchemy.orm.attributes import flag_modified from ..database.db import async_session @@ -33,17 +34,44 @@ async def insert_group_chat(supervisor: str, members: list[str]) -> GroupChat: session.add_all(contact_res.all()) await session.commit() - await session.close() return group_chat_res.one() except Exception as e: - await session.close() raise e + finally: + await session.close() -async def select_member_name_avatar(member_id: str, is_friend: bool): +async def insert_group_chat_members(group_chat_id: str, members: list[str]): + session = async_session() + try: + group_chat: GroupChat = ( + await session.scalars( + select(GroupChat).where(GroupChat.id == group_chat_id) + ) + ).one() + group_chat.members.extend(members) + flag_modified(group_chat, "members") + session.add(group_chat) + + for member in members: + contact: Contact = ( + await session.scalars(select(Contact).where(Contact.user_id == member)) + ).one() + contact.group_chats[group_chat_id] = {"myRemark": "", "nameRemark": ""} + flag_modified(contact, "group_chats") + session.add(contact) + + await session.commit() + except Exception as e: + raise e + finally: + await session.close() + + +async def select_member_name_avatar(member_id: str, is_friend: bool) -> dict | Tuple: session = async_session() if is_friend: - res: ScalarResult[Contact] = await session.scalars( + res: ScalarResult[dict] = await session.scalars( select(Contact.group_chats).where(Contact.user_id == member_id) ) await session.close() @@ -56,5 +84,111 @@ async def select_member_name_avatar(member_id: str, is_friend: bool): .where(UserProfile.user_id == member_id) ) await session.close() - # ('htylight', 'cznowoyn1692502503.png', {'81906574618': {'myRemark': '', 'nameRemark': ''}}) + # ('htylight', 'cznowoyn1692502503.png', {'81906574618': {'myRemark': '', 'nameRemark': ''},}) return res.one() + + +async def select_full_profile(group_chat_id: str) -> Tuple[GroupChat, list[Tuple[str]]]: + session = async_session() + group_chat: GroupChat = ( + await session.scalars(select(GroupChat).where(GroupChat.id == group_chat_id)) + ).one() + members: list[str] = group_chat.members + res = await session.execute( + select( + UserProfile.user_id, + UserProfile.nickname, + UserProfile.avatar, + Contact.group_chats[group_chat_id]["myRemark"], + ) + .join(Contact, UserProfile.user_id == Contact.user_id) + .where(UserProfile.user_id.in_(members)) + ) + + # [ + # ('01H88FWWRFSXMBGM9GYWM060HP', 'test1', None, ''), + # ('01H88EVDZY1R0E267XSB7XGXHG', 'htylight', 'cznowoyn1692502503.png', ''), + # ] + await session.close() + return group_chat, res.all() + + +async def update_group_name(group_chat_id: str, new_name: str): + session = async_session() + try: + await session.execute( + update(GroupChat).values(name=new_name).where(GroupChat.id == group_chat_id) + ) + await session.commit() + except Exception: + raise Exception + finally: + await session.close() + + +async def update_group_intro(group_chat_id: str, new_intro: str): + session = async_session() + try: + await session.execute( + update(GroupChat) + .values(introduction=new_intro) + .where(GroupChat.id == group_chat_id) + ) + await session.commit() + except Exception: + raise Exception + finally: + await session.close() + + +async def update_group_remark(user_id: str, group_chat_id: str, new_remark: str): + session = async_session() + try: + contact: Contact = ( + await session.scalars(select(Contact).where(Contact.user_id == user_id)) + ).one() + contact.group_chats[group_chat_id]["nameRemark"] = new_remark + flag_modified(contact, "group_chats") + session.add(contact) + await session.commit() + except Exception: + raise Exception + finally: + await session.close() + + +async def update_my_remark(user_id: str, group_chat_id: str, new_my_remark: str): + session = async_session() + try: + contact: Contact = ( + await session.scalars(select(Contact).where(Contact.user_id == user_id)) + ).one() + contact.group_chats[group_chat_id]["myRemark"] = new_my_remark + flag_modified(contact, "group_chats") + session.add(contact) + await session.commit() + except Exception: + raise Exception + finally: + await session.close() + + +async def delete_group_chat(group_chat_id: str, members: list[str]): + session = async_session() + try: + await session.execute(delete(GroupChat).where(GroupChat.id == group_chat_id)) + + res: ScalarResult[Contact] = await session.scalars( + select(Contact).where(Contact.user_id.in_(members)) + ) + + for contact in res.all(): + del contact.group_chats[group_chat_id] + flag_modified(contact, "group_chats") + session.add(contact) + + await session.commit() + except Exception: + raise Exception + finally: + await session.close() diff --git a/src/database/db.py b/src/database/db.py index fd0c41b..1398485 100755 --- a/src/database/db.py +++ b/src/database/db.py @@ -1,5 +1,5 @@ from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine db_url = "postgresql+asyncpg://together:togetherno.1@localhost/together" -engine = create_async_engine(db_url) +engine = create_async_engine(db_url, echo=True) async_session = async_sessionmaker(engine, expire_on_commit=False) diff --git a/src/main.py b/src/main.py index 8567db1..98c9395 100755 --- a/src/main.py +++ b/src/main.py @@ -22,7 +22,7 @@ app.include_router(user_account_router, dependencies=[Depends(verify_token)]) app.include_router(search_router, dependencies=[Depends(verify_token)]) app.include_router(apply_router, dependencies=[Depends(verify_token)]) app.include_router(contact_router, dependencies=[Depends(verify_token)]) -app.include_router(group_chat_router) +app.include_router(group_chat_router, dependencies=[Depends(verify_token)]) app.mount("/static", StaticFiles(directory="static"), name="static") diff --git a/src/response_models/group_chat_response.py b/src/response_models/group_chat_response.py index e2de176..c858b69 100644 --- a/src/response_models/group_chat_response.py +++ b/src/response_models/group_chat_response.py @@ -27,3 +27,8 @@ class GroupChatProfileResponse(BaseResponseModel): class MemberNameAvatarResponse(BaseResponseModel): data: _MemberNameAvatar + + +class FullProfileResponse(BaseResponseModel): + groupChat: _GroupChatProfile + memberNameAvatar: dict[str, _MemberNameAvatar] diff --git a/src/routers/group_chat.py b/src/routers/group_chat.py index 9cb0db8..f0117a8 100644 --- a/src/routers/group_chat.py +++ b/src/routers/group_chat.py @@ -3,8 +3,10 @@ from pydantic import BaseModel from ..crud import group_chat_crud from ..response_models.group_chat_response import ( + BaseResponseModel, GroupChatProfileResponse, MemberNameAvatarResponse, + FullProfileResponse, ) router = APIRouter(prefix="/group_chat", tags=["group_chat"]) @@ -15,6 +17,11 @@ class GroupChatCreate(BaseModel): members: list[str] +class GroupChatMembers(BaseModel): + group_chat_id: str + members: list[str] + + @router.post("/create", response_model=GroupChatProfileResponse) async def create_group_chat(group_chat_create: GroupChatCreate): try: @@ -28,8 +35,20 @@ async def create_group_chat(group_chat_create: GroupChatCreate): } except Exception as e: - print(f"Creating Group Chat fail with error: {e}") - return {"code": 9999, "msg": "Server error"} + print(f"Creating Group Chat Fail With Error: {e}") + return {"code": 9999, "msg": "Server Error"} + + +@router.post("/invite_members", response_model=BaseResponseModel) +async def invite_members(member_invitation: GroupChatMembers): + try: + await group_chat_crud.insert_group_chat_members( + **member_invitation.model_dump() + ) + return {"code": 10800, "msg": "Invite Members Successfully"} + except Exception as e: + print(f"Invite members fail with error: {e}") + return {"code": 9999, "msg": "Server Error"} @router.get("/member_name_avatar", response_model=MemberNameAvatarResponse) @@ -37,11 +56,15 @@ async def get_member_name_avatar(group_chat_id: str, member_id: str, is_friend: res = await group_chat_crud.select_member_name_avatar(member_id, is_friend) data = {} if is_friend: - data["remark"] = res[group_chat_id]["myRemark"] + if res.get(group_chat_id): + # make sure my friend is still in this group chat + data["remark"] = res[group_chat_id]["myRemark"] data["nickname"] = "" data["avatar"] = "" else: - data["remark"] = res[2][group_chat_id]["myRemark"] + if len(res) == 3: + # make sure this user is still in this group chat + data["remark"] = res[2][group_chat_id]["myRemark"] data["nickname"] = res[0] data["avatar"] = res[1] @@ -50,3 +73,79 @@ async def get_member_name_avatar(group_chat_id: str, member_id: str, is_friend: "msg": "Get Group Chat Member Name and Avatar Successfully", "data": data, } + + +@router.get("/full_profile", response_model=FullProfileResponse) +async def get_full_profile(group_chat_id: str): + # full profile, includes introduction, noticeboard, group avatar, + # tags, and all members remark, avatar + group_chat, member_name_avatar_list = await group_chat_crud.select_full_profile( + group_chat_id + ) + + member_name_avatar_dict = {} + + for member_name_avatar in member_name_avatar_list: + member_name_avatar_dict[member_name_avatar[0]] = { + "remark": member_name_avatar[3], + "nickname": member_name_avatar[1], + "avatar": member_name_avatar[2] or "", + } + print(group_chat.to_dict()) + print(member_name_avatar_dict) + return { + "code": 10800, + "msg": "Get Group Chat Full Profile Successfully", + "groupChat": group_chat.to_dict(), + "memberNameAvatar": member_name_avatar_dict, + } + + +@router.post("/change_name", response_model=BaseResponseModel) +async def change_name(group_chat_id: str, new_name: str): + try: + await group_chat_crud.update_group_name(group_chat_id, new_name) + return {"code": 10800, "msg": "Change Group Chat Name Successfully"} + except Exception as e: + print(f"Change Group Chat Name Fail With Error: {e}") + return {"code": 9999, "msg": "Server Error"} + + +@router.post("/change_intro", response_model=BaseResponseModel) +async def change_intro(group_chat_id: str, new_intro: str): + try: + await group_chat_crud.update_group_intro(group_chat_id, new_intro) + return {"code": 10800, "msg": "Change Group Chat Intro Successfully"} + except Exception as e: + print(f"Change Group Chat Intro Fail With Error: {e}") + return {"code": 9999, "msg": "Server Error"} + + +@router.post("/change_remark", response_model=BaseResponseModel) +async def change_name_remark(user_id: str, group_chat_id: str, new_remark: str): + try: + await group_chat_crud.update_group_remark(user_id, group_chat_id, new_remark) + return {"code": 10800, "msg": "Change Group Chat Remark Successfully"} + except Exception as e: + print(f"Change Group Chat Remark Fail With Error: {e}") + return {"code": 9999, "msg": "Server Error"} + + +@router.post("/change_my_remark", response_model=BaseResponseModel) +async def change_my_remark(user_id: str, group_chat_id: str, new_my_remark: str): + try: + await group_chat_crud.update_my_remark(user_id, group_chat_id, new_my_remark) + return {"code": 10800, "msg": "Change My Nickname in Group Chat Successfully"} + except Exception as e: + print(f"Change Group Chat My Nickname in Group Chat Fail With Error: {e}") + return {"code": 9999, "msg": "Server Error"} + + +@router.post("/delete", response_model=BaseResponseModel) +async def delete_group_chat(deletion: GroupChatMembers): + try: + await group_chat_crud.delete_group_chat(**deletion.model_dump()) + return {"code": 10800, "msg": "Delete Group Chat Successfully"} + except Exception as e: + print(f"Delete Group Chat Fail With Error: {e}") + return {"code": 9999, "msg": "Server Error"}