diff --git a/resolvers/editor.py b/resolvers/editor.py index 04f0c23f..e8d0b0c4 100644 --- a/resolvers/editor.py +++ b/resolvers/editor.py @@ -8,8 +8,11 @@ from orm.rating import is_negative, is_positive from orm.reaction import Reaction, ReactionKind from orm.shout import Shout, ShoutAuthor, ShoutTopic from orm.topic import Topic +from orm.author import Author from resolvers.follower import reactions_follow, reactions_unfollow +from resolvers.stat import get_with_stat from services.auth import login_required +from services.cache import cache_topic, cache_author from services.db import local_session from services.diff import apply_diff, get_diff from services.logger import root_logger as logger @@ -18,6 +21,22 @@ from services.schema import mutation, query from services.search import search_service +async def cache_by_id(what: str, entity_id: int): + is_author = what == "AUTHOR" + alias = Author if is_author else Topic + q = select(alias).filter(alias.id == entity_id) + [x] = get_with_stat(q) + if not x: + return + + d = x.dict() # convert object to dictionary + if is_author: + await cache_author(d) + else: + await cache_topic(d) + return d + + @query.field("get_my_shout") @login_required async def get_my_shout(_, info, shout_id: int): @@ -280,6 +299,8 @@ async def update_shout(_, info, shout_id: int, shout_input=None, publish=False): if topics_input: patch_topics(session, shout_by_id, topics_input) del shout_input["topics"] + for tpc in topics_input: + await cache_by_id("TOPIC", tpc["id"]) # main topic main_topic = shout_input.get("main_topic") @@ -300,6 +321,8 @@ async def update_shout(_, info, shout_id: int, shout_input=None, publish=False): await notify_shout(shout_dict, "published") # search service indexing search_service.index(shout_by_id) + for a in shout_by_id.authors: + await cache_by_id("AUTHOR", a.id) return {"shout": shout_dict, "error": None} else: @@ -331,13 +354,18 @@ async def delete_shout(_, info, shout_id: int): shout_dict = shout.dict() # NOTE: only owner and editor can mark the shout as deleted if shout_dict["created_by"] == author_id or "editor" in roles: - for author_id in shout.authors: - reactions_unfollow(author_id, shout_id) - shout_dict["deleted_at"] = int(time.time()) Shout.update(shout, shout_dict) session.add(shout) session.commit() + + for author_id in shout.authors: + reactions_unfollow(author_id, shout_id) + await cache_by_id("AUTHOR", author_id) + + for topic_id in shout.topics: + await cache_by_id("TOPIC", topic_id) + await notify_shout(shout_dict, "delete") return {"error": None} else: diff --git a/resolvers/follower.py b/resolvers/follower.py index 8eb2a330..8c20621d 100644 --- a/resolvers/follower.py +++ b/resolvers/follower.py @@ -13,7 +13,7 @@ from orm.shout import Shout, ShoutReactionsFollower from orm.topic import Topic, TopicFollower from resolvers.stat import author_follows_authors, author_follows_topics, get_with_stat from services.auth import login_required -from services.cache import DEFAULT_FOLLOWS, cache_follower, cache_topic +from services.cache import DEFAULT_FOLLOWS, cache_author, cache_topic from services.db import local_session from services.logger import root_logger as logger from services.notify import notify_follower @@ -30,8 +30,10 @@ async def cache_by_slug(what: str, slug: str): return d = x.dict() # convert object to dictionary - cache_handler = cache_follower if is_author else cache_topic - await cache_handler(d) + if is_author: + await cache_author(d) + else: + await cache_topic(d) return d @@ -59,12 +61,14 @@ async def follow(_, info, what, slug): error = author_follow(follower_id, slug) if not error: author_dict = await cache_by_slug(what, slug) - author_id = author_dict.get("id") - follows_ids = [a.id for a in follows] - if author_id not in follows_ids: - await cache_follower(follower_dict, author_dict) - await notify_follower(follower_dict, author_id, "follow") - follows.append(author_dict) + if isinstance(author_dict, dict): + author_id = author_dict.get("id") + if author_id: + follows_ids = [a.id for a in follows] + if author_id not in follows_ids: + await cache_author(follower_dict) + await notify_follower(follower_dict, author_id, "follow") + follows.append(author_dict) elif what == "TOPIC": error = topic_follow(follower_id, slug) @@ -109,13 +113,17 @@ async def unfollow(_, info, what, slug): if not error: logger.info(f"@{follower_dict.get('slug')} unfollowed @{slug}") author_dict = await cache_by_slug(what, slug) - author_id = author_dict.get("id") - for idx, item in enumerate(follows): - if item["id"] == author_id: - await cache_follower(follower_dict, author_dict, False) - await notify_follower(follower_dict, author_id, "unfollow") - follows.pop(idx) # Remove the author_dict from the follows list - break + if isinstance(author_dict, dict): + author_id = author_dict.get("id") + if author_id: + for idx, item in enumerate(follows): + if item["id"] == author_id: + await cache_author(follower_dict) + await notify_follower(follower_dict, author_id, "unfollow") + follows.pop( + idx + ) # Remove the author_dict from the follows list + break elif what == "TOPIC": error = topic_unfollow(follower_id, slug) diff --git a/services/cache.py b/services/cache.py index 13b3ccd7..f8ceeb54 100644 --- a/services/cache.py +++ b/services/cache.py @@ -123,7 +123,7 @@ async def cache_follower(follower: dict, author: dict, is_insert=True): return followers -async def cache_topic(topic_dict: str): +async def cache_topic(topic_dict: dict): # update stat all field for followers' caches in list followers = ( local_session()