add getTopicAuthors

This commit is contained in:
knst-kotov 2021-12-13 21:05:00 +03:00
parent ab9990a616
commit 64a728de41
4 changed files with 59 additions and 2 deletions

View File

@ -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 from orm.shout import ShoutViewStorage, TopicStat, ShoutAuthorStorage
import asyncio import asyncio
@ -33,6 +33,7 @@ async def start_up():
shouts_cache_task = asyncio.create_task(ShoutsCache.worker()) shouts_cache_task = asyncio.create_task(ShoutsCache.worker())
view_storage_task = asyncio.create_task(ShoutViewStorage.worker()) view_storage_task = asyncio.create_task(ShoutViewStorage.worker())
topic_stat_task = asyncio.create_task(TopicStat.worker()) topic_stat_task = asyncio.create_task(TopicStat.worker())
shout_author_task = asyncio.create_task(ShoutAuthorStorage.worker())
async def shutdown(): async def shutdown():
await redis.disconnect() await redis.disconnect()

View File

@ -158,6 +158,11 @@ class TopicStat:
else: else:
self.shouts_by_topic[topic] = [shout] self.shouts_by_topic[topic] = [shout]
async def get_shouts(topic):
self = TopicStat
async with self.lock:
return self.shouts_by_topic.get(topic, [])
@staticmethod @staticmethod
async def get_stat(topic): async def get_stat(topic):
self = TopicStat self = TopicStat
@ -186,6 +191,44 @@ class TopicStat:
print("TopicStat worker: error = %s" % (err)) print("TopicStat worker: error = %s" % (err))
await asyncio.sleep(self.period) await asyncio.sleep(self.period)
class ShoutAuthorStorage:
authors_by_shout = {}
lock = asyncio.Lock()
period = 30*60 #sec
@staticmethod
async def load(session):
self = ShoutAuthorStorage
authors = session.query(ShoutAuthor)
for author in authors:
user = author.user
shout = author.shout
if shout in self.authors_by_shout:
self.authors_by_shout[shout].append(user)
else:
self.authors_by_shout[shout] = [user]
@staticmethod
async def get_authors(shout):
self = ShoutAuthorStorage
async with self.lock:
return self.authors_by_shout.get(shout, [])
@staticmethod
async def worker():
self = ShoutAuthorStorage
print("ShoutAuthorStorage worker start")
while True:
try:
print("ShoutAuthorStorage worker: load stat")
with local_session() as session:
async with self.lock:
await self.load(session)
except Exception as err:
print("ShoutAuthorStorage worker: error = %s" % (err))
await asyncio.sleep(self.period)
class Shout(Base): class Shout(Base):
__tablename__ = 'shout' __tablename__ = 'shout'

View File

@ -1,5 +1,6 @@
from orm import Topic, TopicSubscription, TopicStorage, Shout, User from orm import Topic, TopicSubscription, TopicStorage, Shout, User
from orm.shout import TopicStat from orm.shout import TopicStat, ShoutAuthorStorage
from orm.user import UserStorage
from orm.base import local_session from orm.base import local_session
from resolvers.base import mutation, query, subscription from resolvers.base import mutation, query, subscription
from resolvers.zine import ShoutSubscriptions from resolvers.zine import ShoutSubscriptions
@ -31,6 +32,17 @@ async def topics_by_author(_, info, author):
slugs.update([topic.slug for topic in shout.topics]) slugs.update([topic.slug for topic in shout.topics])
return await TopicStorage.get_topics(slugs) return await TopicStorage.get_topics(slugs)
@query.field("getTopicAuthors")
async def topics_by_author(_, info, slug, count, page):
shouts = await TopicStat.get_shouts(slug)
authors = set()
for shout in shouts:
authors.update(await ShoutAuthorStorage.get_authors(shout))
authors = list(authors)
authors.sort() #TODO sort by username
authors = authors[count * page : count * (page + 1) ]
return [await UserStorage.get_user(author) for author in authors]
@mutation.field("createTopic") @mutation.field("createTopic")
@login_required @login_required
async def create_topic(_, info, input): async def create_topic(_, info, input):

View File

@ -170,6 +170,7 @@ type Query {
topicsBySlugs(slugs: [String]): [Topic]! topicsBySlugs(slugs: [String]): [Topic]!
topicsByCommunity(community: String!): [Topic]! topicsByCommunity(community: String!): [Topic]!
topicsByAuthor(author: String!): [Topic]! topicsByAuthor(author: String!): [Topic]!
getTopicAuthors(slug: String!, count: Int!, page: Int!): [User]!
# getOnlineUsers: [User!]! # getOnlineUsers: [User!]!