get Shout with additional info

This commit is contained in:
knst-kotov 2021-09-24 17:39:37 +03:00
parent d640938c15
commit 9a5ec80b12
3 changed files with 51 additions and 16 deletions

View File

@ -4,8 +4,9 @@ from orm.user import User
from orm.message import Message
from orm.topic import Topic
from orm.notification import Notification
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay
from orm.base import Base, engine
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay,\
ShoutRatingStorage, ShoutViewStorage
from orm.base import Base, engine, local_session
from orm.comment import Comment
__all__ = ["User", "Role", "Operation", "Permission", "Message", "Shout", "Topic", "Notification"]
@ -13,3 +14,7 @@ __all__ = ["User", "Role", "Operation", "Permission", "Message", "Shout", "Topic
Base.metadata.create_all(engine)
Operation.init_table()
Resource.init_table()
with local_session() as session:
rating_storage = ShoutRatingStorage(session)
view_storage = ShoutViewStorage(session)

View File

@ -6,6 +6,8 @@ from orm import Permission, User, Topic
from orm.comment import Comment
from orm.base import Base
from functools import reduce
class ShoutAuthor(Base):
__tablename__ = "shout_author"
@ -36,6 +38,25 @@ class ShoutRating(Base):
ts: str = Column(DateTime, nullable=False, default = datetime.now, comment="Timestamp")
value = Column(Integer)
class ShoutRatingStorage:
def __init__(self, session):
self.ratings = session.query(ShoutRating).all()
def get_rating(self, shout_id):
shout_ratings = list(filter(lambda x: x.shout_id == shout_id, self.ratings))
return reduce((lambda x, y: x + y.value), shout_ratings, 0)
def update_rating(self, new_rating):
rating = next(x for x in self.ratings \
if x.rater_id == new_rating.rater_id and x.shout_id == new_rating.shout_id)
if rating:
rating.value = new_rating.value
rating.ts = new_rating.ts
else:
self.ratings.append(new_rating)
class ShoutViewByDay(Base):
__tablename__ = "shout_view_by_day"
@ -44,6 +65,18 @@ class ShoutViewByDay(Base):
day: str = Column(DateTime, primary_key = True, default = datetime.now)
value = Column(Integer)
class ShoutViewStorage:
def __init__(self, session):
self.views = session.query(ShoutViewByDay).all()
def get_view(self, shout_id):
shout_views = list(filter(lambda x: x.shout_id == shout_id, self.views))
return reduce((lambda x, y: x + y.value), shout_views, 0)
def add_view(self, view):
self.views.append(view)
class Shout(Base):
__tablename__ = 'shout'
@ -66,7 +99,5 @@ class Shout(Base):
layout: str = Column(String, nullable = True)
authors = relationship(lambda: User, secondary=ShoutAuthor.__tablename__) # NOTE: multiple authors
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__)
ratings = relationship(ShoutRating, foreign_keys=ShoutRating.shout_id)
views = relationship(ShoutViewByDay)
visibleFor = relationship(lambda: User, secondary=ShoutViewer.__tablename__)
old_id: str = Column(String, nullable = True)

View File

@ -1,4 +1,5 @@
from orm import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay, User, Community, Resource
from orm import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay, User, Community, Resource,\
rating_storage, view_storage
from orm.base import local_session
from resolvers.base import mutation, query
@ -12,6 +13,7 @@ from datetime import datetime, timedelta
from pathlib import Path
from sqlalchemy import select, func, desc
from sqlalchemy.orm import selectinload
class GitTask:
@ -258,17 +260,14 @@ async def update_shout(_, info, id, input):
"shout" : shout
}
@query.field("getShoutBySlug") #FIXME: add shout joined with comments
@query.field("getShoutBySlug")
async def get_shout_by_slug(_, info, slug):
with local_session() as session:
stmt = select(Shout, func.sum(ShoutRating.value).label("rating")).\
join(ShoutRating).\
where(Shout.slug == slug).\
limit(limit)
shouts = []
for row in session.execute(stmt):
shout = row.Shout
shout.rating = row.rating
# TODO: shout.comments =
shouts.append(shout)
shout = session.query(Shout).\
options(selectinload(Shout.authors)).\
options(selectinload(Shout.comments)).\
options(selectinload(Shout.topics)).\
filter(Shout.slug == slug).first()
shout.rating = rating_storage.get_rating(shout.id)
shout.views = view_storage.get_view(shout.id)
return shout