add shout stat
This commit is contained in:
parent
944af4e96c
commit
26e903d4f2
3
main.py
3
main.py
|
@ -15,7 +15,7 @@ from redis import redis
|
||||||
from resolvers.base import resolvers
|
from resolvers.base import resolvers
|
||||||
from resolvers.zine import GitTask, ShoutsCache
|
from resolvers.zine import GitTask, ShoutsCache
|
||||||
|
|
||||||
from orm.shout import ShoutViewStorage, TopicStat, ShoutAuthorStorage
|
from orm.shout import ShoutViewStorage, TopicStat, ShoutAuthorStorage, CommentStat
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ async def start_up():
|
||||||
view_storage_task = asyncio.create_task(ShoutViewStorage.worker())
|
view_storage_task = asyncio.create_task(ShoutViewStorage.worker())
|
||||||
shout_author_task = asyncio.create_task(ShoutAuthorStorage.worker())
|
shout_author_task = asyncio.create_task(ShoutAuthorStorage.worker())
|
||||||
topic_stat_task = asyncio.create_task(TopicStat.worker())
|
topic_stat_task = asyncio.create_task(TopicStat.worker())
|
||||||
|
comment_stat_task = asyncio.create_task(CommentStat.worker())
|
||||||
|
|
||||||
async def shutdown():
|
async def shutdown():
|
||||||
await redis.disconnect()
|
await redis.disconnect()
|
||||||
|
|
45
orm/shout.py
45
orm/shout.py
|
@ -1,6 +1,6 @@
|
||||||
from typing import List
|
from typing import List
|
||||||
from datetime import datetime, timedelta
|
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 import relationship
|
||||||
from sqlalchemy.orm.attributes import flag_modified
|
from sqlalchemy.orm.attributes import flag_modified
|
||||||
from orm import Permission, User, Topic, TopicSubscription
|
from orm import Permission, User, Topic, TopicSubscription
|
||||||
|
@ -204,6 +204,7 @@ class TopicStat:
|
||||||
else:
|
else:
|
||||||
self.subs_by_topic[topic] = [user]
|
self.subs_by_topic[topic] = [user]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
async def get_shouts(topic):
|
async def get_shouts(topic):
|
||||||
self = TopicStat
|
self = TopicStat
|
||||||
async with self.lock:
|
async with self.lock:
|
||||||
|
@ -277,6 +278,40 @@ class ShoutAuthorStorage:
|
||||||
print("ShoutAuthorStorage worker: error = %s" % (err))
|
print("ShoutAuthorStorage worker: error = %s" % (err))
|
||||||
await asyncio.sleep(self.period)
|
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):
|
class Shout(Base):
|
||||||
__tablename__ = 'shout'
|
__tablename__ = 'shout'
|
||||||
|
|
||||||
|
@ -301,3 +336,11 @@ class Shout(Base):
|
||||||
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__)
|
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__)
|
||||||
mainTopic = Column(ForeignKey("topic.slug"), nullable=True)
|
mainTopic = Column(ForeignKey("topic.slug"), nullable=True)
|
||||||
visibleFor = relationship(lambda: User, secondary=ShoutViewer.__tablename__)
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -88,7 +88,6 @@ class ShoutsCache:
|
||||||
for row in session.execute(stmt):
|
for row in session.execute(stmt):
|
||||||
shout = row.Shout
|
shout = row.Shout
|
||||||
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
||||||
shout.views = await ShoutViewStorage.get_view(shout.slug)
|
|
||||||
shouts.append(shout)
|
shouts.append(shout)
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
ShoutsCache.recent_shouts = shouts
|
ShoutsCache.recent_shouts = shouts
|
||||||
|
@ -108,7 +107,6 @@ class ShoutsCache:
|
||||||
for row in session.execute(stmt):
|
for row in session.execute(stmt):
|
||||||
shout = row.Shout
|
shout = row.Shout
|
||||||
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
||||||
shout.views = await ShoutViewStorage.get_view(shout.slug)
|
|
||||||
shouts.append(shout)
|
shouts.append(shout)
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
ShoutsCache.top_overall = shouts
|
ShoutsCache.top_overall = shouts
|
||||||
|
@ -128,7 +126,6 @@ class ShoutsCache:
|
||||||
for row in session.execute(stmt):
|
for row in session.execute(stmt):
|
||||||
shout = row.Shout
|
shout = row.Shout
|
||||||
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
shout.ratings = await ShoutRatingStorage.get_ratings(shout.slug)
|
||||||
shout.views = await ShoutViewStorage.get_view(shout.slug)
|
|
||||||
shouts.append(shout)
|
shouts.append(shout)
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
ShoutsCache.top_month = shouts
|
ShoutsCache.top_month = shouts
|
||||||
|
@ -336,7 +333,6 @@ async def get_shout_by_slug(_, info, slug):
|
||||||
return {} #TODO return error field
|
return {} #TODO return error field
|
||||||
|
|
||||||
shout.ratings = await ShoutRatingStorage.get_ratings(slug)
|
shout.ratings = await ShoutRatingStorage.get_ratings(slug)
|
||||||
shout.views = await ShoutViewStorage.get_view(slug)
|
|
||||||
return shout
|
return shout
|
||||||
|
|
||||||
@query.field("getShoutComments")
|
@query.field("getShoutComments")
|
||||||
|
|
|
@ -307,8 +307,6 @@ type Shout {
|
||||||
community: Int
|
community: Int
|
||||||
cover: String
|
cover: String
|
||||||
layout: String
|
layout: String
|
||||||
rating: Int
|
|
||||||
views: Int
|
|
||||||
# replyTo: Shout
|
# replyTo: Shout
|
||||||
versionOf: Shout
|
versionOf: Shout
|
||||||
tags: [String] # actual values
|
tags: [String] # actual values
|
||||||
|
@ -322,6 +320,14 @@ type Shout {
|
||||||
deletedBy: Int
|
deletedBy: Int
|
||||||
publishedBy: Int # if there is no published field - it is not published
|
publishedBy: Int # if there is no published field - it is not published
|
||||||
publishedAt: DateTime
|
publishedAt: DateTime
|
||||||
|
|
||||||
|
stat: ShoutStat
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShoutStat {
|
||||||
|
views: Int!
|
||||||
|
comments: Int!
|
||||||
|
ratings: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Community {
|
type Community {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user