core/services/stat/views.py

122 lines
3.7 KiB
Python
Raw Normal View History

2022-11-15 09:25:04 +00:00
from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport
import asyncio
2022-11-15 12:04:22 +00:00
import json
from base.redis import redis
2022-11-15 09:25:04 +00:00
from services.zine.topics import TopicStorage
query_ackee_views = gql(
"""
query getDomainsFacts {
domains {
statistics {
views {
id
count
}
pages {
id
count
created
}
}
facts {
activeVisitors
# averageViews
# averageDuration
viewsToday
viewsMonth
viewsYear
}
}
}
"""
)
2022-11-15 12:04:22 +00:00
class ViewStat:
2022-11-15 09:25:04 +00:00
lock = asyncio.Lock()
by_slugs = {}
by_topics = {}
period = 30 * 60 # 30 minutes
transport = AIOHTTPTransport(url="https://ackee.discours.io/")
client = Client(transport=transport, fetch_schema_from_transport=True)
@staticmethod
async def load_views():
# TODO: when the struture of paylod will be transparent
# TODO: perhaps ackee token getting here
2022-11-15 12:04:22 +00:00
self = ViewStat
2022-11-15 09:25:04 +00:00
async with self.lock:
2022-11-15 12:04:22 +00:00
self.by_topics = await redis.execute("GET", "views_by_topics")
if self.by_topics:
2022-11-15 15:20:44 +00:00
self.by_topics = dict(json.loads(self.by_topics))
else:
self.by_topics = {}
2022-11-15 12:04:22 +00:00
self.by_slugs = await redis.execute("GET", "views_by_shouts")
if self.by_slugs:
2022-11-15 15:20:44 +00:00
self.by_slugs = dict(json.loads(self.by_slugs))
else:
self.by_slugs = {}
2022-11-15 12:04:22 +00:00
domains = await self.client.execute_async(query_ackee_views)
2022-11-15 09:25:04 +00:00
print("[stat.ackee] loaded domains")
print(domains)
print('\n\n# TODO: something here...\n\n')
@staticmethod
async def get_shout(shout_slug):
2022-11-15 12:04:22 +00:00
self = ViewStat
2022-11-15 09:25:04 +00:00
async with self.lock:
return self.by_slugs.get(shout_slug) or 0
@staticmethod
async def get_topic(topic_slug):
2022-11-15 12:04:22 +00:00
self = ViewStat
2022-11-15 09:25:04 +00:00
async with self.lock:
2022-11-15 15:25:07 +00:00
shouts = self.by_topics.get(topic_slug) or {}
2022-11-15 09:25:04 +00:00
topic_views = 0
for v in shouts.values():
topic_views += v
return topic_views
@staticmethod
async def increment(shout_slug, amount=1):
2022-11-15 12:04:22 +00:00
self = ViewStat
2022-11-15 09:25:04 +00:00
async with self.lock:
self.by_slugs[shout_slug] = self.by_slugs.get(shout_slug) or 0
self.by_slugs[shout_slug] += amount
2022-11-15 12:04:22 +00:00
await redis.execute(
"SET",
f"views_by_shouts/{shout_slug}",
str(self.by_slugs[shout_slug])
)
2022-11-15 09:25:04 +00:00
shout_topics = await TopicStorage.get_topics_by_slugs([shout_slug, ])
for t in shout_topics:
self.by_topics[t] = self.by_topics.get(t) or {}
self.by_topics[t][shout_slug] = self.by_topics[t].get(shout_slug) or 0
self.by_topics[t][shout_slug] += amount
2022-11-15 12:04:22 +00:00
await redis.execute(
"SET",
f"views_by_topics/{t}/{shout_slug}",
str(self.by_topics[t][shout_slug])
)
2022-11-15 09:25:04 +00:00
@staticmethod
2022-11-15 12:04:22 +00:00
async def reset():
self = ViewStat
self.by_topics = {}
self.by_slugs = {}
2022-11-15 09:25:04 +00:00
@staticmethod
async def worker():
2022-11-15 12:04:22 +00:00
self = ViewStat
2022-11-15 09:25:04 +00:00
while True:
try:
2022-11-15 12:04:22 +00:00
await self.load_views()
2022-11-15 09:25:04 +00:00
except Exception as err:
print("[stat.ackee] : %s" % (err))
2022-11-15 12:04:22 +00:00
print("[stat.ackee] renew period: %d minutes" % (ViewStat.period / 60))
await asyncio.sleep(self.period)