Merge branch 'prepare-comments' of github.com:Discours/discours-backend into prepare-comments

This commit is contained in:
tonyrewin 2022-11-24 07:59:35 +03:00
commit 97ee88aff3
3 changed files with 46 additions and 40 deletions

View File

@ -1,6 +1,6 @@
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.orm import selectinload from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import desc, asc, select, case from sqlalchemy.sql.expression import desc, asc, select, case
from base.orm import local_session from base.orm import local_session
from base.resolvers import query from base.resolvers import query
@ -37,8 +37,8 @@ async def load_shout(_, info, slug):
with local_session() as session: with local_session() as session:
shout = session.query(Shout).options( shout = session.query(Shout).options(
# TODO add cation # TODO add cation
selectinload(Shout.authors), joinedload(Shout.authors),
selectinload(Shout.topics), joinedload(Shout.topics),
).filter( ).filter(
Shout.slug == slug Shout.slug == slug
).filter( ).filter(
@ -48,6 +48,12 @@ async def load_shout(_, info, slug):
return shout return shout
def map_result_item(result_item):
shout = result_item[0]
shout.rating = result_item[1]
return shout
@query.field("loadShouts") @query.field("loadShouts")
async def load_shouts_by(_, info, options): async def load_shouts_by(_, info, options):
""" """
@ -71,14 +77,24 @@ async def load_shouts_by(_, info, options):
""" """
q = select(Shout).options( q = select(Shout).options(
# TODO add caption joinedload(Shout.authors),
selectinload(Shout.authors), joinedload(Shout.topics),
selectinload(Shout.topics),
).where( ).where(
Shout.deletedAt.is_(None) Shout.deletedAt.is_(None)
) )
user = info.context["request"].user user = info.context["request"].user
q = apply_filters(q, options.get("filters"), user) q = apply_filters(q, options.get("filters"), user)
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('rating'))
o = options.get("order_by") o = options.get("order_by")
if o: if o:
@ -92,21 +108,9 @@ async def load_shouts_by(_, info, options):
).add_columns( ).add_columns(
sa.func.max(Reaction.createdAt).label(o) sa.func.max(Reaction.createdAt).label(o)
) )
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(o))
order_by = o order_by = o
else: else:
order_by = 'createdAt' order_by = Shout.createdAt
order_by_desc = True if options.get('order_by_desc') is None else options.get('order_by_desc') order_by_desc = True if options.get('order_by_desc') is None else options.get('order_by_desc')
@ -116,10 +120,13 @@ async def load_shouts_by(_, info, options):
q = q.group_by(Shout.id).order_by(query_order_by).limit(limit).offset(offset) q = q.group_by(Shout.id).order_by(query_order_by).limit(limit).offset(offset)
with local_session() as session: with local_session() as session:
shouts = list(map(lambda r: r.Shout, session.execute(q))) shouts = list(map(map_result_item, session.execute(q).unique()))
for s in shouts:
s.stat = await ReactedStorage.get_shout_stat(s.slug) for shout in shouts:
for a in s.authors: shout.stat = await ReactedStorage.get_shout_stat(shout.slug, shout.rating)
a.caption = await ShoutAuthorStorage.get_author_caption(s.slug, a.slug)
del shout.rating
for author in shout.authors:
author.caption = await ShoutAuthorStorage.get_author_caption(shout.slug, author.slug)
return shouts return shouts

View File

@ -1,14 +1,15 @@
import random import sqlalchemy as sa
from sqlalchemy import and_, select
from sqlalchemy import and_
from auth.authenticate import login_required from auth.authenticate import login_required
from base.orm import local_session from base.orm import local_session
from base.resolvers import mutation, query from base.resolvers import mutation, query
from orm import Shout
from orm.topic import Topic, TopicFollower from orm.topic import Topic, TopicFollower
from services.zine.topics import TopicStorage from services.zine.topics import TopicStorage
# from services.stat.reacted import ReactedStorage # from services.stat.reacted import ReactedStorage
from services.stat.topicstat import TopicStat from services.stat.topicstat import TopicStat
# from services.stat.viewed import ViewedStorage # from services.stat.viewed import ViewedStorage
@ -98,10 +99,10 @@ async def topic_unfollow(user, slug):
with local_session() as session: with local_session() as session:
sub = ( sub = (
session.query(TopicFollower) session.query(TopicFollower)
.filter( .filter(
and_(TopicFollower.follower == user.slug, TopicFollower.topic == slug) and_(TopicFollower.follower == user.slug, TopicFollower.topic == slug)
) )
.first() .first()
) )
if not sub: if not sub:
raise Exception("[resolvers.topics] follower not exist") raise Exception("[resolvers.topics] follower not exist")
@ -113,11 +114,8 @@ async def topic_unfollow(user, slug):
@query.field("topicsRandom") @query.field("topicsRandom")
async def topics_random(_, info, amount=12): async def topics_random(_, info, amount=12):
topics = await TopicStorage.get_topics_all() with local_session() as session:
normalized_topics = [] q = select(Topic).join(Shout).group_by(Topic.id).having(sa.func.count(Shout.id) > 2).order_by(
for topic in topics: sa.func.random()).limit(amount)
topic.stat = await get_topic_stat(topic.slug) random_topics = list(map(lambda result_item: result_item.Topic, session.execute(q)))
if topic.stat["shouts"] > 2: return random_topics
normalized_topics.append(topic)
sample_length = min(len(normalized_topics), amount)
return random.sample(normalized_topics, sample_length)

View File

@ -34,14 +34,15 @@ class ReactedStorage:
modified_shouts = set([]) modified_shouts = set([])
@staticmethod @staticmethod
async def get_shout_stat(slug): async def get_shout_stat(slug, rating):
viewed = int(await ViewedStorage.get_shout(slug)) viewed = int(await ViewedStorage.get_shout(slug))
# print(viewed) # print(viewed)
return { return {
"viewed": viewed, "viewed": viewed,
"reacted": len(await ReactedStorage.get_shout(slug)), "reacted": len(await ReactedStorage.get_shout(slug)),
"commented": len(await ReactedStorage.get_comments(slug)), "commented": len(await ReactedStorage.get_comments(slug)),
"rating": await ReactedStorage.get_rating(slug), # "rating": await ReactedStorage.get_rating(slug),
"rating": rating
} }
@staticmethod @staticmethod