From 64e1bea4cdaf4770c239bcb9178d78fce8c36b95 Mon Sep 17 00:00:00 2001 From: tonyrewin Date: Thu, 16 Feb 2023 13:08:55 +0300 Subject: [PATCH] my feed fixes --- resolvers/zine/following.py | 41 ++++++++++++------------- resolvers/zine/load.py | 61 ++++++++++++++++++++++--------------- schema.graphql | 1 + 3 files changed, 57 insertions(+), 46 deletions(-) diff --git a/resolvers/zine/following.py b/resolvers/zine/following.py index 72c3a0e9..ba3f64b0 100644 --- a/resolvers/zine/following.py +++ b/resolvers/zine/following.py @@ -1,12 +1,12 @@ import asyncio from base.orm import local_session -from base.resolvers import mutation, subscription, query +from base.resolvers import mutation, subscription from auth.authenticate import login_required from auth.credentials import AuthCredentials # from resolvers.community import community_follow, community_unfollow from orm.user import AuthorFollower from orm.topic import TopicFollower -from orm.shout import Shout, ShoutReactionsFollower +from orm.shout import ShoutReactionsFollower from resolvers.zine.profile import author_follow, author_unfollow from resolvers.zine.reactions import reactions_follow, reactions_unfollow from resolvers.zine.topics import topic_follow, topic_unfollow @@ -14,22 +14,6 @@ from services.following import Following, FollowingManager, FollowingResult from graphql.type import GraphQLResolveInfo -@query.field("myFeed") -@login_required -async def get_my_feed(_, info): - auth: AuthCredentials = info.context["request"].auth - user_id = auth.user_id - try: - with local_session() as session: - following_authors = session.query(AuthorFollower).where(AuthorFollower.follower == user_id).unique().all() - following_topics = session.query(TopicFollower).where(TopicFollower.follower == user_id).unique().all() - # TODO: my feed query - shouts = [] - return shouts - except Exception: - pass - - @mutation.field("follow") @login_required async def follow(_, info, what, slug): @@ -99,11 +83,9 @@ async def shout_generator(_, info: GraphQLResolveInfo): tasks = [] with local_session() as session: - following_authors = session.query(AuthorFollower).where( - AuthorFollower.follower == user_id).all() - following_topics = session.query(TopicFollower).where(TopicFollower.follower == user_id).all() - # notify new shout + # notify new shout by followed authors + following_topics = session.query(TopicFollower).where(TopicFollower.follower == user_id).all() for topic_id in following_topics: following_topic = Following('topic', topic_id) @@ -111,12 +93,27 @@ async def shout_generator(_, info: GraphQLResolveInfo): following_topic_task = following_topic.queue.get() tasks.append(following_topic_task) + # by followed topics + following_authors = session.query(AuthorFollower).where( + AuthorFollower.follower == user_id).all() + for author_id in following_authors: following_author = Following('author', author_id) await FollowingManager.register('author', following_author) following_author_task = following_author.queue.get() tasks.append(following_author_task) + # TODO: use communities + # by followed communities + # following_communities = session.query(CommunityFollower).where( + # CommunityFollower.follower == user_id).all() + + # for community_id in following_communities: + # following_community = Following('community', author_id) + # await FollowingManager.register('community', following_community) + # following_community_task = following_community.queue.get() + # tasks.append(following_community_task) + while True: shout = await asyncio.gather(*tasks) yield shout diff --git a/resolvers/zine/load.py b/resolvers/zine/load.py index 0dfc9468..6c42fad0 100644 --- a/resolvers/zine/load.py +++ b/resolvers/zine/load.py @@ -199,32 +199,45 @@ async def load_shouts_by(_, info, options): @query.field("myFeed") @login_required -async def get_my_feed(_, info): +async def get_my_feed(_, info, options): auth: AuthCredentials = info.context["request"].auth user_id = auth.user_id + + q = select(Shout).options( + joinedload(Shout.authors), + joinedload(Shout.topics), + ).where( + Shout.deletedAt.is_(None) + ) + + q = q.join( + ShoutAuthor + ).join( + AuthorFollower + ).where( + AuthorFollower.follower == user_id + ).join( + ShoutTopic + ).join( + TopicFollower + ).where(TopicFollower.follower == user_id) + + q = add_stat_columns(q) + q = apply_filters(q, options.get("filters", {}), user_id) + + order_by = options.get("order_by", Shout.createdAt) + if order_by == 'reacted': + aliased_reaction = aliased(Reaction) + q.outerjoin(aliased_reaction).add_columns(func.max(aliased_reaction.createdAt).label('reacted')) + + query_order_by = desc(order_by) if options.get('order_by_desc', True) else asc(order_by) + offset = options.get("offset", 0) + limit = options.get("limit", 10) + + q = q.group_by(Shout.id).order_by(query_order_by).limit(limit).offset(offset) + + shouts = [] with local_session() as session: - q = select(Shout).options( - joinedload(Shout.authors), - joinedload(Shout.topics), - ).where( - Shout.deletedAt.is_(None) - ) - - q = q.join( - ShoutAuthor - ).join( - AuthorFollower - ).where( - AuthorFollower.follower == user_id - ).join( - ShoutTopic - ).join( - TopicFollower - ).where(TopicFollower.follower == user_id) - - q = add_stat_columns(q) - - shouts = [] for [shout, reacted_stat, commented_stat, rating_stat] in session.execute(q).unique(): shouts.append(shout) shout.stat = { @@ -234,4 +247,4 @@ async def get_my_feed(_, info): "rating": rating_stat } - return shouts + return shouts diff --git a/schema.graphql b/schema.graphql index f780d0fb..e4f99856 100644 --- a/schema.graphql +++ b/schema.graphql @@ -302,6 +302,7 @@ type Query { userFollowedTopics(slug: String!): [Topic]! authorsAll: [Author]! getAuthor(slug: String!): User + myFeed(options: LoadShoutsOptions): [Shout] # draft/collab loadDrafts: [DraftCollab]!