diff --git a/resolvers/chats.py b/resolvers/chats.py index 2a12c4d..aff8d87 100644 --- a/resolvers/chats.py +++ b/resolvers/chats.py @@ -1,11 +1,10 @@ import json import time import uuid -from typing import List from models.chat import Chat, ChatUpdate -from models.member import ChatMember from services.auth import login_required +from services.core import authors_by_user from services.presence import notify_chat from services.rediscache import redis from services.schema import mutation @@ -22,7 +21,9 @@ async def update_chat(_, info, chat_new: ChatUpdate): :param chat_new: dict with chat data :return: Result { error chat } """ - author_id = info.context["author_id"] + user_id = info.context["user_id"] + author = authors_by_user[user_id] + author_id = author["id"] chat_id = chat_new["id"] chat_str = await redis.execute("GET", f"chats/{chat_id}") if not chat_str: @@ -51,45 +52,48 @@ async def update_chat(_, info, chat_new: ChatUpdate): @login_required async def create_chat(_, info, title="", members=None): members = members or [] - print("create_chat context: %r" % info.context) - author_id = info.context["author_id"] print("create_chat members: %r" % members) - if author_id not in members: - members.append(int(author_id)) + print("create_chat context: %r" % info.context) + user_id = info.context["user_id"] + author = authors_by_user[user_id] + author_id = author["id"] + if author_id: + if author_id not in members: + members.append(int(author_id)) - # NOTE: private chats has no title - # reuse private chat created before if exists - if len(members) == 2 and title == "": - chatset1 = set((await redis.execute("SMEMBERS", f"chats_by_author/{members[0]}")) or []) - chatset2 = set((await redis.execute("SMEMBERS", f"chats_by_author/{members[1]}")) or []) - for c in chatset1.intersection(chatset2): - chat_data = await redis.execute("GET", f"chats/{c}") - if chat_data: - chat = json.loads(chat_data) - if chat["title"] == "": - print("[inbox] createChat found old chat") - return {"chat": chat, "error": "existed"} + # NOTE: private chats has no title + # reuse private chat created before if exists + if len(members) == 2 and title == "": + chatset1 = set((await redis.execute("SMEMBERS", f"chats_by_author/{members[0]}")) or []) + chatset2 = set((await redis.execute("SMEMBERS", f"chats_by_author/{members[1]}")) or []) + for c in chatset1.intersection(chatset2): + chat_data = await redis.execute("GET", f"chats/{c}") + if chat_data: + chat = json.loads(chat_data) + if chat["title"] == "": + print("[inbox] createChat found old chat") + return {"chat": chat, "error": "existed"} - chat_id = str(uuid.uuid4()) - chat: Chat = { - "id": chat_id, - "members": members, - "title": title, - "description": "", - "created_by": author_id, - "created_at": int(time.time()), - "updated_at": int(time.time()), - "admins": members if (len(members) == 2 and title == "") else [], - } + chat_id = str(uuid.uuid4()) + chat: Chat = { + "id": chat_id, + "members": members, + "title": title, + "description": "", + "created_by": author_id, + "created_at": int(time.time()), + "updated_at": int(time.time()), + "admins": members if (len(members) == 2 and title == "") else [], + } - for member_id in members: - await redis.execute("SADD", f"chats_by_author/{member_id}", chat_id) - await notify_chat(chat, member_id, "create") + for member_id in members: + await redis.execute("SADD", f"chats_by_author/{member_id}", chat_id) + await notify_chat(chat, member_id, "create") - print(f"\n\n[resolvers.chats] creating: {chat}\n\n") + print(f"\n\n[resolvers.chats] creating: {chat}\n\n") - await redis.execute("SET", f"chats/{chat_id}", json.dumps(chat)) - await redis.execute("SET", f"chats/{chat_id}/next_message_id", str(0)) + await redis.execute("SET", f"chats/{chat_id}", json.dumps(chat)) + await redis.execute("SET", f"chats/{chat_id}/next_message_id", str(0)) return {"error": None, "chat": chat} @@ -97,8 +101,9 @@ async def create_chat(_, info, title="", members=None): @mutation.field("delete_chat") @login_required async def delete_chat(_, info, chat_id: str): - author_id = info.context["author_id"] - + user_id = info.context["user_id"] + author = authors_by_user[user_id] + author_id = author["id"] chat_str = await redis.execute("GET", f"chats/{chat_id}") if chat_str: chat: Chat = json.loads(chat_str) diff --git a/resolvers/load.py b/resolvers/load.py index dda7b17..b8ac1cc 100644 --- a/resolvers/load.py +++ b/resolvers/load.py @@ -6,7 +6,7 @@ from models.chat import ChatPayload, Message from models.member import ChatMember from resolvers.chats import create_chat from services.auth import login_required -from services.core import authors_by_id, get_my_followed +from services.core import authors_by_id, get_my_followed, authors_by_user from services.rediscache import redis from services.schema import query @@ -52,7 +52,9 @@ async def load_messages( @login_required async def load_chats(_, info, limit: int = 50, offset: int = 0) -> Dict[str, Union[List[Dict[str, Any]], None]]: """load :limit chats of current user with :offset""" - author_id = info.context.get("author_id") + user_id = info.context["user_id"] + author = authors_by_user[user_id] + author_id = author["id"] chats = [] if author_id: cids = await redis.execute("SMEMBERS", f"chats_by_author/{author_id}") @@ -88,13 +90,15 @@ async def load_chats(_, info, limit: int = 50, offset: int = 0) -> Dict[str, Uni @login_required async def load_messages_by(_, info, by, limit: int = 10, offset: int = 0): """load :limit messages of :chat_id with :offset""" - author_id = info.context["author_id"] - user_chats = (await redis.execute("SMEMBERS", "chats_by_author/" + str(author_id))) or [] - user_chats = [c for c in user_chats] - if user_chats: + user_id = info.context["user_id"] + author = authors_by_user[user_id] + author_id = author["id"] + author_chats = (await redis.execute("SMEMBERS", "chats_by_author/" + str(author_id))) or [] + author_chats = [c for c in author_chats] + if author_chats: messages = [] by_chat = by.get("chat") - if by_chat in user_chats: + if by_chat in author_chats: chat = await redis.execute("GET", f"chats/{by_chat}") if not chat: return {"messages": [], "error": "chat not exist"} diff --git a/resolvers/messages.py b/resolvers/messages.py index 03ca47a..c4797d4 100644 --- a/resolvers/messages.py +++ b/resolvers/messages.py @@ -3,6 +3,7 @@ import time from models.chat import Message from services.auth import login_required +from services.core import authors_by_user from services.presence import notify_message from services.rediscache import redis from services.schema import mutation @@ -12,7 +13,10 @@ from services.schema import mutation @login_required async def create_message(_, info, chat_id: str, body: str, reply_to=None): """Создание сообщения с телом :body для чата :chat_id с возможным ответом на :reply_to""" - author_id = info.context["author_id"] + + user_id = info.context["user_id"] + author = authors_by_user[user_id] + author_id = author["id"] # Получение данных чата из Redis chat_data = await redis.execute("GET", f"chats/{chat_id}") diff --git a/resolvers/search.py b/resolvers/search.py index 8258965..5fb8c51 100644 --- a/resolvers/search.py +++ b/resolvers/search.py @@ -4,7 +4,7 @@ from typing import Any, Dict, List, Union from resolvers.load import load_messages from services.auth import login_required -from services.core import authors_by_id +from services.core import authors_by_id, authors_by_user from services.rediscache import redis from services.schema import query @@ -16,7 +16,10 @@ async def search_recipients(_, info, text: str, limit: int = 50, offset: int = 0 # TODO: maybe redis scan? - author_id = info.context["author_id"] + user_id = info.context["user_id"] + author = authors_by_user[user_id] + author_id = author["id"] + existed_chats = await redis.execute("SMEMBERS", f"/chats_by_author/{author_id}") if existed_chats: for chat_id in list(json.loads(existed_chats))[offset : (offset + limit)]: @@ -38,7 +41,9 @@ async def search_recipients(_, info, text: str, limit: int = 50, offset: int = 0 async def search_messages( _, info, by: Dict[str, Union[str, int]], limit: int, offset: int ) -> Dict[str, Union[List[Dict[str, Any]], None]]: - author_id = info.context["author_id"] + user_id = info.context["user_id"] + author = authors_by_user[user_id] + author_id = author["id"] lookup_chats = set((await redis.execute("SMEMBERS", f"chats_by_author/{author_id}")) or []) messages_set = set([]) diff --git a/services/auth.py b/services/auth.py index fd547f7..6adf4ca 100644 --- a/services/auth.py +++ b/services/auth.py @@ -2,9 +2,6 @@ from functools import wraps from aiohttp import ClientSession from starlette.exceptions import HTTPException -from models.member import ChatMember -from services.core import authors_by_user - from settings import AUTH_URL @@ -63,9 +60,6 @@ def login_required(f): user_id = await check_auth(req) if user_id: context["user_id"] = user_id - author: ChatMember | None = authors_by_user.get(user_id) - if author: - context["author_id"] = author["id"] return await f(*args, **kwargs) return decorated_function