diff --git a/resolvers/zine.py b/resolvers/zine.py index 45161aae..1ed2742c 100644 --- a/resolvers/zine.py +++ b/resolvers/zine.py @@ -1,12 +1,12 @@ +#!/usr/bin/env python3.10 from datetime import datetime, timedelta import sqlalchemy as sa from sqlalchemy.orm import selectinload -from sqlalchemy.sql.expression import or_, desc, asc, select, case -from timeit import default_timer as timer +from sqlalchemy.sql.expression import desc, asc, select, case from auth.authenticate import login_required from base.orm import local_session from base.resolvers import mutation, query -from orm.shout import Shout, ShoutAuthor +from orm.shout import Shout from orm.reaction import Reaction, ReactionKind # from resolvers.community import community_follow, community_unfollow from resolvers.profile import author_follow, author_unfollow @@ -55,7 +55,7 @@ async def load_shouts_by(_, info, options): """ q = select(Shout).options( - # TODO add cation + # TODO add caption selectinload(Shout.authors), selectinload(Shout.topics), ).where( @@ -67,10 +67,7 @@ async def load_shouts_by(_, info, options): user = info.context["request"].user q.join(Reaction, Reaction.createdBy == user.slug) if options.get("filters").get("visibility"): - q = q.filter(or_( - Shout.visibility.ilike(f"%{options.get('filters').get('visibility')}%"), - Shout.visibility.ilike(f"%{'public'}%"), - )) + q = q.filter(Shout.visibility == options.get("filters").get("visibility")) if options.get("filters").get("layout"): q = q.filter(Shout.layout == options.get("filters").get("layout")) if options.get("filters").get("author"): @@ -84,49 +81,43 @@ async def load_shouts_by(_, info, options): if options.get("filters").get("days"): before = datetime.now() - timedelta(days=int(options.get("filter").get("days")) or 30) q = q.filter(Shout.createdAt > before) - - if options.get("order_by") == 'comments': - q = q.join(Reaction, Shout.slug == Reaction.shout and Reaction.body.is_not(None)).add_columns( - sa.func.count(Reaction.id).label(options.get("order_by"))) - if options.get("order_by") == 'reacted': - q = q.join(Reaction).add_columns(sa.func.max(Reaction.createdAt).label(options.get("order_by"))) - if options.get("order_by") == "rating": - q = q.join(Reaction).add_columns(sa.func.sum(case( - (Reaction.kind == ReactionKind.AGREE, 1), - (Reaction.kind == ReactionKind.DISAGREE, -1), - (Reaction.kind == ReactionKind.PROOF, 1), - (Reaction.kind == ReactionKind.DISPROOF, -1), - (Reaction.kind == ReactionKind.ACCEPT, 1), - (Reaction.kind == ReactionKind.REJECT, -1), - (Reaction.kind == ReactionKind.LIKE, 1), - (Reaction.kind == ReactionKind.DISLIKE, -1), - else_=0 - )).label(options.get("order_by"))) - # if order_by == 'views': - # TODO dump ackee data to db periodically - - order_by = options.get("order_by") if options.get("order_by") else 'createdAt' - + o = options.get("order_by") + if o: + q = q.add_columns(sa.func.count(Reaction.id).label(o)) + if o == 'comments': + q = q.join(Reaction, Shout.slug == Reaction.shout) + q = q.filter(Reaction.body.is_not(None)) + elif o == 'reacted': + q = q.join(Reaction).add_columns(sa.func.max( + Reaction.createdAt).label(options.get("order_by"))) + elif o == "rating": + q = q.join(Reaction).add_columns(sa.func.sum(case( + (Reaction.kind == ReactionKind.AGREE, 1), + (Reaction.kind == ReactionKind.DISAGREE, -1), + (Reaction.kind == ReactionKind.PROOF, 1), + (Reaction.kind == ReactionKind.DISPROOF, -1), + (Reaction.kind == ReactionKind.ACCEPT, 1), + (Reaction.kind == ReactionKind.REJECT, -1), + (Reaction.kind == ReactionKind.LIKE, 1), + (Reaction.kind == ReactionKind.DISLIKE, -1), + else_=0 + )).label(options.get("order_by"))) + order_by = o + else: + order_by = 'createdAt' order_by_desc = True if options.get('order_by_desc') is None else options.get('order_by_desc') - query_order_by = desc(order_by) if order_by_desc else asc(order_by) - - q = q.group_by(Shout.id).order_by(query_order_by).limit(options.get("limit")).offset( - options.get("offset") if options.get("offset") else 0) + offset = options.get("offset") if options.get("offset") else 0 + limit = options.get("limit") or 10 + q = q.group_by(Shout.id).order_by(query_order_by).limit(limit).offset(offset) with local_session() as session: - # post query stats and author's captions - # start = timer() shouts = list(map(lambda r: r.Shout, session.execute(q))) for s in shouts: s.stat = await ReactedStorage.get_shout_stat(s.slug) for a in s.authors: a.caption = await ShoutAuthorStorage.get_author_caption(s.slug, a.slug) - # end = timer() - # print(end - start) - # print(q) - return shouts