reactions-api-update
All checks were successful
Deploy on push / deploy (push) Successful in 1m8s

This commit is contained in:
Untone 2024-07-22 10:42:41 +03:00
parent 451f041206
commit a43a44302b
3 changed files with 108 additions and 7 deletions

View File

@ -26,6 +26,8 @@ from resolvers.reaction import (
load_shouts_followed, load_shouts_followed,
load_shouts_followed_by, load_shouts_followed_by,
update_reaction, update_reaction,
load_shout_comments,
load_shout_ratings
) )
from resolvers.reader import ( from resolvers.reader import (
get_shout, get_shout,
@ -36,7 +38,7 @@ from resolvers.reader import (
load_shouts_search, load_shouts_search,
load_shouts_unrated, load_shouts_unrated,
load_shouts_coauthored, load_shouts_coauthored,
load_shouts_discussed, load_shouts_discussed
) )
from resolvers.topic import ( from resolvers.topic import (
get_topic, get_topic,
@ -98,6 +100,8 @@ __all__ = [
"update_reaction", "update_reaction",
"delete_reaction", "delete_reaction",
"load_reactions_by", "load_reactions_by",
"load_shout_comments",
"load_shout_ratings",
# notifier # notifier
"load_notifications", "load_notifications",
"notifications_seen_thread", "notifications_seen_thread",

View File

@ -21,15 +21,15 @@ from services.viewed import ViewedStorage
def add_reaction_stat_columns(q, aliased_reaction): def add_reaction_stat_columns(q, aliased_reaction):
q = q.outerjoin(aliased_reaction).add_columns( q = q.outerjoin(aliased_reaction, aliased_reaction.deleted_at.is_(None)).add_columns(
func.sum(aliased_reaction.id).label("reacted_stat"), func.sum(aliased_reaction.id).label("reacted_stat"),
func.sum(case((aliased_reaction.kind == str(ReactionKind.COMMENT.value), 1), else_=0)).label("comments_stat"), func.sum(case((aliased_reaction.kind == str(ReactionKind.COMMENT.value), 1), else_=0)).label("comments_stat"),
func.sum(case((aliased_reaction.kind == str(ReactionKind.LIKE.value), 1), else_=0)).label("likes_stat"), func.sum(case((aliased_reaction.kind == str(ReactionKind.LIKE.value), 1), else_=0)).label("likes_stat"),
func.sum(case((aliased_reaction.kind == str(ReactionKind.DISLIKE.value), 1), else_=0)).label("dislikes_stat"), func.sum(case((aliased_reaction.kind == str(ReactionKind.DISLIKE.value), 1), else_=0)).label("dislikes_stat"),
func.max( func.max(
case( case(
(aliased_reaction.kind != str(ReactionKind.COMMENT.value), None), (aliased_reaction.kind == str(ReactionKind.COMMENT.value), aliased_reaction.created_at),
else_=aliased_reaction.created_at, else_=None,
) )
).label("last_comment_stat"), ).label("last_comment_stat"),
) )
@ -37,6 +37,8 @@ def add_reaction_stat_columns(q, aliased_reaction):
return q return q
def is_featured_author(session, author_id): def is_featured_author(session, author_id):
"""checks if author has at least one featured publication""" """checks if author has at least one featured publication"""
return ( return (
@ -432,7 +434,7 @@ async def load_reactions_by(_, info, by, limit=50, offset=0):
"reacted": reacted_stat, "reacted": reacted_stat,
"commented": commented_stat, "commented": commented_stat,
} }
reactions.add(reaction) # Используем список для хранения реакций reactions.add(reaction)
return reactions return reactions
@ -447,7 +449,7 @@ async def reacted_shouts_updates(follower_id: int, limit=50, offset=0) -> List[S
select(Shout) select(Shout)
.outerjoin( .outerjoin(
Reaction, Reaction,
and_(Reaction.shout == Shout.id, Reaction.created_by == follower_id), and_(Reaction.shout == Shout.id, Reaction.created_by == follower_id, Reaction.deleted_at.is_(None)),
) )
.outerjoin(Author, Shout.authors.any(id=follower_id)) .outerjoin(Author, Shout.authors.any(id=follower_id))
.options(joinedload(Shout.reactions), joinedload(Shout.authors)) .options(joinedload(Shout.reactions), joinedload(Shout.authors))
@ -460,7 +462,7 @@ async def reacted_shouts_updates(follower_id: int, limit=50, offset=0) -> List[S
select(Shout) select(Shout)
.join(Reaction, Reaction.shout == Shout.id) .join(Reaction, Reaction.shout == Shout.id)
.options(joinedload(Shout.reactions), joinedload(Shout.authors)) .options(joinedload(Shout.reactions), joinedload(Shout.authors))
.filter(Reaction.created_by == follower_id) .filter(and_(Reaction.created_by == follower_id, Reaction.deleted_at.is_(None)))
.group_by(Shout.id) .group_by(Shout.id)
) )
q2 = add_reaction_stat_columns(q2, aliased(Reaction)) q2 = add_reaction_stat_columns(q2, aliased(Reaction))
@ -517,3 +519,96 @@ async def load_shouts_followed_by(_, info, slug: str, limit=50, offset=0) -> Lis
except Exception as error: except Exception as error:
logger.debug(error) logger.debug(error)
return [] return []
@query.field("load_shout_ratings")
async def load_shout_ratings(_, info, shout: int, limit=100, offset=0):
"""
get paginated reactions with no stats
:param info: graphql meta
:param shout: int shout id
:param limit: int amount of shouts
:param offset: int offset in this order
:return: Reaction[]
"""
q = (
select(Reaction, Author, Shout)
.select_from(Reaction)
.join(Author, Reaction.created_by == Author.id)
.join(Shout, Reaction.shout == Shout.id)
)
# filter, group, order, limit, offset
q = q.filter(and_(Reaction.deleted_at.is_(None), Reaction.shout == shout, Reaction.kind.in_(RATING_REACTIONS)))
q = q.group_by(Reaction.id)
q = q.order_by(desc(Reaction.created_at))
q = q.limit(limit).offset(offset)
reactions = set()
with local_session() as session:
result_rows = session.execute(q)
for [
reaction,
author,
shout,
] in result_rows:
reaction.created_by = author
reaction.shout = shout
reactions.add(reaction)
return reactions
@query.field("load_shout_comments")
async def load_shout_comments(_, info, shout: int, limit=50, offset=0):
"""
getting paginated comments with stats
:param info: graphql meta
:param shout: int shout id
:param limit: int amount of shouts
:param offset: int offset in this order
:return: Reaction[]
"""
q = (
select(Reaction, Author, Shout)
.select_from(Reaction)
.join(Author, Reaction.created_by == Author.id)
.join(Shout, Reaction.shout == Shout.id)
)
# calculate counters
aliased_reaction = aliased(Reaction)
q = add_reaction_stat_columns(q, aliased_reaction)
# filter, group, order, limit, offset
q = q.filter(and_(Reaction.deleted_at.is_(None), Reaction.shout == shout, Reaction.body.is_not(None)))
q = q.group_by(Reaction.id)
q = q.order_by(desc(Reaction.created_at))
q = q.limit(limit).offset(offset)
reactions = set()
with local_session() as session:
result_rows = session.execute(q)
for [
reaction,
author,
shout,
reacted_stat,
commented_stat,
likes_stat,
dislikes_stat,
_last_comment,
] in result_rows:
reaction.created_by = author
reaction.shout = shout
reaction.stat = {
"rating": int(likes_stat or 0) - int(dislikes_stat or 0),
"reacted": reacted_stat,
"commented": commented_stat,
}
reactions.add(reaction)
return reactions

View File

@ -27,6 +27,8 @@ type Query {
# reader # reader
get_shout(slug: String): Shout get_shout(slug: String): Shout
load_shouts_by(options: LoadShoutsOptions): [Shout] load_shouts_by(options: LoadShoutsOptions): [Shout]
load_shout_comments(shout: Int!, limit: Int, offset: Int): [Reaction]
load_shout_ratings(shout: Int!, limit: Int, offset: Int): [Reaction]
load_shouts_search(text: String!, limit: Int, offset: Int): [SearchResult] load_shouts_search(text: String!, limit: Int, offset: Int): [SearchResult]
load_shouts_feed(options: LoadShoutsOptions): [Shout] load_shouts_feed(options: LoadShoutsOptions): [Shout]
load_shouts_unrated(limit: Int, offset: Int): [Shout] load_shouts_unrated(limit: Int, offset: Int): [Shout]