From 5ecb0d811bfaddb4bb9a7e5044c5adc67d9b396f Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Wed, 23 Nov 2022 03:05:34 +0100 Subject: [PATCH] load reactions with user --- resolvers/zine/reactions.py | 89 ++++++++++++++++++++----------------- server.py | 2 +- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/resolvers/zine/reactions.py b/resolvers/zine/reactions.py index 6423dc71..f74d6ee7 100644 --- a/resolvers/zine/reactions.py +++ b/resolvers/zine/reactions.py @@ -1,6 +1,7 @@ from datetime import datetime, timedelta +from sqlalchemy import and_, asc, desc, select, text, func, column +from sqlalchemy.orm import aliased -from sqlalchemy import and_, asc, desc, select, text, func from auth.authenticate import login_required from base.orm import local_session from base.resolvers import mutation, query @@ -23,11 +24,11 @@ def reactions_follow(user: User, slug: str, auto=False): with local_session() as session: following = ( session.query(ShoutReactionsFollower) - .where(and_( + .where(and_( ShoutReactionsFollower.follower == user.slug, ShoutReactionsFollower.shout == slug )) - .first() + .first() ) if not following: following = ShoutReactionsFollower.create( @@ -43,11 +44,11 @@ def reactions_unfollow(user, slug): with local_session() as session: following = ( session.query(ShoutReactionsFollower) - .where(and_( + .where(and_( ShoutReactionsFollower.follower == user.slug, ShoutReactionsFollower.shout == slug )) - .first() + .first() ) if following: session.delete(following) @@ -198,32 +199,11 @@ async def delete_reaction(_, info, rid): session.commit() return {} - -def prepare_reactions(q, by): - """ query filters and order """ - if by.get("shout"): - q = q.filter(Reaction.shout == by["shout"]) - elif by.get("shouts"): - q = q.filter(Reaction.shout.in_(by["shouts"])) - if by.get("createdBy"): - q = q.filter(Reaction.createdBy == by.get("createdBy")) - if by.get("topic"): - q = q.filter(Shout.topics.contains(by["topic"])) - if by.get("comment"): - q = q.filter(func.length(Reaction.body) > 0) - if by.get('search', 0) > 2: - q = q.filter(Reaction.body.ilike(f'%{by["body"]}%')) - if by.get("days"): - after = datetime.now() - timedelta(days=int(by["days"]) or 30) - q = q.filter(Reaction.createdAt > after) - order_way = asc if by.get("sort", "").startswith("-") else desc - order_field = by.get("sort") or Reaction.createdAt - q = q.group_by( - Reaction.id - ).order_by( - order_way(order_field) - ) - return q +def map_result_item(result_item): + reaction = result_item[0] + user = result_item[1] + reaction.createdBy = user + return reaction @query.field("loadReactionsBy") @@ -243,18 +223,45 @@ async def load_reactions_by(_, _info, by, limit=50, offset=0): :param offset: int offset in this order :return: Reaction[] """ + + CreatedByUser = aliased(User) + q = select( - Reaction - ).join( - User, Reaction.createdBy == User.slug + Reaction, CreatedByUser + ).join(CreatedByUser, Reaction.createdBy == CreatedByUser.slug) + + if by.get("shout"): + q = q.filter(Reaction.shout == by["shout"]) + elif by.get("shouts"): + q = q.filter(Reaction.shout.in_(by["shouts"])) + if by.get("createdBy"): + q = q.filter(Reaction.createdBy == by.get("createdBy")) + if by.get("topic"): + q = q.filter(Shout.topics.contains(by["topic"])) + if by.get("comment"): + q = q.filter(func.length(Reaction.body) > 0) + if by.get('search', 0) > 2: + q = q.filter(Reaction.body.ilike(f'%{by["body"]}%')) + if by.get("days"): + after = datetime.now() - timedelta(days=int(by["days"]) or 30) + q = q.filter(Reaction.createdAt > after) + order_way = asc if by.get("sort", "").startswith("-") else desc + order_field = by.get("sort") or Reaction.createdAt + q = q.group_by( + Reaction.id, CreatedByUser.id + ).order_by( + order_way(order_field) ) - q = prepare_reactions(q, by).where(Reaction.deletedAt.is_(None)) + + q = q.where(Reaction.deletedAt.is_(None)) q = q.limit(limit).offset(offset) - rrr = [] + with local_session() as session: - for r in list(map(lambda r: r.Reaction, session.execute(q))): - r.stat = await get_reaction_stat(r.id) - rrr.append(r) + reactions = list(map(map_result_item, session.execute(q))) + for reaction in reactions: + reaction.stat = await get_reaction_stat(reaction.id) + if by.get("stat"): - rrr.sort(lambda r: r.stat.get(by["stat"]) or r.createdAt) - return rrr + reactions.sort(lambda r: r.stat.get(by["stat"]) or r.createdAt) + + return reactions diff --git a/server.py b/server.py index dc7041bc..2cb70715 100644 --- a/server.py +++ b/server.py @@ -74,7 +74,7 @@ if __name__ == "__main__": headers=headers, # log_config=LOGGING_CONFIG, log_level=None, - access_log=True, + access_log=False, reload=True ) # , ssl_keyfile="discours.key", ssl_certfile="discours.crt") elif x == "migrate":