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.message import Message
from orm.topic import Topic from orm.topic import Topic
from orm.notification import Notification from orm.notification import Notification
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay,\
from orm.base import Base, engine ShoutRatingStorage, ShoutViewStorage
from orm.base import Base, engine, local_session
from orm.comment import Comment from orm.comment import Comment
__all__ = ["User", "Role", "Operation", "Permission", "Message", "Shout", "Topic", "Notification"] __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) Base.metadata.create_all(engine)
Operation.init_table() Operation.init_table()
Resource.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.comment import Comment
from orm.base import Base from orm.base import Base
from functools import reduce
class ShoutAuthor(Base): class ShoutAuthor(Base):
__tablename__ = "shout_author" __tablename__ = "shout_author"
@ -36,6 +38,25 @@ class ShoutRating(Base):
ts: str = Column(DateTime, nullable=False, default = datetime.now, comment="Timestamp") ts: str = Column(DateTime, nullable=False, default = datetime.now, comment="Timestamp")
value = Column(Integer) 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): class ShoutViewByDay(Base):
__tablename__ = "shout_view_by_day" __tablename__ = "shout_view_by_day"
@ -44,6 +65,18 @@ class ShoutViewByDay(Base):
day: str = Column(DateTime, primary_key = True, default = datetime.now) day: str = Column(DateTime, primary_key = True, default = datetime.now)
value = Column(Integer) 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): class Shout(Base):
__tablename__ = 'shout' __tablename__ = 'shout'
@ -66,7 +99,5 @@ class Shout(Base):
layout: str = Column(String, nullable = True) layout: str = Column(String, nullable = True)
authors = relationship(lambda: User, secondary=ShoutAuthor.__tablename__) # NOTE: multiple authors authors = relationship(lambda: User, secondary=ShoutAuthor.__tablename__) # NOTE: multiple authors
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__) 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__) visibleFor = relationship(lambda: User, secondary=ShoutViewer.__tablename__)
old_id: str = Column(String, nullable = True) 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 orm.base import local_session
from resolvers.base import mutation, query from resolvers.base import mutation, query
@ -12,6 +13,7 @@ from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from sqlalchemy import select, func, desc from sqlalchemy import select, func, desc
from sqlalchemy.orm import selectinload
class GitTask: class GitTask:
@ -258,17 +260,14 @@ async def update_shout(_, info, id, input):
"shout" : shout "shout" : shout
} }
@query.field("getShoutBySlug") #FIXME: add shout joined with comments @query.field("getShoutBySlug")
async def get_shout_by_slug(_, info, slug): async def get_shout_by_slug(_, info, slug):
with local_session() as session: with local_session() as session:
stmt = select(Shout, func.sum(ShoutRating.value).label("rating")).\ shout = session.query(Shout).\
join(ShoutRating).\ options(selectinload(Shout.authors)).\
where(Shout.slug == slug).\ options(selectinload(Shout.comments)).\
limit(limit) options(selectinload(Shout.topics)).\
shouts = [] filter(Shout.slug == slug).first()
for row in session.execute(stmt): shout.rating = rating_storage.get_rating(shout.id)
shout = row.Shout shout.views = view_storage.get_view(shout.id)
shout.rating = row.rating
# TODO: shout.comments =
shouts.append(shout)
return shout return shout