Merge branch 'prealpha' into main

This commit is contained in:
2022-12-02 11:51:53 +03:00
19 changed files with 221 additions and 210 deletions

View File

@@ -3,6 +3,7 @@ import uuid
from datetime import datetime, timezone
from auth.authenticate import login_required
from auth.credentials import AuthCredentials
from base.redis import redis
from base.resolvers import mutation
@@ -18,7 +19,7 @@ async def update_chat(_, info, chat_new: dict):
:param chat_new: dict with chat data
:return: Result { error chat }
"""
user = info.context["request"].user
auth: AuthCredentials = info.context["request"].auth
chat_id = chat_new["id"]
chat = await redis.execute("GET", f"chats/{chat_id}")
if not chat:
@@ -26,7 +27,9 @@ async def update_chat(_, info, chat_new: dict):
"error": "chat not exist"
}
chat = dict(json.loads(chat))
if user.slug in chat["admins"]:
# TODO
if auth.user_id in chat["admins"]:
chat.update({
"title": chat_new.get("title", chat["title"]),
"description": chat_new.get("description", chat["description"]),
@@ -46,10 +49,11 @@ async def update_chat(_, info, chat_new: dict):
@mutation.field("createChat")
@login_required
async def create_chat(_, info, title="", members=[]):
user = info.context["request"].user
auth: AuthCredentials = info.context["request"].auth
chat = {}
if user.slug not in members:
members.append(user.slug)
if auth.user_id not in members:
members.append(auth.user_id)
# reuse chat craeted before if exists
if len(members) == 2 and title == "":
@@ -73,7 +77,7 @@ async def create_chat(_, info, title="", members=[]):
"id": chat_id,
"users": members,
"title": title,
"createdBy": user.slug,
"createdBy": auth.user_id,
"createdAt": int(datetime.now(tz=timezone.utc).timestamp()),
"updatedAt": int(datetime.now(tz=timezone.utc).timestamp()),
"admins": []
@@ -93,13 +97,14 @@ async def create_chat(_, info, title="", members=[]):
@mutation.field("deleteChat")
@login_required
async def delete_chat(_, info, chat_id: str):
user = info.context["request"].user
auth: AuthCredentials = info.context["request"].auth
chat = await redis.execute("GET", f"/chats/{chat_id}")
if chat:
chat = dict(json.loads(chat))
if user.slug in chat['admins']:
if auth.user_id in chat['admins']:
await redis.execute("DEL", f"chats/{chat_id}")
await redis.execute("SREM", "chats_by_user/" + user, chat_id)
await redis.execute("SREM", "chats_by_user/" + str(auth.user_id), chat_id)
await redis.execute("COMMIT")
else:
return {

View File

@@ -2,6 +2,7 @@ import json
from datetime import datetime, timedelta, timezone
from auth.authenticate import login_required
from auth.credentials import AuthCredentials
from base.redis import redis
from base.orm import local_session
from base.resolvers import query
@@ -30,12 +31,9 @@ async def load_messages(chat_id: str, limit: int, offset: int):
@login_required
async def load_chats(_, info, limit: int = 50, offset: int = 0):
""" load :limit chats of current user with :offset """
user = info.context["request"].user
if user:
print('[inbox] load user\'s chats %s' % user.slug)
else:
raise Unauthorized("Please login to load chats")
cids = await redis.execute("SMEMBERS", "chats_by_user/" + user.slug)
auth: AuthCredentials = info.context["request"].auth
cids = await redis.execute("SMEMBERS", "chats_by_user/" + str(auth.user_id))
if cids:
cids = list(cids)[offset:offset + limit]
if not cids:
@@ -47,7 +45,7 @@ async def load_chats(_, info, limit: int = 50, offset: int = 0):
if c:
c = dict(json.loads(c))
c['messages'] = await load_messages(cid, 5, 0)
c['unread'] = await get_unread_counter(cid, user.slug)
c['unread'] = await get_unread_counter(cid, auth.user_id)
with local_session() as session:
c['members'] = []
for userslug in c["users"]:
@@ -65,11 +63,11 @@ async def load_chats(_, info, limit: int = 50, offset: int = 0):
}
async def search_user_chats(by, messages: set, slug: str, limit, offset):
async def search_user_chats(by, messages: set, user_id: int, limit, offset):
cids = set([])
by_author = by.get('author')
body_like = by.get('body')
cids.unioin(set(await redis.execute("SMEMBERS", "chats_by_user/" + slug)))
cids.unioin(set(await redis.execute("SMEMBERS", "chats_by_user/" + str(user_id))))
if by_author:
# all author's messages
cids.union(set(await redis.execute("SMEMBERS", f"chats_by_user/{by_author}")))
@@ -104,9 +102,11 @@ async def load_messages_by(_, info, by, limit: int = 10, offset: int = 0):
# everyone's messages in filtered chat
messages.union(set(await load_messages(by_chat, limit, offset)))
user = info.context["request"].user
if user and len(messages) == 0:
messages.union(search_user_chats(by, messages, user.slug, limit, offset))
auth: AuthCredentials = info.context["request"].auth
if len(messages) == 0:
# FIXME
messages.union(search_user_chats(by, messages, auth.user_id, limit, offset))
days = by.get("days")
if days:
@@ -126,9 +126,10 @@ async def load_messages_by(_, info, by, limit: int = 10, offset: int = 0):
@query.field("loadRecipients")
async def load_recipients(_, info, limit=50, offset=0):
chat_users = []
user = info.context["request"].user
auth: AuthCredentials = info.context["request"].auth
try:
chat_users += await followed_authors(user.slug)
chat_users += await followed_authors(auth.user_id)
limit = limit - len(chat_users)
except Exception:
pass

View File

@@ -3,6 +3,7 @@ import json
from datetime import datetime, timezone
from auth.authenticate import login_required
from auth.credentials import AuthCredentials
from base.redis import redis
from base.resolvers import mutation, subscription
from services.inbox import ChatFollowing, MessageResult, MessagesStorage
@@ -12,7 +13,8 @@ from services.inbox import ChatFollowing, MessageResult, MessagesStorage
@login_required
async def create_message(_, info, chat: str, body: str, replyTo=None):
""" create message with :body for :chat_id replying to :replyTo optionally """
user = info.context["request"].user
auth: AuthCredentials = info.context["request"].auth
chat = await redis.execute("GET", f"chats/{chat}")
if not chat:
return {
@@ -25,7 +27,7 @@ async def create_message(_, info, chat: str, body: str, replyTo=None):
new_message = {
"chatId": chat['id'],
"id": message_id,
"author": user.slug,
"author": auth.user_id,
"body": body,
"replyTo": replyTo,
"createdAt": int(datetime.now(tz=timezone.utc).timestamp()),
@@ -55,7 +57,7 @@ async def create_message(_, info, chat: str, body: str, replyTo=None):
@mutation.field("updateMessage")
@login_required
async def update_message(_, info, chat_id: str, message_id: int, body: str):
user = info.context["request"].user
auth: AuthCredentials = info.context["request"].auth
chat = await redis.execute("GET", f"chats/{chat_id}")
if not chat:
@@ -66,7 +68,7 @@ async def update_message(_, info, chat_id: str, message_id: int, body: str):
return {"error": "message not exist"}
message = json.loads(message)
if message["author"] != user.slug:
if message["author"] != auth.user_id:
return {"error": "access denied"}
message["body"] = body
@@ -86,7 +88,7 @@ async def update_message(_, info, chat_id: str, message_id: int, body: str):
@mutation.field("deleteMessage")
@login_required
async def delete_message(_, info, chat_id: str, message_id: int):
user = info.context["request"].user
auth: AuthCredentials = info.context["request"].auth
chat = await redis.execute("GET", f"chats/{chat_id}")
if not chat:
@@ -97,15 +99,15 @@ async def delete_message(_, info, chat_id: str, message_id: int):
if not message:
return {"error": "message not exist"}
message = json.loads(message)
if message["author"] != user.slug:
if message["author"] != auth.user_id:
return {"error": "access denied"}
await redis.execute("LREM", f"chats/{chat_id}/message_ids", 0, str(message_id))
await redis.execute("DEL", f"chats/{chat_id}/messages/{str(message_id)}")
users = chat["users"]
for user_slug in users:
await redis.execute("LREM", f"chats/{chat_id}/unread/{user_slug}", 0, str(message_id))
for user_id in users:
await redis.execute("LREM", f"chats/{chat_id}/unread/{user_id}", 0, str(message_id))
result = MessageResult("DELETED", message)
await MessagesStorage.put(result)
@@ -116,7 +118,7 @@ async def delete_message(_, info, chat_id: str, message_id: int):
@mutation.field("markAsRead")
@login_required
async def mark_as_read(_, info, chat_id: str, messages: [int]):
user = info.context["request"].user
auth: AuthCredentials = info.context["request"].auth
chat = await redis.execute("GET", f"chats/{chat_id}")
if not chat:
@@ -124,11 +126,11 @@ async def mark_as_read(_, info, chat_id: str, messages: [int]):
chat = json.loads(chat)
users = set(chat["users"])
if user.slug not in users:
if auth.user_id not in users:
return {"error": "access denied"}
for message_id in messages:
await redis.execute("LREM", f"chats/{chat_id}/unread/{user.slug}", 0, str(message_id))
await redis.execute("LREM", f"chats/{chat_id}/unread/{auth.user_id}", 0, str(message_id))
return {
"error": None
@@ -139,8 +141,9 @@ async def mark_as_read(_, info, chat_id: str, messages: [int]):
@login_required
async def message_generator(obj, info):
try:
user = info.context["request"].user
user_following_chats = await redis.execute("GET", f"chats_by_user/{user.slug}")
auth: AuthCredentials = info.context["request"].auth
user_following_chats = await redis.execute("GET", f"chats_by_user/{auth.user_id}")
if user_following_chats:
user_following_chats = list(json.loads(user_following_chats)) # chat ids
else:

View File

@@ -1,6 +1,7 @@
import json
from auth.authenticate import login_required
from auth.credentials import AuthCredentials
from base.redis import redis
from base.resolvers import query
from base.orm import local_session
@@ -12,8 +13,8 @@ from orm.user import AuthorFollower, User
async def search_recipients(_, info, query: str, limit: int = 50, offset: int = 0):
result = []
# TODO: maybe redis scan?
user = info.context["request"].user
talk_before = await redis.execute("GET", f"/chats_by_user/{user.slug}")
auth: AuthCredentials = info.context["request"].auth
talk_before = await redis.execute("GET", f"/chats_by_user/{auth.user_id}")
if talk_before:
talk_before = list(json.loads(talk_before))[offset:offset + limit]
for chat_id in talk_before:
@@ -24,7 +25,6 @@ async def search_recipients(_, info, query: str, limit: int = 50, offset: int =
if member.startswith(query):
if member not in result:
result.append(member)
user = info.context["request"].user
more_amount = limit - len(result)