Merge branch 'main' of github.com:Discours/discours-backend into main

This commit is contained in:
tonyrewin 2022-07-01 09:40:18 +03:00
commit e60e5691b3
7 changed files with 73 additions and 95 deletions

View File

@ -18,6 +18,8 @@ class ShoutCommentsSubscription(Base):
subscriber = Column(ForeignKey('user.slug'), primary_key = True) subscriber = Column(ForeignKey('user.slug'), primary_key = True)
shout = Column(ForeignKey('shout.slug'), primary_key = True) shout = Column(ForeignKey('shout.slug'), primary_key = True)
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Created at") createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
auto = Column(Boolean, nullable=False, default = False)
deletedAt: str = Column(DateTime, nullable=True)
class ShoutAuthor(Base): class ShoutAuthor(Base):
__tablename__ = "shout_author" __tablename__ = "shout_author"

View File

@ -2,7 +2,7 @@ from resolvers.auth import login, sign_out, is_email_used, register, confirm, au
from resolvers.zine import get_shout_by_slug, subscribe, unsubscribe, view_shout, rate_shout, \ from resolvers.zine import get_shout_by_slug, subscribe, unsubscribe, view_shout, rate_shout, \
top_month, top_overall, recent_published, recent_all, top_viewed, \ top_month, top_overall, recent_published, recent_all, top_viewed, \
shouts_by_authors, shouts_by_topics, shouts_by_communities shouts_by_authors, shouts_by_topics, shouts_by_communities
from resolvers.profile import get_users_by_slugs, get_current_user, shouts_reviewed, shout_comments_subscribed from resolvers.profile import get_users_by_slugs, get_current_user, shouts_reviewed
from resolvers.topics import topic_subscribe, topic_unsubscribe, topics_by_author, \ from resolvers.topics import topic_subscribe, topic_unsubscribe, topics_by_author, \
topics_by_community, topics_by_slugs topics_by_community, topics_by_slugs
from resolvers.comments import create_comment, delete_comment, update_comment, rate_comment from resolvers.comments import create_comment, delete_comment, update_comment, rate_comment
@ -31,7 +31,6 @@ __all__ = [
"shouts_by_topics", "shouts_by_topics",
"shouts_by_authors", "shouts_by_authors",
"shouts_by_communities", "shouts_by_communities",
"shout_comments_subscribed",
"shouts_reviewed", "shouts_reviewed",
"top_month", "top_month",
"top_overall", "top_overall",

View File

@ -6,71 +6,55 @@ from auth.authenticate import login_required
import asyncio import asyncio
from datetime import datetime from datetime import datetime
class CommentResult: def comments_subscribe(user, slug, auto = False):
def __init__(self, status, comment): with local_session() as session:
self.status = status sub = session.query(ShoutCommentsSubscription).\
self.comment = comment filter(ShoutCommentsSubscription.subscriber == user.slug, ShoutCommentsSubscription.shout == slug).\
first()
if auto and sub:
return
elif not auto and sub:
if not sub.deletedAt is None:
sub.deletedAt = None
sub.auto = False
session.commit()
return
raise Exception("subscription already exist")
class ShoutCommentsSubscription:
queue = asyncio.Queue()
def __init__(self, shout_slug):
self.shout_slug = shout_slug
class ShoutCommentsStorage:
lock = asyncio.Lock()
subscriptions = []
@staticmethod
async def register_subscription(subs):
self = ShoutCommentsStorage
async with self.lock:
self.subscriptions.append(subs)
@staticmethod
async def del_subscription(subs):
self = ShoutCommentsStorage
async with self.lock:
self.subscriptions.remove(subs)
@staticmethod
async def put(comment_result):
self = ShoutCommentsStorage
async with self.lock:
for subs in self.subscriptions:
if comment_result.comment.shout == subs.shout_slug:
subs.queue.put_nowait(comment_result)
def comments_subscribe(user, slug):
ShoutCommentsSubscription.create( ShoutCommentsSubscription.create(
subscriber = user.slug, subscriber = user.slug,
shout = slug) shout = slug,
auto = auto)
def comments_unsubscribe(user, slug): def comments_unsubscribe(user, slug):
with local_session() as session: with local_session() as session:
sub = session.query(ShoutCommentsSubscription).\ sub = session.query(ShoutCommentsSubscription).\
filter(and_(ShoutCommentsSubscription.subscriber == user.slug, ShoutCommentsSubscription.shout == slug)).\ filter(ShoutCommentsSubscription.subscriber == user.slug, ShoutCommentsSubscription.shout == slug).\
first() first()
if not sub: if not sub:
raise Exception("subscription not exist") raise Exception("subscription not exist")
session.delete(sub) if sub.auto:
sub.deletedAt = datetime.now()
else:
session.delete(sub)
session.commit() session.commit()
@mutation.field("createComment") @mutation.field("createComment")
@login_required @login_required
async def create_comment(_, info, body, shout, replyTo = None): async def create_comment(_, info, body, shout, replyTo = None):
auth = info.context["request"].auth user = info.context["request"].user
user_id = auth.user_id
comment = Comment.create( comment = Comment.create(
author = user_id, author = user.id,
body = body, body = body,
shout = shout, shout = shout,
replyTo = replyTo replyTo = replyTo
) )
result = CommentResult("NEW", comment) try:
await ShoutCommentsStorage.put(result) comments_subscribe(user, shout, True)
except Exception as e:
print(f"error on comment autosubscribe: {e}")
return {"comment": comment} return {"comment": comment}
@ -92,9 +76,6 @@ async def update_comment(_, info, id, body):
session.commit() session.commit()
result = CommentResult("UPDATED", comment)
await ShoutCommentsStorage.put(result)
return {"comment": comment} return {"comment": comment}
@mutation.field("deleteComment") @mutation.field("deleteComment")
@ -113,9 +94,6 @@ async def delete_comment(_, info, id):
comment.deletedAt = datetime.now() comment.deletedAt = datetime.now()
session.commit() session.commit()
result = CommentResult("DELETED", comment)
await ShoutCommentsStorage.put(result)
return {} return {}
@mutation.field("rateComment") @mutation.field("rateComment")
@ -130,7 +108,7 @@ async def rate_comment(_, info, id, value):
return {"error": "invalid comment id"} return {"error": "invalid comment id"}
rating = session.query(CommentRating).\ rating = session.query(CommentRating).\
filter(CommentRating.comment_id == id and CommentRating.createdBy == user_id).first() filter(CommentRating.comment_id == id, CommentRating.createdBy == user_id).first()
if rating: if rating:
rating.value = value rating.value = value
session.commit() session.commit()
@ -141,7 +119,12 @@ async def rate_comment(_, info, id, value):
createdBy = user_id, createdBy = user_id,
value = value) value = value)
result = CommentResult("UPDATED_RATING", comment)
await ShoutCommentsStorage.put(result)
return {} return {}
def get_subscribed_shout_comments(slug):
with local_session() as session:
rows = session.query(ShoutCommentsSubscription.shout).\
filter(ShoutCommentsSubscription.subscriber == slug, ShoutCommentsSubscription.deletedAt == None).\
all()
slugs = [row.shout for row in rows]
return slugs

View File

@ -1,6 +1,7 @@
from orm import Shout, ShoutRating, ShoutRatingStorage from orm import Shout, ShoutRating, ShoutRatingStorage
from orm.base import local_session from orm.base import local_session
from resolvers.base import mutation, query, subscription from resolvers.base import mutation, query, subscription
from resolvers.comments import comments_subscribe
from auth.authenticate import login_required from auth.authenticate import login_required
import asyncio import asyncio
from datetime import datetime from datetime import datetime
@ -19,7 +20,9 @@ async def create_shout(_, info, input):
ShoutAuthor.create( ShoutAuthor.create(
shout = new_shout.slug, shout = new_shout.slug,
user = user.slug) user = user.slug)
comments_subscribe(user, new_shout.slug, True)
if "mainTopic" in input: if "mainTopic" in input:
topic_slugs.append(input["mainTopic"]) topic_slugs.append(input["mainTopic"])
@ -106,4 +109,4 @@ async def delete_shout(_, info, slug):
shout.deletedAt = datetime.now() shout.deletedAt = datetime.now()
session.commit() session.commit()
return {} return {}

View File

@ -4,6 +4,8 @@ from orm.comment import Comment
from orm.base import local_session from orm.base import local_session
from orm.topic import Topic, TopicSubscription from orm.topic import Topic, TopicSubscription
from resolvers.base import mutation, query, subscription from resolvers.base import mutation, query, subscription
from resolvers.community import get_subscribed_communities
from resolvers.comments import get_subscribed_shout_comments
from auth.authenticate import login_required from auth.authenticate import login_required
from inbox_resolvers.inbox import get_total_unread_messages_for_user from inbox_resolvers.inbox import get_total_unread_messages_for_user
@ -30,10 +32,11 @@ def _get_user_subscribed_authors(slug):
async def get_user_info(slug): async def get_user_info(slug):
return { return {
"totalUnreadMessages" : await get_total_unread_messages_for_user(slug), "totalUnreadMessages" : await get_total_unread_messages_for_user(slug),
"userSubscribedTopics" : _get_user_subscribed_topic_slugs(slug), "userSubscribedTopics" : _get_user_subscribed_topic_slugs(slug),
"userSubscribedAuthors" : _get_user_subscribed_authors(slug), "userSubscribedAuthors" : _get_user_subscribed_authors(slug),
"userSubscribedCommunities": get_subscribed_communities(slug) "userSubscribedCommunities" : get_subscribed_communities(slug),
"userSubscribedShoutComments": get_subscribed_shout_comments(slug)
} }
@query.field("getCurrentUser") @query.field("getCurrentUser")
@ -203,22 +206,6 @@ async def shouts_reviewed(_, info, page, size):
return shouts return shouts
@query.field("shoutCommentsSubscribed")
@login_required
async def shout_comments_subscribed(_, info, slug, page, size):
user = info.context["request"].user
with local_session() as session:
comments_by_shout = session.query(Comment).\
join(ShoutCommentsSubscription).\
join(ShoutCommentsSubscription, ShoutCommentsSubscription.shout == slug).\
where(ShoutCommentsSubscription.subscriber == user.slug)
comments = comments_by_shout.\
order_by(desc(Shout.createdAt)).\
limit(size).\
offset( (page - 1) * size)
return shouts
@query.field("shoutsCommentedByUser") @query.field("shoutsCommentedByUser")
async def shouts_commented_by_user(_, info, slug, page, size): async def shouts_commented_by_user(_, info, slug, page, size):
user = await UserStorage.get_user_by_slug(slug) user = await UserStorage.get_user_by_slug(slug)

View File

@ -7,6 +7,9 @@ from orm.user import UserStorage, AuthorSubscription
from orm.topic import TopicSubscription from orm.topic import TopicSubscription
from resolvers.base import mutation, query from resolvers.base import mutation, query
from resolvers.profile import author_subscribe, author_unsubscribe
from resolvers.topics import topic_subscribe, topic_unsubscribe
from resolvers.community import community_subscribe, community_unsubscribe
from resolvers.comments import comments_subscribe, comments_unsubscribe from resolvers.comments import comments_subscribe, comments_unsubscribe
from auth.authenticate import login_required from auth.authenticate import login_required
from settings import SHOUTS_REPO from settings import SHOUTS_REPO
@ -315,39 +318,39 @@ async def shouts_by_communities(_, info, slugs, page, size):
@mutation.field("subscribe") @mutation.field("subscribe")
@login_required @login_required
async def subscribe(_, info, subscription, slug): async def subscribe(_, info, what, slug):
user = info.context["request"].user user = info.context["request"].user
try: try:
if subscription == "AUTHOR": if what == "AUTHOR":
author_subscribe(user, slug) author_subscribe(user, slug)
elif subscription == "TOPIC": elif what == "TOPIC":
topic_subscribe(user, slug) topic_subscribe(user, slug)
elif subscription == "COMMUNITY": elif what == "COMMUNITY":
community_subscribe(user, slug) community_subscribe(user, slug)
elif comments_subscription == "COMMENTS": elif what == "COMMENTS":
comments_subscribe(user, slug) comments_subscribe(user, slug)
except Exception as e: except Exception as e:
return {"error" : e} return {"error" : str(e)}
return {} return {}
@mutation.field("unsubscribe") @mutation.field("unsubscribe")
@login_required @login_required
async def unsubscribe(_, info, subscription, slug): async def unsubscribe(_, info, what, slug):
user = info.context["request"].user user = info.context["request"].user
try: try:
if subscription == "AUTHOR": if what == "AUTHOR":
author_unsubscribe(user, slug) author_unsubscribe(user, slug)
elif subscription == "TOPIC": elif what == "TOPIC":
topic_unsubscribe(user, slug) topic_unsubscribe(user, slug)
elif subscription == "COMMUNITY": elif what == "COMMUNITY":
community_unsubscribe(user, slug) community_unsubscribe(user, slug)
elif subscription == "COMMENTS": elif what == "COMMENTS":
comments_unsubscribe(user, slug) comments_unsubscribe(user, slug)
except Exception as e: except Exception as e:
return {"error" : e} return {"error" : str(e)}
return {} return {}
@ -374,4 +377,4 @@ async def rate_shout(_, info, slug, value):
await ShoutRatingStorage.update_rating(rating) await ShoutRatingStorage.update_rating(rating)
return {"error" : ""} return {"error" : ""}

View File

@ -7,10 +7,11 @@ type Result {
} }
type CurrentUserInfo { type CurrentUserInfo {
totalUnreadMessages: Int totalUnreadMessages: Int
userSubscribedTopics: [String]! userSubscribedTopics: [String]!
userSubscribedAuthors: [String]! userSubscribedAuthors: [String]!
userSubscribedCommunities: [String]! userSubscribedCommunities: [String]!
userSubscribedShoutComments: [String]!
} }
type AuthResult { type AuthResult {
@ -98,6 +99,7 @@ enum SubscriptionType {
TOPIC TOPIC
AUTHOR AUTHOR
COMMUNITY COMMUNITY
COMMENTS
} }
################################### Mutation ################################### Mutation
@ -205,7 +207,6 @@ type Query {
getCommunity(slug: String): Community! getCommunity(slug: String): Community!
getCommunities: [Community]! getCommunities: [Community]!
shoutCommentsSubscribed(slug: String!, page: Int!, size: Int!): [Shout]!
shoutsReviewed(page: Int!, size: Int!): [Shout]! shoutsReviewed(page: Int!, size: Int!): [Shout]!
recentCommented(page: Int!, size: Int!): [Shout]! recentCommented(page: Int!, size: Int!): [Shout]!
} }