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, \ from resolvers.inbox.messages import load_chat_messages, \
create_message, delete_message, update_message, \ create_message, delete_message, update_message, \
message_generator, mark_as_read message_generator, mark_as_read
from resolvers.inbox.search import search_users, \
search_messages, search_chats
__all__ = [ __all__ = [
"follow", "follow",

View File

@ -5,28 +5,7 @@ from datetime import datetime
from auth.authenticate import login_required from auth.authenticate import login_required
from base.redis import redis from base.redis import redis
from base.resolvers import mutation, query from base.resolvers import mutation, query
from resolvers.inbox.messages import load_messages from resolvers.inbox.load import load_messages, load_user_chats
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 add_user_to_chat(user_slug: str, chat_id: str, chat=None): 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)) 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") @query.field("loadChats")
@login_required @login_required
async def load_chats(_, info): 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.redis import redis
from base.resolvers import mutation, query, subscription from base.resolvers import mutation, query, subscription
from services.inbox import ChatFollowing, MessageResult, MessagesStorage from services.inbox import ChatFollowing, MessageResult, MessagesStorage
from resolvers.inbox.chats import get_chats_by_user from resolvers.inbox.load import load_messages
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
}
@query.field("loadMessages") @query.field("loadMessages")
@ -173,7 +155,11 @@ async def mark_as_read(_, info, chat_id: str, messages: [int]):
async def message_generator(obj, info): async def message_generator(obj, info):
try: try:
user = info.context["request"].user 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 = [] tasks = []
updated = {} updated = {}
for chat_id in user_following_chats: for chat_id in user_following_chats:

View File

@ -2,13 +2,14 @@ import json
from auth.authenticate import login_required from auth.authenticate import login_required
from base.redis import redis from base.redis import redis
from base.resolvers import query, session from base.resolvers import query
from orm.zine import AuthorFollower from base.orm import local_session
from orm.user import AuthorFollower
@query.field("searchUsers") @query.field("searchUsers")
@login_required @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 = [] result = []
# TODO: maybe redis scan? # TODO: maybe redis scan?
user = info.context["request"].user 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) more_amount = amount - len(result)
# followings with local_session() as session:
result += session.query(AuthorFollower.author).where(AuthorFollower.follower.startswith(query))\ # followings
.offset(offset + len(result)).limit(more_amount) result += session.query(AuthorFollower.author).where(AuthorFollower.follower.startswith(query))\
.offset(offset + len(result)).limit(more_amount)
more_amount = amount more_amount = amount
# followers # followers
result += session.query(AuthorFollower.follower).where(AuthorFollower.author.startswith(query))\ result += session.query(AuthorFollower.follower).where(AuthorFollower.author.startswith(query))\
.offset(offset + len(result)).limit(offset + len(result) + amount) .offset(offset + len(result)).limit(offset + len(result) + amount)
return { return {
"slugs": list(result), "slugs": list(result),
"error": None "error": None
@ -43,7 +45,7 @@ async def search_user(_, info, query: str, offset: int = 0, amount: int = 50):
@query.field("searchChats") @query.field("searchChats")
@login_required @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 user = info.context["request"].user
my_chats = await redis.execute("GET", f"/chats_by_user/{user.slug}") my_chats = await redis.execute("GET", f"/chats_by_user/{user.slug}")
chats = [] chats = []

View File

@ -11,7 +11,7 @@ from orm.shout import Shout
from orm.topic import Topic, TopicFollower from orm.topic import Topic, TopicFollower
from orm.user import User, UserRole, Role, UserRating, AuthorFollower from orm.user import User, UserRole, Role, UserRating, AuthorFollower
from .community import followed_communities 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 .topics import get_topic_stat
from services.auth.users import UserStorage from services.auth.users import UserStorage
from services.zine.shoutscache import ShoutsCache from services.zine.shoutscache import ShoutsCache

View File

@ -138,6 +138,7 @@ type Mutation {
# inbox # inbox
createChat(title: String, members: [String]!): Result! createChat(title: String, members: [String]!): Result!
updateChat(chat: ChatInput!): Result! updateChat(chat: ChatInput!): Result!
deleteChat(chatId: String!): Result!
inviteChat(chatId: String!, userslug: String!): Result! inviteChat(chatId: String!, userslug: String!): Result!
enterChat(chatId: String!): Result! enterChat(chatId: String!): Result!
createMessage(chatId: String!, body: String!, replyTo: String): Result! createMessage(chatId: String!, body: String!, replyTo: String): Result!