diff --git a/resolvers/zine/load.py b/resolvers/zine/load.py index cdb27004..79dcffb9 100644 --- a/resolvers/zine/load.py +++ b/resolvers/zine/load.py @@ -1,6 +1,6 @@ from datetime import datetime, timedelta, timezone import sqlalchemy as sa -from sqlalchemy.orm import joinedload, aliased, make_transient +from sqlalchemy.orm import joinedload, aliased from sqlalchemy.sql.expression import desc, asc, select, case from base.orm import local_session from base.resolvers import query @@ -40,6 +40,32 @@ def add_rating_stat_column(q): )).label('rating_stat')) +# def calc_reactions(q): +# aliased_reaction = aliased(Reaction) +# return q.join(aliased_reaction).add_columns( +# sa.func.sum(case( +# (aliased_reaction.kind == ReactionKind.AGREE, 1), +# (aliased_reaction.kind == ReactionKind.DISAGREE, -1), +# (aliased_reaction.kind == ReactionKind.PROOF, 1), +# (aliased_reaction.kind == ReactionKind.DISPROOF, -1), +# (aliased_reaction.kind == ReactionKind.ACCEPT, 1), +# (aliased_reaction.kind == ReactionKind.REJECT, -1), +# (aliased_reaction.kind == ReactionKind.LIKE, 1), +# (aliased_reaction.kind == ReactionKind.DISLIKE, -1), +# else_=0) +# ).label('rating'), +# sa.func.sum( +# case( +# (aliased_reaction.body.is_not(None), 1), +# else_=0 +# ) +# ).label('commented'), +# sa.func.sum( +# aliased_reaction.id +# ).label('reacted') +# ) + + def apply_filters(q, filters, user=None): filters = {} if filters is None else filters if filters.get("reacted") and user: diff --git a/resolvers/zine/reactions.py b/resolvers/zine/reactions.py index a0abafb8..5647c253 100644 --- a/resolvers/zine/reactions.py +++ b/resolvers/zine/reactions.py @@ -205,16 +205,6 @@ async def delete_reaction(_, info, rid): session.commit() return {} - -def map_result_item(result_item): - [user, shout, reaction] = result_item - print(reaction) - reaction.createdBy = user - reaction.shout = shout - reaction.replyTo = reaction - return reaction - - @query.field("loadReactionsBy") async def load_reactions_by(_, _info, by, limit=50, offset=0): """ @@ -235,15 +225,12 @@ async def load_reactions_by(_, _info, by, limit=50, offset=0): CreatedByUser = aliased(User) ReactedShout = aliased(Shout) - RepliedReaction = aliased(Reaction) q = select( - Reaction, CreatedByUser, ReactedShout, RepliedReaction + Reaction, CreatedByUser, ReactedShout ).join( CreatedByUser, Reaction.createdBy == CreatedByUser.slug ).join( ReactedShout, Reaction.shout == ReactedShout.slug - ).join( - RepliedReaction, Reaction.replyTo == RepliedReaction.id ) if by.get("shout"): @@ -261,23 +248,26 @@ async def load_reactions_by(_, _info, by, limit=50, offset=0): if by.get("days"): after = datetime.now(tz=timezone.utc) - 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, ReactedShout.id ).order_by( order_way(order_field) ) + q = calc_reactions(q) + q = q.where(Reaction.deletedAt.is_(None)) q = q.limit(limit).offset(offset) reactions = [] + with local_session() as session: - for [ - [reaction, rating, commented, reacted], shout, reply - ] in list(map(map_result_item, session.execute(q))): + for [reaction, user, shout, rating, commented, reacted] in session.execute(q): + reaction.createdBy = user reaction.shout = shout - reaction.replyTo = reply reaction.stat = { "rating": rating, "commented": commented, diff --git a/schema.graphql b/schema.graphql index b61f7b43..9933cb35 100644 --- a/schema.graphql +++ b/schema.graphql @@ -152,7 +152,7 @@ type Mutation { updateChat(chat: ChatInput!): Result! deleteChat(chatId: String!): Result! - createMessage(chat: String!, body: String!, replyTo: String): Result! + createMessage(chat: String!, body: String!, replyTo: Int): Result! updateMessage(chatId: String!, id: Int!, body: String!): Result! deleteMessage(chatId: String!, id: Int!): Result! markAsRead(chatId: String!, ids: [Int]!): Result! @@ -410,7 +410,7 @@ type Reaction { range: String # full / 0:2340 kind: ReactionKind! body: String - replyTo: Reaction + replyTo: Int stat: Stat old_id: String old_thread: String