inbox-refactoring

This commit is contained in:
tonyrewin 2022-11-12 10:13:51 +03:00
parent 6bc7b6f433
commit 89d5863920
7 changed files with 83 additions and 75 deletions

View File

@ -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",

View File

@ -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):

59
resolvers/inbox/load.py Normal file
View File

@ -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
}

View File

@ -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:

View File

@ -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 = []

View File

@ -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

View File

@ -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!