From eba8e6d6af09218bb5a8b9d8d1a4039ff5ab0c9f Mon Sep 17 00:00:00 2001 From: knst-kotov Date: Tue, 31 Aug 2021 18:15:27 +0300 Subject: [PATCH] shout rating and view with timestamp --- orm/__init__.py | 2 +- orm/shout.py | 14 +++++++++++--- resolvers/zine.py | 29 +++++++++++++++++++++++------ schema.graphql | 2 +- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/orm/__init__.py b/orm/__init__.py index 6d2bda93..bec01443 100644 --- a/orm/__init__.py +++ b/orm/__init__.py @@ -4,7 +4,7 @@ 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 +from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay from orm.base import Base, engine __all__ = ["User", "Role", "Operation", "Permission", "Message", "Shout", "Topic", "Notification"] diff --git a/orm/shout.py b/orm/shout.py index 6a3a4428..bc0b4a1f 100644 --- a/orm/shout.py +++ b/orm/shout.py @@ -20,11 +20,20 @@ class ShoutTopic(Base): topic = Column(ForeignKey('topic.id'), primary_key = True) class ShoutRating(Base): - __tablename__ = "shout_ratings" + __tablename__ = "shout_rating" id = None rater_id = Column(ForeignKey('user.id'), primary_key = True) shout_id = Column(ForeignKey('shout.id'), primary_key = True) + ts: str = Column(DateTime, nullable=False, default = datetime.now, comment="Timestamp") + value = Column(Integer) + +class ShoutViewByDay(Base): + __tablename__ = "shout_view_by_day" + + id = None + shout_id = Column(ForeignKey('shout.id'), primary_key = True) + day: str = Column(DateTime, primary_key = True, default = datetime.now) value = Column(Integer) class Shout(Base): @@ -40,7 +49,6 @@ class Shout(Base): replyTo: int = Column(ForeignKey("shout.id"), nullable=True) versionOf: int = Column(ForeignKey("shout.id"), nullable=True) tags: str = Column(String, nullable=True) - views: int = Column(Integer, default=0) published: bool = Column(Boolean, default=False) publishedAt: str = Column(DateTime, nullable=True) cover: str = Column(String, nullable = True) @@ -49,6 +57,6 @@ 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__) - rating: int = Column(Integer, nullable=True, comment="Rating") ratings = relationship(ShoutRating, foreign_keys=ShoutRating.shout_id) + views = relationship(ShoutViewByDay) old_id: str = Column(String, nullable = True) diff --git a/resolvers/zine.py b/resolvers/zine.py index 4d845e80..e8bd40a4 100644 --- a/resolvers/zine.py +++ b/resolvers/zine.py @@ -1,4 +1,4 @@ -from orm import Shout, ShoutAuthor, ShoutTopic, ShoutRating, User, Community, Resource +from orm import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay, User, Community, Resource from orm.base import local_session from resolvers.base import mutation, query @@ -8,7 +8,7 @@ from settings import SHOUTS_REPO import subprocess import asyncio -from datetime import datetime +from datetime import datetime, timedelta from pathlib import Path from sqlalchemy import select, func, desc @@ -69,20 +69,37 @@ class GitTask: @query.field("topShoutsByView") async def top_shouts_by_view(_, info, limit): + month_ago = datetime.now() - timedelta(days = 30) with local_session() as session: - shouts = session.query(Shout).order_by(Shout.views.desc()).limit(limit).all() + stmt = select(Shout, func.sum(ShoutViewByDay.value).label("view")).\ + join(ShoutViewByDay).\ + where(ShoutViewByDay.day > month_ago).\ + group_by(Shout.id).\ + order_by(desc("view")).\ + limit(limit) + shouts = [] + for row in session.execute(stmt): + shout = row.Shout + shout.view = row.view + shouts.append(shout) return shouts @query.field("topShoutsByRating") async def top_shouts(_, info, limit): + month_ago = datetime.now() - timedelta(days = 30) with local_session() as session: - stmt = select(Shout, func.sum(ShoutRating.value).label("shout_rating")).\ + stmt = select(Shout, func.sum(ShoutRating.value).label("rating")).\ join(ShoutRating).\ + where(ShoutRating.ts > month_ago).\ group_by(Shout.id).\ - order_by(desc("shout_rating")).\ + order_by(desc("rating")).\ limit(limit) - shouts = [row.Shout for row in session.execute(stmt)] + shouts = [] + for row in session.execute(stmt): + shout = row.Shout + shout.rating = row.rating + shouts.append(shout) return shouts diff --git a/schema.graphql b/schema.graphql index 7bd8c1a2..93723561 100644 --- a/schema.graphql +++ b/schema.graphql @@ -203,7 +203,7 @@ type Shout { versionOf: String visibleForRoles: [String] # role ids are strings visibleForUsers: [Int] - views: Int + view: Int old_id: String }