reviewed resolvers

This commit is contained in:
tonyrewin 2022-09-22 13:31:44 +03:00
parent c292d7da55
commit 64914028fb
8 changed files with 77 additions and 68 deletions

View File

@ -75,7 +75,7 @@ async def get_user_collections(_, _info, userslug):
collections = ( collections = (
session.query(Collection) session.query(Collection)
.where( .where(
and_(Collection.createdBy == userslug, bool(Collection.publishedAt)) and_(Collection.createdBy == userslug, Collection.publishedAt.is_not(None))
) )
.all() .all()
) )

View File

@ -3,9 +3,9 @@ from datetime import datetime
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 from base.resolvers import mutation
from orm import Shout
from orm.rbac import Resource from orm.rbac import Resource
from orm.shout import ShoutAuthor, ShoutTopic from orm.shout import Shout, ShoutAuthor, ShoutTopic
from orm.topic import TopicFollower
from orm.user import User from orm.user import User
from resolvers.reactions import reactions_follow, reactions_unfollow from resolvers.reactions import reactions_follow, reactions_unfollow
from services.zine.gittask import GitTask from services.zine.gittask import GitTask
@ -20,22 +20,33 @@ async def create_shout(_, info, inp):
if topic_slugs: if topic_slugs:
del inp["topic_slugs"] del inp["topic_slugs"]
new_shout = Shout.create(**inp) with local_session() as session:
ShoutAuthor.create(shout=new_shout.slug, user=user.slug) new_shout = Shout.create(**inp)
reactions_follow(user, new_shout.slug, True) # NOTE: shout made by one first author
sa = ShoutAuthor.create(shout=new_shout.slug, user=user.slug)
session.add(sa)
if "mainTopic" in inp: reactions_follow(user, new_shout.slug, True)
topic_slugs.append(inp["mainTopic"])
for slug in topic_slugs: if "mainTopic" in inp:
ShoutTopic.create(shout=new_shout.slug, topic=slug) topic_slugs.append(inp["mainTopic"])
new_shout.topic_slugs = topic_slugs
for slug in topic_slugs:
st = ShoutTopic.create(shout=new_shout.slug, topic=slug)
session.add(st)
tf = session.query(TopicFollower).where(follower=user.slug, topic=slug)
if not tf:
tf = TopicFollower.create(follower=user.slug, topic=slug, auto=True)
session.add(tf)
new_shout.topic_slugs = topic_slugs
session.add(new_shout)
session.commit()
GitTask(inp, user.username, user.email, "new shout %s" % (new_shout.slug)) GitTask(inp, user.username, user.email, "new shout %s" % (new_shout.slug))
# await ShoutCommentsStorage.send_shout(new_shout)
return {"shout": new_shout} return {"shout": new_shout}
@ -44,31 +55,28 @@ async def create_shout(_, info, inp):
async def update_shout(_, info, inp): async def update_shout(_, info, inp):
auth = info.context["request"].auth auth = info.context["request"].auth
user_id = auth.user_id user_id = auth.user_id
slug = inp["slug"] slug = inp["slug"]
session = local_session() with local_session() as session:
user = session.query(User).filter(User.id == user_id).first() user = session.query(User).filter(User.id == user_id).first()
shout = session.query(Shout).filter(Shout.slug == slug).first() shout = session.query(Shout).filter(Shout.slug == slug).first()
if not shout:
return {"error": "shout not found"}
if not shout: authors = [author.id for author in shout.authors]
return {"error": "shout not found"} if user_id not in authors:
scopes = auth.scopes
authors = [author.id for author in shout.authors] print(scopes)
if user_id not in authors: if Resource.shout_id not in scopes:
scopes = auth.scopes return {"error": "access denied"}
print(scopes) else:
if Resource.shout_id not in scopes: shout.update(inp)
return {"error": "access denied"} shout.updatedAt = datetime.now()
session.add(shout)
shout.update(inp) for topic in inp.get("topic_slugs", []):
shout.updatedAt = datetime.now() st = ShoutTopic.create(shout=slug, topic=topic)
session.add(shout) session.add(st)
session.commit() session.commit()
session.close()
for topic in inp.get("topic_slugs", []):
ShoutTopic.create(shout=slug, topic=topic)
GitTask(inp, user.username, user.email, "update shout %s" % (slug)) GitTask(inp, user.username, user.email, "update shout %s" % (slug))

View File

@ -35,7 +35,7 @@ async def get_user_feed(_, info, offset, limit) -> List[Shout]:
return shouts return shouts
@query.field("myCandidates") @query.field("recentCandidates")
@login_required @login_required
async def user_unpublished_shouts(_, info, offset, limit) -> List[Shout]: async def user_unpublished_shouts(_, info, offset, limit) -> List[Shout]:
user = info.context["request"].user user = info.context["request"].user
@ -43,7 +43,7 @@ async def user_unpublished_shouts(_, info, offset, limit) -> List[Shout]:
shouts = prepare_shouts( shouts = prepare_shouts(
session.query(Shout) session.query(Shout)
.join(ShoutAuthor) .join(ShoutAuthor)
.where(and_(not bool(Shout.publishedAt), ShoutAuthor.user == user.slug)) .where(and_(Shout.publishedAt.is_(None), ShoutAuthor.user == user.slug))
.order_by(desc(Shout.createdAt)) .order_by(desc(Shout.createdAt))
.limit(limit) .limit(limit)
.offset(offset) .offset(offset)

View File

@ -1,6 +1,6 @@
from datetime import datetime from datetime import datetime
from sqlalchemy import desc from sqlalchemy import desc, 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
@ -22,14 +22,14 @@ async def get_reaction_stat(reaction_id):
} }
def reactions_follow(user, slug, auto=False): def reactions_follow(user: User, slug: str, auto=False):
with local_session() as session: with local_session() as session:
following = ( following = (
session.query(ShoutReactionsFollower) session.query(ShoutReactionsFollower)
.filter( .where(and_(
ShoutReactionsFollower.follower == user.slug, ShoutReactionsFollower.follower == user.slug,
ShoutReactionsFollower.shout == slug ShoutReactionsFollower.shout == slug
) ))
.first() .first()
) )
if not following: if not following:
@ -46,10 +46,10 @@ def reactions_unfollow(user, slug):
with local_session() as session: with local_session() as session:
following = ( following = (
session.query(ShoutReactionsFollower) session.query(ShoutReactionsFollower)
.filter( .where(and_(
ShoutReactionsFollower.follower == user.slug, ShoutReactionsFollower.follower == user.slug,
ShoutReactionsFollower.shout == slug, ShoutReactionsFollower.shout == slug
) ))
.first() .first()
) )
if following: if following:
@ -83,7 +83,7 @@ async def update_reaction(_, info, inp):
user_id = auth.user_id user_id = auth.user_id
with local_session() as session: with local_session() as session:
user = session.query(User).filter(User.id == user_id).first() user = session.query(User).where(User.id == user_id).first()
reaction = session.query(Reaction).filter(Reaction.id == inp.id).first() reaction = session.query(Reaction).filter(Reaction.id == inp.id).first()
if not reaction: if not reaction:
return {"error": "invalid reaction id"} return {"error": "invalid reaction id"}
@ -109,7 +109,7 @@ async def delete_reaction(_, info, rid):
auth = info.context["request"].auth auth = info.context["request"].auth
user_id = auth.user_id user_id = auth.user_id
with local_session() as session: with local_session() as session:
user = session.query(User).filter(User.id == user_id).first() user = session.query(User).where(User.id == user_id).first()
reaction = session.query(Reaction).filter(Reaction.id == rid).first() reaction = session.query(Reaction).filter(Reaction.id == rid).first()
if not reaction: if not reaction:
return {"error": "invalid reaction id"} return {"error": "invalid reaction id"}
@ -145,7 +145,7 @@ async def get_reactions_for_shouts(_, info, shouts, offset, limit):
reactions += ( reactions += (
session.query(Reaction) session.query(Reaction)
.filter(Reaction.shout == slug) .filter(Reaction.shout == slug)
.where(not bool(Reaction.deletedAt)) .where(Reaction.deletedAt.is_not(None))
.order_by(desc("createdAt")) .order_by(desc("createdAt"))
.offset(offset) .offset(offset)
.limit(limit) .limit(limit)
@ -163,7 +163,7 @@ async def get_reactions_by_author(_, info, slug, limit=50, offset=0):
with local_session() as session: with local_session() as session:
reactions = ( reactions = (
session.query(Reaction) session.query(Reaction)
.filter(Reaction.createdBy == slug) .where(Reaction.createdBy == slug)
.limit(limit) .limit(limit)
.offset(offset) .offset(offset)
) )

View File

@ -56,7 +56,11 @@ async def topics_by_author(_, _info, author):
@mutation.field("createTopic") @mutation.field("createTopic")
@login_required @login_required
async def create_topic(_, _info, inp): async def create_topic(_, _info, inp):
new_topic = Topic.create(**inp) with local_session() as session:
# TODO: check user permissions to create topic for exact community
new_topic = Topic.create(**inp)
session.add(new_topic)
session.commit()
await TopicStorage.update_topic(new_topic) await TopicStorage.update_topic(new_topic)
return {"topic": new_topic} return {"topic": new_topic}

View File

@ -97,14 +97,14 @@ async def get_shout_by_slug(_, info, slug):
@query.field("searchQuery") @query.field("searchQuery")
async def get_search_results(_, _info, query, offset, limit): async def get_search_results(_, _info, searchtext, offset, limit):
# TODO: remove the copy of searchByTopics # TODO: remove the copy of searchByTopics
# with search ranking query # with search ranking query
with local_session() as session: with local_session() as session:
shouts = ( shouts = (
session.query(Shout) session.query(Shout)
.join(ShoutTopic) .join(ShoutTopic)
.where(and_(ShoutTopic.topic.in_(query), bool(Shout.publishedAt))) .where(and_(ShoutTopic.topic.in_(searchtext), Shout.publishedAt.is_not(None)))
.order_by(desc(Shout.publishedAt)) .order_by(desc(Shout.publishedAt))
.limit(limit) .limit(limit)
.offset(offset) .offset(offset)
@ -123,7 +123,7 @@ async def shouts_by_topics(_, _info, slugs, offset, limit):
shouts = ( shouts = (
session.query(Shout) session.query(Shout)
.join(ShoutTopic) .join(ShoutTopic)
.where(and_(ShoutTopic.topic.in_(slugs), bool(Shout.publishedAt))) .where(and_(ShoutTopic.topic.in_(slugs), Shout.publishedAt.is_not(None)))
.order_by(desc(Shout.publishedAt)) .order_by(desc(Shout.publishedAt))
.limit(limit) .limit(limit)
.offset(offset) .offset(offset)
@ -141,8 +141,8 @@ async def shouts_by_collection(_, _info, collection, offset, limit):
shouts = ( shouts = (
session.query(Shout) session.query(Shout)
.join(ShoutCollection, ShoutCollection.collection == collection) .join(ShoutCollection, ShoutCollection.collection == collection)
.where(and_(ShoutCollection.shout == Shout.slug, bool(Shout.publishedAt))) .where(and_(ShoutCollection.shout == Shout.slug, Shout.publishedAt.is_not(None)))
.order_by(desc(Shout.publishedAt)) .order_by(desc("publishedAt"))
.limit(limit) .limit(limit)
.offset(offset) .offset(offset)
) )
@ -158,7 +158,7 @@ async def shouts_by_authors(_, _info, slugs, offset, limit):
shouts = ( shouts = (
session.query(Shout) session.query(Shout)
.join(ShoutAuthor) .join(ShoutAuthor)
.where(and_(ShoutAuthor.user.in_(slugs), bool(Shout.publishedAt))) .where(and_(ShoutAuthor.user.in_(slugs), Shout.publishedAt.is_not(None)))
.order_by(desc(Shout.publishedAt)) .order_by(desc(Shout.publishedAt))
.limit(limit) .limit(limit)
.offset(offset) .offset(offset)
@ -186,7 +186,7 @@ async def shouts_by_communities(_, info, slugs, offset, limit):
.join(ShoutTopic) .join(ShoutTopic)
.where( .where(
and_( and_(
bool(Shout.publishedAt), Shout.publishedAt.is_not(None),
ShoutTopic.topic.in_( ShoutTopic.topic.in_(
select(Topic.slug).where(Topic.community.in_(slugs)) select(Topic.slug).where(Topic.community.in_(slugs))
), ),

View File

@ -228,7 +228,6 @@ type Query {
shoutsByTopics(slugs: [String]!, offset: Int!, limit: Int!): [Shout]! shoutsByTopics(slugs: [String]!, offset: Int!, limit: Int!): [Shout]!
shoutsByAuthors(slugs: [String]!, offset: Int!, limit: Int!): [Shout]! shoutsByAuthors(slugs: [String]!, offset: Int!, limit: Int!): [Shout]!
shoutsByCommunities(slugs: [String]!, offset: Int!, limit: Int!): [Shout]! shoutsByCommunities(slugs: [String]!, offset: Int!, limit: Int!): [Shout]!
myCandidates(offset: Int!, limit: Int!): [Shout]! # test
# topReacted(offset: Int!, limit: Int!): [Shout]! # topReacted(offset: Int!, limit: Int!): [Shout]!
topAuthors(offset: Int!, limit: Int!): [Author]! # by User.rating topAuthors(offset: Int!, limit: Int!): [Author]! # by User.rating
topPublished(daysago: Int!, offset: Int!, limit: Int!): [Shout]! topPublished(daysago: Int!, offset: Int!, limit: Int!): [Shout]!
@ -239,6 +238,7 @@ type Query {
recentReacted(offset: Int!, limit: Int!): [Shout]! # TODO: use in design! recentReacted(offset: Int!, limit: Int!): [Shout]! # TODO: use in design!
recentCommented(offset: Int!, limit: Int!): [Shout]! recentCommented(offset: Int!, limit: Int!): [Shout]!
recentAll(offset: Int!, limit: Int!): [Shout]! recentAll(offset: Int!, limit: Int!): [Shout]!
recentCandidates(offset: Int!, limit: Int!): [Shout]!
# reactons # reactons
reactionsByAuthor(slug: String!, offset: Int!, limit: Int!): [Reaction]! reactionsByAuthor(slug: String!, offset: Int!, limit: Int!): [Reaction]!

View File

@ -123,7 +123,7 @@ class ShoutsCache:
reactions = session.query(Reaction).order_by(Reaction.createdAt).limit(ShoutsCache.limit) reactions = session.query(Reaction).order_by(Reaction.createdAt).limit(ShoutsCache.limit)
commented_slugs = set([]) commented_slugs = set([])
for r in reactions: for r in reactions:
if bool(r.body): if len(r.body) > 0:
commented_slugs.add(r.shout) commented_slugs.add(r.shout)
shouts = await prepare_shouts( shouts = await prepare_shouts(
session, session,
@ -156,18 +156,18 @@ class ShoutsCache:
( (
select( select(
Shout, Shout,
func.sum(int(bool(Reaction.kind == ReactionKind.LIKE))).label('liked') func.sum(Reaction.id).label('reacted')
) )
.options( .options(
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics), selectinload(Shout.topics),
selectinload(Shout.reactions), selectinload(Shout.reactions),
) )
.join(Reaction) .join(Reaction, Reaction.kind == ReactionKind.LIKE)
.where(Shout.deletedAt.is_(None)) .where(Shout.deletedAt.is_(None))
.filter(Shout.publishedAt.is_not(None)) .filter(Shout.publishedAt.is_not(None))
.group_by(Shout.slug) .group_by(Shout.slug)
.order_by(desc("liked")) .order_by(desc("reacted"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
), ),
) )
@ -183,10 +183,7 @@ class ShoutsCache:
shouts = await prepare_shouts( shouts = await prepare_shouts(
session, session,
( (
select( select(Shout)
Shout,
func.sum(int(bool(Reaction.kind == ReactionKind.LIKE))).label('liked')
)
.options( .options(
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics), selectinload(Shout.topics),
@ -196,7 +193,6 @@ class ShoutsCache:
.where(Shout.deletedAt.is_(None)) .where(Shout.deletedAt.is_(None))
.filter(Shout.publishedAt > month_ago) .filter(Shout.publishedAt > month_ago)
.group_by(Shout.slug) .group_by(Shout.slug)
.order_by(desc("liked"))
.limit(ShoutsCache.limit) .limit(ShoutsCache.limit)
), ),
) )
@ -214,14 +210,14 @@ class ShoutsCache:
( (
select( select(
Shout, Shout,
func.sum(int(bool(Reaction.body))).label("commented") func.sum(Reaction.id).label("commented")
) )
.options( .options(
selectinload(Shout.authors), selectinload(Shout.authors),
selectinload(Shout.topics), selectinload(Shout.topics),
selectinload(Shout.reactions) selectinload(Shout.reactions)
) )
.join(Reaction) .join(Reaction, func.length(Reaction.body) > 0)
.where(Shout.deletedAt.is_(None)) .where(Shout.deletedAt.is_(None))
.filter(Shout.publishedAt > month_ago) .filter(Shout.publishedAt > month_ago)
.group_by(Shout.slug) .group_by(Shout.slug)
@ -255,6 +251,7 @@ class ShoutsCache:
for s in ShoutsCache.recent_published: for s in ShoutsCache.recent_published:
if s.publishedAt >= before: if s.publishedAt >= before:
shouts_by_rating.append(s) shouts_by_rating.append(s)
shouts_by_rating.sort(lambda s: s.stat["rating"], reverse=True)
return shouts_by_rating return shouts_by_rating
@staticmethod @staticmethod