diff --git a/resolvers/__init__.py b/resolvers/__init__.py index 69dfe953..bebee337 100644 --- a/resolvers/__init__.py +++ b/resolvers/__init__.py @@ -66,6 +66,8 @@ from resolvers.inbox.chats import load_chats, \ from resolvers.inbox.messages import load_chat_messages, \ create_message, delete_message, update_message, \ message_generator, mark_as_read +from resolvers.inbox.search import search_users, \ + search_messages, search_chats __all__ = [ "follow", diff --git a/resolvers/inbox/chats.py b/resolvers/inbox/chats.py index 7e2206c7..e6923811 100644 --- a/resolvers/inbox/chats.py +++ b/resolvers/inbox/chats.py @@ -5,28 +5,7 @@ from datetime import datetime from auth.authenticate import login_required from base.redis import redis from base.resolvers import mutation, query -from resolvers.inbox.messages import load_messages - - -async def get_unread_counter(chat_id: str, user_slug: str): - try: - return int(await redis.execute("LLEN", f"chats/{chat_id}/unread/{user_slug}")) - except Exception: - return 0 - - -async def get_total_unread_counter(user_slug: str): - chats = await redis.execute("GET", f"chats_by_user/{user_slug}") - if not chats: - return 0 - - chats = json.loads(chats) - unread = 0 - for chat_id in chats: - n = await get_unread_counter(chat_id, user_slug) - unread += n - - return unread +from resolvers.inbox.load import load_messages, load_user_chats async def add_user_to_chat(user_slug: str, chat_id: str, chat=None): @@ -41,27 +20,6 @@ async def add_user_to_chat(user_slug: str, chat_id: str, chat=None): await redis.execute("SET", f"chats_by_user/{member}", json.dumps(chats_ids)) -async def get_chats_by_user(slug: str): - chats = await redis.execute("GET", f"chats_by_user/{slug}") - if chats: - chats = list(json.loads(chats)) - return chats or [] - - -async def load_user_chats(slug, offset: int, amount: int): - """ load :amount chats of :slug user with :offset """ - chats = await get_chats_by_user(slug)[offset:offset + amount] - if not chats: - chats = [] - for c in chats: - c['messages'] = await load_messages(c['id']) - c['unread'] = await get_unread_counter(c['id'], slug) - return { - "chats": chats, - "error": None - } - - @query.field("loadChats") @login_required async def load_chats(_, info): diff --git a/resolvers/inbox/load.py b/resolvers/inbox/load.py new file mode 100644 index 00000000..49c1e766 --- /dev/null +++ b/resolvers/inbox/load.py @@ -0,0 +1,59 @@ +import json + +from base.redis import redis + + +async def get_unread_counter(chat_id: str, user_slug: str): + try: + return int(await redis.execute("LLEN", f"chats/{chat_id}/unread/{user_slug}")) + except Exception: + return 0 + + +async def get_total_unread_counter(user_slug: str): + chats = await redis.execute("GET", f"chats_by_user/{user_slug}") + if not chats: + return 0 + + chats = json.loads(chats) + unread = 0 + for chat_id in chats: + n = await get_unread_counter(chat_id, user_slug) + unread += n + + return unread + + +async def load_user_chats(slug, offset: int, amount: int): + """ load :amount chats of :slug user with :offset """ + + chats = await redis.execute("GET", f"chats_by_user/{slug}") + if chats: + chats = list(json.loads(chats))[offset:offset + amount] + if not chats: + chats = [] + for c in chats: + c['messages'] = await load_messages(c['id']) + c['unread'] = await get_unread_counter(c['id'], slug) + return { + "chats": chats, + "error": None + } + + +async def load_messages(chatId: str, offset: int, amount: int): + ''' load :amount messages for :chatId with :offset ''' + messages = [] + message_ids = await redis.lrange( + f"chats/{chatId}/message_ids", 0 - offset - amount, 0 - offset + ) + if message_ids: + message_keys = [ + f"chats/{chatId}/messages/{mid}" for mid in message_ids + ] + messages = await redis.mget(*message_keys) + messages = [json.loads(msg) for msg in messages] + return { + "messages": messages, + "error": None + } diff --git a/resolvers/inbox/messages.py b/resolvers/inbox/messages.py index 0118c17f..e6494808 100644 --- a/resolvers/inbox/messages.py +++ b/resolvers/inbox/messages.py @@ -6,25 +6,7 @@ from auth.authenticate import login_required from base.redis import redis from base.resolvers import mutation, query, subscription from services.inbox import ChatFollowing, MessageResult, MessagesStorage -from resolvers.inbox.chats import get_chats_by_user - - -async def load_messages(chatId: str, offset: int, amount: int): - ''' load :amount messages for :chatId with :offset ''' - messages = [] - message_ids = await redis.lrange( - f"chats/{chatId}/message_ids", 0 - offset - amount, 0 - offset - ) - if message_ids: - message_keys = [ - f"chats/{chatId}/messages/{mid}" for mid in message_ids - ] - messages = await redis.mget(*message_keys) - messages = [json.loads(msg) for msg in messages] - return { - "messages": messages, - "error": None - } +from resolvers.inbox.load import load_messages @query.field("loadMessages") @@ -173,7 +155,11 @@ async def mark_as_read(_, info, chat_id: str, messages: [int]): async def message_generator(obj, info): try: user = info.context["request"].user - user_following_chats = await get_chats_by_user(user.slug) # chat ids + user_following_chats = await redis.execute("GET", f"chats_by_user/{user.slug}") + if user_following_chats: + user_following_chats = list(json.loads(user_following_chats)) # chat ids + else: + user_following_chats = [] tasks = [] updated = {} for chat_id in user_following_chats: diff --git a/resolvers/inbox/search.py b/resolvers/inbox/search.py index 2f490b9a..82048e00 100644 --- a/resolvers/inbox/search.py +++ b/resolvers/inbox/search.py @@ -2,13 +2,14 @@ import json from auth.authenticate import login_required from base.redis import redis -from base.resolvers import query, session -from orm.zine import AuthorFollower +from base.resolvers import query +from base.orm import local_session +from orm.user import AuthorFollower @query.field("searchUsers") @login_required -async def search_user(_, info, query: str, offset: int = 0, amount: int = 50): +async def search_users(_, info, query: str, offset: int = 0, amount: int = 50): result = [] # TODO: maybe redis scan? user = info.context["request"].user @@ -27,14 +28,15 @@ async def search_user(_, info, query: str, offset: int = 0, amount: int = 50): more_amount = amount - len(result) - # followings - result += session.query(AuthorFollower.author).where(AuthorFollower.follower.startswith(query))\ - .offset(offset + len(result)).limit(more_amount) + with local_session() as session: + # followings + result += session.query(AuthorFollower.author).where(AuthorFollower.follower.startswith(query))\ + .offset(offset + len(result)).limit(more_amount) - more_amount = amount - # followers - result += session.query(AuthorFollower.follower).where(AuthorFollower.author.startswith(query))\ - .offset(offset + len(result)).limit(offset + len(result) + amount) + more_amount = amount + # followers + result += session.query(AuthorFollower.follower).where(AuthorFollower.author.startswith(query))\ + .offset(offset + len(result)).limit(offset + len(result) + amount) return { "slugs": list(result), "error": None @@ -43,7 +45,7 @@ async def search_user(_, info, query: str, offset: int = 0, amount: int = 50): @query.field("searchChats") @login_required -async def search_chat(_, info, query: str, offset: int = 0, amount: int = 50): +async def search_chats(_, info, query: str, offset: int = 0, amount: int = 50): user = info.context["request"].user my_chats = await redis.execute("GET", f"/chats_by_user/{user.slug}") chats = [] diff --git a/resolvers/profile.py b/resolvers/profile.py index dc0dcba0..84adff89 100644 --- a/resolvers/profile.py +++ b/resolvers/profile.py @@ -11,7 +11,7 @@ from orm.shout import Shout from orm.topic import Topic, TopicFollower from orm.user import User, UserRole, Role, UserRating, AuthorFollower from .community import followed_communities -from .inbox.messages import get_total_unread_counter +from .inbox.load import get_total_unread_counter from .topics import get_topic_stat from services.auth.users import UserStorage from services.zine.shoutscache import ShoutsCache diff --git a/schema.graphql b/schema.graphql index d720990b..d755aa88 100644 --- a/schema.graphql +++ b/schema.graphql @@ -138,6 +138,7 @@ type Mutation { # inbox createChat(title: String, members: [String]!): Result! updateChat(chat: ChatInput!): Result! + deleteChat(chatId: String!): Result! inviteChat(chatId: String!, userslug: String!): Result! enterChat(chatId: String!): Result! createMessage(chatId: String!, body: String!, replyTo: String): Result!