Merge branch 'main' of github.com:Discours/discours-backend into main
This commit is contained in:
commit
e60e5691b3
|
@ -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"
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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" : ""}
|
||||||
|
|
|
@ -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]!
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user