From ee577c75fdc29b9a2ca5a57ea22f7fa8ecb89bca Mon Sep 17 00:00:00 2001 From: Untone Date: Wed, 21 Feb 2024 11:52:57 +0300 Subject: [PATCH] graphql-schema-update --- CHANGELOG.txt | 1 + resolvers/__init__.py | 10 ++--- resolvers/author.py | 15 ------- resolvers/follower.py | 95 +++++++++++++++++++++++++++---------------- schema/query.graphql | 6 +-- 5 files changed, 69 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 4346d872..1af4856a 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,6 @@ [0.3.2] - redis cache for what author follows +- graphql add query: get topic followers [0.3.1] - enabling sentry diff --git a/resolvers/__init__.py b/resolvers/__init__.py index 1db67072..9936f512 100644 --- a/resolvers/__init__.py +++ b/resolvers/__init__.py @@ -1,7 +1,6 @@ from resolvers.author import ( get_author, get_author_follows, - get_author_followers, get_author_id, get_authors_all, load_authors_by, @@ -10,7 +9,7 @@ from resolvers.author import ( ) from resolvers.community import get_communities_all, get_community from resolvers.editor import create_shout, delete_shout, update_shout -from resolvers.follower import follow, get_my_followed, unfollow +from resolvers.follower import follow, unfollow, get_topic_followers, get_shout_followers, get_author_followers from resolvers.reaction import ( create_reaction, delete_reaction, @@ -39,9 +38,8 @@ __all__ = [ # author "get_author", "get_author_id", - "get_authors_all", - "get_author_followers", "get_author_follows", + "get_authors_all", "load_authors_by", "rate_author", "update_author", @@ -65,7 +63,9 @@ __all__ = [ # follower "follow", "unfollow", - "get_my_followed", + "get_topic_followers", + "get_shout_followers", + "get_author_followers", # editor "create_shout", "update_shout", diff --git a/resolvers/author.py b/resolvers/author.py index ee1d5138..cdb16010 100644 --- a/resolvers/author.py +++ b/resolvers/author.py @@ -265,21 +265,6 @@ async def get_author_follows( raise ValueError("Author not found") -@query.field("get_author_followers") -async def get_author_followers(_, _info, slug) -> List[Author]: - q = select(Author) - q = add_author_stat_columns(q) - - aliased_author = aliased(Author) - q = ( - q.join(AuthorFollower, AuthorFollower.follower == Author.id) - .join(aliased_author, aliased_author.id == AuthorFollower.author) - .where(aliased_author.slug == slug) - ) - - return await get_authors_from_query(q) - - @mutation.field("rate_author") @login_required async def rate_author(_, info, rated_slug, value): diff --git a/resolvers/follower.py b/resolvers/follower.py index 82252447..58796049 100644 --- a/resolvers/follower.py +++ b/resolvers/follower.py @@ -1,5 +1,6 @@ from typing import List +from sqlalchemy import select, or_ from sqlalchemy.orm import aliased from sqlalchemy.sql import and_ @@ -8,8 +9,9 @@ from orm.community import Community from orm.reaction import Reaction from orm.shout import Shout, ShoutReactionsFollower from orm.topic import Topic, TopicFollower +from resolvers.author import add_author_stat_columns, get_authors_from_query from resolvers.community import community_follow, community_unfollow -from resolvers.topic import topic_follow, topic_unfollow +from resolvers.topic import topic_follow, topic_unfollow, add_topic_stat_columns, get_topics_from_query from services.auth import login_required from services.db import local_session from services.notify import notify_follower @@ -121,42 +123,17 @@ def query_follows(user_id: str): async def get_follows_by_user_id(user_id: str): - redis_key = f"user:{user_id}:follows" - res = await redis.execute("HGET", redis_key) - if res: - return res + if user_id: + redis_key = f"user:{user_id}:follows" + res = await redis.execute("HGET", redis_key) + if res: + return res - logger.info(f"getting follows for {user_id}") - follows = query_follows(user_id) - await redis.execute("HSET", redis_key, follows) + logger.debug(f"getting follows for {user_id}") + follows = query_follows(user_id) + await redis.execute("HSET", redis_key, follows) - return follows - - -@query.field("get_my_followed") -@login_required -async def get_my_followed(_, info): - user_id = info.context["user_id"] - return await get_follows_by_user_id(user_id) - - -@query.field("get_shout_followers") -def get_shout_followers( - _, _info, slug: str = "", shout_id: int | None = None -) -> List[Author]: - followers = [] - with local_session() as session: - shout = None - if slug: - shout = session.query(Shout).filter(Shout.slug == slug).first() - elif shout_id: - shout = session.query(Shout).filter(Shout.id == shout_id).first() - if shout: - reactions = session.query(Reaction).filter(Reaction.shout == shout.id).all() - for r in reactions: - followers.append(r.created_by) - - return followers + return follows def reactions_follow(author_id, shout_id, auto=False): @@ -238,3 +215,51 @@ def author_unfollow(follower_id, slug): session.commit() return True return False + + +@query.field("get_topic_followers") +async def get_topic_followers(_, _info, slug: str, topic_id: int) -> List[Author]: + q = select(Author) + q = add_topic_stat_columns(q) + + q = ( + q.join(TopicFollower, TopicFollower.follower == Author.id) + .join(Topic, Topic.id == TopicFollower.topic) + .filter(or_(Topic.slug == slug, Topic.id == topic_id)) + ) + + return await get_topics_from_query(q) + + +@query.field("get_author_followers") +async def get_author_followers(_, _info, slug) -> List[Author]: + q = select(Author) + q = add_author_stat_columns(q) + + aliased_author = aliased(Author) + q = ( + q.join(AuthorFollower, AuthorFollower.follower == Author.id) + .join(aliased_author, aliased_author.id == AuthorFollower.author) + .where(aliased_author.slug == slug) + ) + + return await get_authors_from_query(q) + + +@query.field("get_shout_followers") +def get_shout_followers( + _, _info, slug: str = "", shout_id: int | None = None +) -> List[Author]: + followers = [] + with local_session() as session: + shout = None + if slug: + shout = session.query(Shout).filter(Shout.slug == slug).first() + elif shout_id: + shout = session.query(Shout).filter(Shout.id == shout_id).first() + if shout: + reactions = session.query(Reaction).filter(Reaction.shout == shout.id).all() + for r in reactions: + followers.append(r.created_by) + + return followers diff --git a/schema/query.graphql b/schema/query.graphql index b4215505..b20fc94a 100644 --- a/schema/query.graphql +++ b/schema/query.graphql @@ -3,8 +3,6 @@ type Query { get_author(slug: String, author_id: Int): Author get_author_id(user: String!): Author get_authors_all: [Author] - get_author_followers(slug: String, user: String, author_id: Int): [Author] - get_author_follows(slug: String, user: String, author_id: Int): AuthorFollows! load_authors_by(by: AuthorsBy!, limit: Int, offset: Int): [Author] # community @@ -15,8 +13,10 @@ type Query { get_shouts_drafts: [Shout] # follower - get_my_followed: CommonResult! # { authors topics communities } get_shout_followers(slug: String, shout_id: Int): [Author] + get_topic_followers(slug: String, topic_id: Int): [Author] + get_author_followers(slug: String, user: String, author_id: Int): [Author] + get_author_follows(slug: String, user: String, author_id: Int): AuthorFollows! # reaction load_reactions_by(by: ReactionBy!, limit: Int, offset: Int): [Reaction]