add shout stat

This commit is contained in:
knst-kotov 2021-12-17 11:22:31 +01:00
parent 944af4e96c
commit 26e903d4f2
4 changed files with 54 additions and 8 deletions

View File

@ -15,7 +15,7 @@ from redis import redis
from resolvers.base import resolvers
from resolvers.zine import GitTask, ShoutsCache
from orm.shout import ShoutViewStorage, TopicStat, ShoutAuthorStorage
from orm.shout import ShoutViewStorage, TopicStat, ShoutAuthorStorage, CommentStat
import asyncio
@ -34,6 +34,7 @@ async def start_up():
view_storage_task = asyncio.create_task(ShoutViewStorage.worker())
shout_author_task = asyncio.create_task(ShoutAuthorStorage.worker())
topic_stat_task = asyncio.create_task(TopicStat.worker())
comment_stat_task = asyncio.create_task(CommentStat.worker())
async def shutdown():
await redis.disconnect()

View File

@ -1,6 +1,6 @@
from typing import List
from datetime import datetime, timedelta
from sqlalchemy import Table, Column, Integer, String, ForeignKey, DateTime, Boolean
from sqlalchemy import Table, Column, Integer, String, ForeignKey, DateTime, Boolean, func
from sqlalchemy.orm import relationship
from sqlalchemy.orm.attributes import flag_modified
from orm import Permission, User, Topic, TopicSubscription
@ -204,6 +204,7 @@ class TopicStat:
else:
self.subs_by_topic[topic] = [user]
@staticmethod
async def get_shouts(topic):
self = TopicStat
async with self.lock:
@ -277,6 +278,40 @@ class ShoutAuthorStorage:
print("ShoutAuthorStorage worker: error = %s" % (err))
await asyncio.sleep(self.period)
class CommentStat:
stat_by_topic = {}
lock = asyncio.Lock()
period = 30*60 #sec
@staticmethod
async def load(session):
self = CommentStat
stats = session.query(Comment.shout, func.count(Comment.id).label("count")).\
group_by(Comment.shout)
self.stat_by_topic = dict([(stat.shout, stat.count) for stat in stats])
@staticmethod
async def get_stat(shout):
self = CommentStat
async with self.lock:
return self.stat_by_topic.get(shout, 0)
@staticmethod
async def worker():
self = CommentStat
print("CommentStat worker start")
while True:
try:
print("CommentStat worker: load stat")
with local_session() as session:
async with self.lock:
await self.load(session)
except Exception as err:
print("CommentStat worker: error = %s" % (err))
await asyncio.sleep(self.period)
class Shout(Base):
__tablename__ = 'shout'
@ -301,3 +336,11 @@ class Shout(Base):
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__)
mainTopic = Column(ForeignKey("topic.slug"), nullable=True)
visibleFor = relationship(lambda: User, secondary=ShoutViewer.__tablename__)
@property
async def stat(self):
return {
"views": await ShoutViewStorage.get_view(self.slug),
"comments": await CommentStat.get_stat(self.slug),
"ratings": await ShoutRatingStorage.get_total_rating(self.slug)
}

View File

@ -88,7 +88,6 @@ class ShoutsCache:
for row in session.execute(stmt):
shout = row.Shout
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
shout.views = await ShoutViewStorage.get_view(shout.slug)
shouts.append(shout)
async with ShoutsCache.lock:
ShoutsCache.recent_shouts = shouts
@ -108,7 +107,6 @@ class ShoutsCache:
for row in session.execute(stmt):
shout = row.Shout
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
shout.views = await ShoutViewStorage.get_view(shout.slug)
shouts.append(shout)
async with ShoutsCache.lock:
ShoutsCache.top_overall = shouts
@ -128,7 +126,6 @@ class ShoutsCache:
for row in session.execute(stmt):
shout = row.Shout
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
shout.views = await ShoutViewStorage.get_view(shout.slug)
shouts.append(shout)
async with ShoutsCache.lock:
ShoutsCache.top_month = shouts
@ -336,7 +333,6 @@ async def get_shout_by_slug(_, info, slug):
return {} #TODO return error field
shout.ratings = await ShoutRatingStorage.get_ratings(slug)
shout.views = await ShoutViewStorage.get_view(slug)
return shout
@query.field("getShoutComments")

View File

@ -307,8 +307,6 @@ type Shout {
community: Int
cover: String
layout: String
rating: Int
views: Int
# replyTo: Shout
versionOf: Shout
tags: [String] # actual values
@ -322,6 +320,14 @@ type Shout {
deletedBy: Int
publishedBy: Int # if there is no published field - it is not published
publishedAt: DateTime
stat: ShoutStat
}
type ShoutStat {
views: Int!
comments: Int!
ratings: Int!
}
type Community {