shoutscache, format
This commit is contained in:
parent
742042398c
commit
365c2f25e7
|
@ -74,11 +74,8 @@ async def migrate(entry, storage):
|
||||||
reaction_dict["kind"] = ReactionKind.COMMENT
|
reaction_dict["kind"] = ReactionKind.COMMENT
|
||||||
|
|
||||||
# creating reaction from old comment
|
# creating reaction from old comment
|
||||||
day = (reaction_dict.get("createdAt") or ts).replace(
|
|
||||||
hour=0, minute=0, second=0, microsecond=0
|
|
||||||
)
|
|
||||||
reaction = Reaction.create(**reaction_dict)
|
reaction = Reaction.create(**reaction_dict)
|
||||||
await ReactedStorage.increment(reaction)
|
await ReactedStorage.react(reaction)
|
||||||
|
|
||||||
reaction_dict["id"] = reaction.id
|
reaction_dict["id"] = reaction.id
|
||||||
for comment_rating_old in entry.get("ratings", []):
|
for comment_rating_old in entry.get("ratings", []):
|
||||||
|
@ -106,7 +103,7 @@ async def migrate(entry, storage):
|
||||||
try:
|
try:
|
||||||
# creating reaction from old rating
|
# creating reaction from old rating
|
||||||
rr = Reaction.create(**re_reaction_dict)
|
rr = Reaction.create(**re_reaction_dict)
|
||||||
await ReactedStorage.increment(rr)
|
await ReactedStorage.react(rr)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("[migration] comment rating error: %r" % re_reaction_dict)
|
print("[migration] comment rating error: %r" % re_reaction_dict)
|
||||||
|
|
|
@ -269,11 +269,11 @@ async def migrate(entry, storage):
|
||||||
)
|
)
|
||||||
reaction.update(reaction_dict)
|
reaction.update(reaction_dict)
|
||||||
else:
|
else:
|
||||||
reaction_dict['day'] = (reaction_dict.get("createdAt") or ts).replace(
|
reaction_dict["day"] = (
|
||||||
hour=0, minute=0, second=0, microsecond=0
|
reaction_dict.get("createdAt") or ts
|
||||||
)
|
).replace(hour=0, minute=0, second=0, microsecond=0)
|
||||||
rea = Reaction.create(**reaction_dict)
|
rea = Reaction.create(**reaction_dict)
|
||||||
await ReactedStorage.increment(rea)
|
await ReactedStorage.react(rea)
|
||||||
# shout_dict['ratings'].append(reaction_dict)
|
# shout_dict['ratings'].append(reaction_dict)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise Exception("[migration] content_item.ratings error: \n%r" % content_rating)
|
raise Exception("[migration] content_item.ratings error: \n%r" % content_rating)
|
||||||
|
|
|
@ -21,3 +21,4 @@ class Collection(Base):
|
||||||
pic = Column(String, nullable=True, comment="Picture")
|
pic = Column(String, nullable=True, comment="Picture")
|
||||||
createdAt = Column(DateTime, default=datetime.now, comment="Created At")
|
createdAt = Column(DateTime, default=datetime.now, comment="Created At")
|
||||||
createdBy = Column(ForeignKey("user.id"), comment="Created By")
|
createdBy = Column(ForeignKey("user.id"), comment="Created By")
|
||||||
|
publishedAt = Column(DateTime, default=datetime.now, comment="Published At")
|
||||||
|
|
|
@ -30,7 +30,6 @@ class Reaction(Base):
|
||||||
return {
|
return {
|
||||||
"viewed": await ViewedStorage.get_reaction(self.id),
|
"viewed": await ViewedStorage.get_reaction(self.id),
|
||||||
"reacted": len(await ReactedStorage.get_reaction(self.id)),
|
"reacted": len(await ReactedStorage.get_reaction(self.id)),
|
||||||
# TODO: "replied"
|
|
||||||
"rating": await ReactedStorage.get_reaction_rating(self.id),
|
"rating": await ReactedStorage.get_reaction_rating(self.id),
|
||||||
"commented": len(await ReactedStorage.get_reaction_comments(self.id)),
|
"commented": len(await ReactedStorage.get_reaction_comments(self.id)),
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,14 +9,14 @@ from sqlalchemy import and_
|
||||||
|
|
||||||
@mutation.field("createCollection")
|
@mutation.field("createCollection")
|
||||||
@login_required
|
@login_required
|
||||||
async def create_collection(_, info, input):
|
async def create_collection(_, _info, inp):
|
||||||
# auth = info.context["request"].auth
|
# auth = info.context["request"].auth
|
||||||
# user_id = auth.user_id
|
# user_id = auth.user_id
|
||||||
collection = Collection.create(
|
collection = Collection.create(
|
||||||
slug=input.get("slug", ""),
|
slug=inp.get("slug", ""),
|
||||||
title=input.get("title", ""),
|
title=inp.get("title", ""),
|
||||||
desc=input.get("desc", ""),
|
desc=inp.get("desc", ""),
|
||||||
pic=input.get("pic", ""),
|
pic=inp.get("pic", ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
return {"collection": collection}
|
return {"collection": collection}
|
||||||
|
@ -24,7 +24,7 @@ async def create_collection(_, info, input):
|
||||||
|
|
||||||
@mutation.field("updateCollection")
|
@mutation.field("updateCollection")
|
||||||
@login_required
|
@login_required
|
||||||
async def update_collection(_, info, input):
|
async def update_collection(_, info, inp):
|
||||||
auth = info.context["request"].auth
|
auth = info.context["request"].auth
|
||||||
user_id = auth.user_id
|
user_id = auth.user_id
|
||||||
collection_slug = input.get("slug", "")
|
collection_slug = input.get("slug", "")
|
||||||
|
@ -38,9 +38,9 @@ async def update_collection(_, info, input):
|
||||||
return {"error": "invalid collection id"}
|
return {"error": "invalid collection id"}
|
||||||
if collection.createdBy not in (owner + editors):
|
if collection.createdBy not in (owner + editors):
|
||||||
return {"error": "access denied"}
|
return {"error": "access denied"}
|
||||||
collection.title = input.get("title", "")
|
collection.title = inp.get("title", "")
|
||||||
collection.desc = input.get("desc", "")
|
collection.desc = inp.get("desc", "")
|
||||||
collection.pic = input.get("pic", "")
|
collection.pic = inp.get("pic", "")
|
||||||
collection.updatedAt = datetime.now()
|
collection.updatedAt = datetime.now()
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ async def delete_collection(_, info, slug):
|
||||||
|
|
||||||
|
|
||||||
@query.field("getUserCollections")
|
@query.field("getUserCollections")
|
||||||
async def get_user_collections(_, info, userslug):
|
async def get_user_collections(_, _info, userslug):
|
||||||
collections = []
|
collections = []
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
user = session.query(User).filter(User.slug == userslug).first()
|
user = session.query(User).filter(User.slug == userslug).first()
|
||||||
|
|
|
@ -58,10 +58,10 @@ def reactions_unfollow(user, slug):
|
||||||
async def create_reaction(_, info, inp):
|
async def create_reaction(_, info, inp):
|
||||||
user = info.context["request"].user
|
user = info.context["request"].user
|
||||||
|
|
||||||
# TODO: filter allowed reaction kinds
|
# TODO: filter allowed for post reaction kinds
|
||||||
|
|
||||||
reaction = Reaction.create(**inp)
|
reaction = Reaction.create(**inp)
|
||||||
ReactedStorage.increment(reaction.shout, reaction.replyTo)
|
ReactedStorage.react(reaction)
|
||||||
try:
|
try:
|
||||||
reactions_follow(user, inp["shout"], True)
|
reactions_follow(user, inp["shout"], True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -18,42 +18,42 @@ from sqlalchemy.orm import selectinload
|
||||||
@query.field("topViewed")
|
@query.field("topViewed")
|
||||||
async def top_viewed(_, info, page, size):
|
async def top_viewed(_, info, page, size):
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
return ShoutsCache.top_viewed[((page - 1) * size) : (page * size)]
|
return ShoutsCache.get_top_viewed[((page - 1) * size) : (page * size)]
|
||||||
|
|
||||||
|
|
||||||
@query.field("topMonth")
|
@query.field("topMonth")
|
||||||
async def top_month(_, info, page, size):
|
async def top_month(_, info, page, size):
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
return ShoutsCache.top_month[((page - 1) * size) : (page * size)]
|
return ShoutsCache.get_top_month[((page - 1) * size) : (page * size)]
|
||||||
|
|
||||||
|
|
||||||
@query.field("topOverall")
|
@query.field("topOverall")
|
||||||
async def top_overall(_, info, page, size):
|
async def top_overall(_, info, page, size):
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
return ShoutsCache.top_overall[((page - 1) * size) : (page * size)]
|
return ShoutsCache.get_top_overall[((page - 1) * size) : (page * size)]
|
||||||
|
|
||||||
|
|
||||||
@query.field("recentPublished")
|
@query.field("recentPublished")
|
||||||
async def recent_published(_, info, page, size):
|
async def recent_published(_, info, page, size):
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
return ShoutsCache.recent_published[((page - 1) * size) : (page * size)]
|
return ShoutsCache.get_recent_published[((page - 1) * size) : (page * size)]
|
||||||
|
|
||||||
|
|
||||||
@query.field("recentAll")
|
@query.field("recentAll")
|
||||||
async def recent_all(_, info, page, size):
|
async def recent_all(_, info, page, size):
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
return ShoutsCache.recent_all[((page - 1) * size) : (page * size)]
|
return ShoutsCache.get_recent_all[((page - 1) * size) : (page * size)]
|
||||||
|
|
||||||
|
|
||||||
@query.field("recentReacted")
|
@query.field("recentReacted")
|
||||||
async def recent_reacted(_, info, page, size):
|
async def recent_reacted(_, info, page, size):
|
||||||
async with ShoutsCache.lock:
|
async with ShoutsCache.lock:
|
||||||
return ShoutsCache.recent_reacted[((page - 1) * size) : (page * size)]
|
return ShoutsCache.get_recent_reacted[((page - 1) * size) : (page * size)]
|
||||||
|
|
||||||
|
|
||||||
@mutation.field("viewShout")
|
@mutation.field("viewShout")
|
||||||
async def view_shout(_, info, slug):
|
async def view_shout(_, info, slug):
|
||||||
await ViewedStorage.inc_shout(slug)
|
await ViewedStorage.increment(slug)
|
||||||
return {"error": ""}
|
return {"error": ""}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from sqlalchemy import and_, desc, func, select
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
from base.orm import local_session
|
from base.orm import local_session
|
||||||
from orm.reaction import Reaction
|
from orm.reaction import Reaction
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
||||||
from services.stat.reacted import ReactedStorage
|
from services.stat.reacted import ReactedStorage
|
||||||
from services.stat.viewed import ViewedByDay
|
from services.stat.viewed import ViewedByDay
|
||||||
|
|
||||||
|
@ -14,6 +14,16 @@ class ShoutsCache:
|
||||||
period = 60 * 60 # 1 hour
|
period = 60 * 60 # 1 hour
|
||||||
lock = asyncio.Lock()
|
lock = asyncio.Lock()
|
||||||
|
|
||||||
|
recent_published = []
|
||||||
|
recent_all = []
|
||||||
|
recent_reacted = []
|
||||||
|
top_month = []
|
||||||
|
top_overall = []
|
||||||
|
top_viewed = []
|
||||||
|
|
||||||
|
by_author = {}
|
||||||
|
by_topic = {}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def prepare_recent_published():
|
async def prepare_recent_published():
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
|
@ -151,6 +161,82 @@ class ShoutsCache:
|
||||||
print("[zine.cache] %d top viewed shouts " % len(shouts))
|
print("[zine.cache] %d top viewed shouts " % len(shouts))
|
||||||
ShoutsCache.top_viewed = shouts
|
ShoutsCache.top_viewed = shouts
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def prepare_by_author():
|
||||||
|
shouts_by_author = {}
|
||||||
|
with local_session() as session:
|
||||||
|
|
||||||
|
for a in session.query(ShoutAuthor).all():
|
||||||
|
|
||||||
|
shout = session.query(Shout).filter(Shout.slug == a.shout).first()
|
||||||
|
|
||||||
|
if not shouts_by_author[a.author]:
|
||||||
|
shouts_by_author[a.author] = []
|
||||||
|
|
||||||
|
if shout not in shouts_by_author[a.author]:
|
||||||
|
shouts_by_author[a.author].push(shout)
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
print("[zine.cache indexed by %d authors " % len(shouts_by_author.keys()))
|
||||||
|
ShoutsCache.by_author = shouts_by_author
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def prepare_by_topic():
|
||||||
|
shouts_by_topic = {}
|
||||||
|
with local_session() as session:
|
||||||
|
|
||||||
|
for t in session.query(ShoutTopic).all():
|
||||||
|
|
||||||
|
shout = session.query(Shout).filter(Shout.slug == t.shout).first()
|
||||||
|
|
||||||
|
if not shouts_by_topic[t.topic]:
|
||||||
|
shouts_by_topic[t.topic] = []
|
||||||
|
|
||||||
|
if shout not in shouts_by_topic[t.topic]:
|
||||||
|
shouts_by_topic[t.topic].push(shout)
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
print("[zine.cache] indexed by %d topics " % len(shouts_by_topic.keys()))
|
||||||
|
ShoutsCache.by_topic = shouts_by_topic
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_shouts_by_author():
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
return ShoutsCache.by_author
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_shouts_by_topic():
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
return ShoutsCache.by_topic
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_top_overall():
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
return ShoutsCache.by_topic
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_top_month():
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
return ShoutsCache.by_topic
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_top_viewed():
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
return ShoutsCache.by_topic
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_recent_published():
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
return ShoutsCache.recent_published
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_recent_all():
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
return ShoutsCache.recent_all
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def get_recent_reacted():
|
||||||
|
async with ShoutsCache.lock:
|
||||||
|
return ShoutsCache.recent_reacted
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def worker():
|
async def worker():
|
||||||
while True:
|
while True:
|
||||||
|
@ -158,9 +244,13 @@ class ShoutsCache:
|
||||||
await ShoutsCache.prepare_top_month()
|
await ShoutsCache.prepare_top_month()
|
||||||
await ShoutsCache.prepare_top_overall()
|
await ShoutsCache.prepare_top_overall()
|
||||||
await ShoutsCache.prepare_top_viewed()
|
await ShoutsCache.prepare_top_viewed()
|
||||||
|
|
||||||
await ShoutsCache.prepare_recent_published()
|
await ShoutsCache.prepare_recent_published()
|
||||||
await ShoutsCache.prepare_recent_all()
|
await ShoutsCache.prepare_recent_all()
|
||||||
await ShoutsCache.prepare_recent_reacted()
|
await ShoutsCache.prepare_recent_reacted()
|
||||||
|
|
||||||
|
await ShoutsCache.prepare_by_author()
|
||||||
|
await ShoutsCache.prepare_by_topic()
|
||||||
print("[zine.cache] periodical update")
|
print("[zine.cache] periodical update")
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print("[zine.cache] error: %s" % (err))
|
print("[zine.cache] error: %s" % (err))
|
||||||
|
|
|
@ -11,8 +11,8 @@ class TopicStorage:
|
||||||
self = TopicStorage
|
self = TopicStorage
|
||||||
topics = session.query(Topic)
|
topics = session.query(Topic)
|
||||||
self.topics = dict([(topic.slug, topic) for topic in topics])
|
self.topics = dict([(topic.slug, topic) for topic in topics])
|
||||||
for topic in self.topics.values():
|
for tpc in self.topics.values():
|
||||||
self.load_parents(topic)
|
self.load_parents(tpc)
|
||||||
|
|
||||||
print("[zine.topics] %d precached" % len(self.topics.keys()))
|
print("[zine.topics] %d precached" % len(self.topics.keys()))
|
||||||
|
|
||||||
|
@ -51,7 +51,16 @@ class TopicStorage:
|
||||||
return list(topics)
|
return list(topics)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def add_topic(topic):
|
async def get_topics_by_author(author):
|
||||||
|
self = TopicStorage
|
||||||
|
async with self.lock:
|
||||||
|
topics = filter(
|
||||||
|
lambda topic: topic.community == author, self.topics.values()
|
||||||
|
)
|
||||||
|
return list(topics)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def update_topic(topic):
|
||||||
self = TopicStorage
|
self = TopicStorage
|
||||||
async with self.lock:
|
async with self.lock:
|
||||||
self.topics[topic.slug] = topic
|
self.topics[topic.slug] = topic
|
||||||
|
|
Loading…
Reference in New Issue
Block a user