following-fix
This commit is contained in:
parent
47bc3adb69
commit
1a685e458d
|
@ -59,14 +59,17 @@ async def get_author(_, _info, slug="", author_id=0):
|
||||||
author_query = select(Author).filter(
|
author_query = select(Author).filter(
|
||||||
or_(Author.slug == slug, Author.id == author_id)
|
or_(Author.slug == slug, Author.id == author_id)
|
||||||
)
|
)
|
||||||
[found_author] = local_session().execute(author_query).first()
|
lookup_result = local_session().execute(author_query).first()
|
||||||
|
if lookup_result:
|
||||||
|
[found_author] = lookup_result
|
||||||
logger.debug(found_author)
|
logger.debug(found_author)
|
||||||
if found_author:
|
if found_author:
|
||||||
logger.debug(f"found author id: {found_author.id}")
|
logger.debug(f"found author id: {found_author.id}")
|
||||||
author_id = found_author.id if found_author.id else author_id
|
author_id = found_author.id if found_author.id else author_id
|
||||||
if author_id:
|
if author_id:
|
||||||
cached_result = await redis.execute("GET", f"author:{author_id}")
|
cached_result = await redis.execute("GET", f"author:{author_id}")
|
||||||
author_dict = json.loads(cached_result) if cached_result else None
|
if isinstance(cached_result, str):
|
||||||
|
author_dict = json.loads(cached_result)
|
||||||
|
|
||||||
# update stat from db
|
# update stat from db
|
||||||
if not author_dict or not author_dict.get("stat"):
|
if not author_dict or not author_dict.get("stat"):
|
||||||
|
@ -180,7 +183,7 @@ async def get_author_follows(_, _info, slug="", user=None, author_id=0):
|
||||||
# logger.debug(author)
|
# logger.debug(author)
|
||||||
if author and isinstance(author, Author):
|
if author and isinstance(author, Author):
|
||||||
# logger.debug(author.dict())
|
# logger.debug(author.dict())
|
||||||
author_id = author.id
|
author_id = author.id if not author_id else author_id
|
||||||
rkey = f"author:{author_id}:follows-authors"
|
rkey = f"author:{author_id}:follows-authors"
|
||||||
logger.debug(f"getting {author_id} follows authors")
|
logger.debug(f"getting {author_id} follows authors")
|
||||||
cached = await redis.execute("GET", rkey)
|
cached = await redis.execute("GET", rkey)
|
||||||
|
|
|
@ -13,7 +13,7 @@ from orm.shout import Shout, ShoutReactionsFollower
|
||||||
from orm.topic import Topic, TopicFollower
|
from orm.topic import Topic, TopicFollower
|
||||||
from resolvers.stat import author_follows_authors, author_follows_topics, get_with_stat
|
from resolvers.stat import author_follows_authors, author_follows_topics, get_with_stat
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from services.cache import DEFAULT_FOLLOWS
|
from services.cache import DEFAULT_FOLLOWS, cache_follower
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from services.logger import root_logger as logger
|
from services.logger import root_logger as logger
|
||||||
from services.notify import notify_follower
|
from services.notify import notify_follower
|
||||||
|
@ -24,21 +24,35 @@ from services.schema import mutation, query
|
||||||
@mutation.field("follow")
|
@mutation.field("follow")
|
||||||
@login_required
|
@login_required
|
||||||
async def follow(_, info, what, slug):
|
async def follow(_, info, what, slug):
|
||||||
follows = []
|
|
||||||
error = None
|
error = None
|
||||||
user_id = info.context.get("user_id")
|
user_id = info.context.get("user_id")
|
||||||
if not user_id:
|
if not user_id:
|
||||||
return {"error": "unauthorized"}
|
return {"error": "unauthorized"}
|
||||||
|
|
||||||
follower = local_session().query(Author).filter(Author.user == user_id).first()
|
follower = local_session().query(Author).filter(Author.user == user_id).first()
|
||||||
|
if not follower:
|
||||||
|
return {"error": "cant find follower account"}
|
||||||
|
|
||||||
|
entity = what.lower()
|
||||||
|
follows = []
|
||||||
|
follows_str = await redis.execute("GET", f"author:{follower.id}:follows-{entity}s")
|
||||||
|
if isinstance(follows_str, str):
|
||||||
|
follows = json.loads(follows_str)
|
||||||
|
|
||||||
if not follower:
|
if not follower:
|
||||||
return {"error": "cant find follower"}
|
return {"error": "cant find follower"}
|
||||||
|
|
||||||
if what == "AUTHOR":
|
if what == "AUTHOR":
|
||||||
error = author_follow(follower.id, slug)
|
error = author_follow(follower.id, slug)
|
||||||
if not error:
|
if not error:
|
||||||
author = local_session().query(Author).where(Author.slug == slug).first()
|
result = get_with_stat(select(Author).where(Author.slug == slug))
|
||||||
|
if result:
|
||||||
|
[author] = result
|
||||||
if author:
|
if author:
|
||||||
|
await cache_follower(follower, author)
|
||||||
await notify_follower(follower.dict(), author.id, "follow")
|
await notify_follower(follower.dict(), author.id, "follow")
|
||||||
|
if not any(a["id"] == author.id for a in follows):
|
||||||
|
follows.append(author.dict())
|
||||||
|
|
||||||
elif what == "TOPIC":
|
elif what == "TOPIC":
|
||||||
error = topic_follow(follower.id, slug)
|
error = topic_follow(follower.id, slug)
|
||||||
|
@ -53,10 +67,6 @@ async def follow(_, info, what, slug):
|
||||||
if error:
|
if error:
|
||||||
return {"error": error}
|
return {"error": error}
|
||||||
|
|
||||||
entity = what.lower()
|
|
||||||
follows_str = await redis.execute("GET", f"author:{follower.id}:follows-{entity}s")
|
|
||||||
if follows_str:
|
|
||||||
follows = json.loads(follows_str)
|
|
||||||
return {f"{entity}s": follows}
|
return {f"{entity}s": follows}
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,17 +78,24 @@ async def unfollow(_, info, what, slug):
|
||||||
user_id = info.context.get("user_id")
|
user_id = info.context.get("user_id")
|
||||||
if not user_id:
|
if not user_id:
|
||||||
return {"error": "unauthorized"}
|
return {"error": "unauthorized"}
|
||||||
|
|
||||||
follower = local_session().query(Author).filter(Author.user == user_id).first()
|
follower = local_session().query(Author).filter(Author.user == user_id).first()
|
||||||
if not follower:
|
if not follower:
|
||||||
return {"error": "follower profile is not found"}
|
return {"error": "cant find follower account"}
|
||||||
|
|
||||||
if what == "AUTHOR":
|
if what == "AUTHOR":
|
||||||
error = author_unfollow(follower.id, slug)
|
error = author_unfollow(follower.id, slug)
|
||||||
# NOTE: after triggers should update cached stats
|
# NOTE: after triggers should update cached stats
|
||||||
if not error:
|
if not error:
|
||||||
logger.info(f"@{follower.slug} unfollowed @{slug}")
|
logger.info(f"@{follower.slug} unfollowed @{slug}")
|
||||||
author = local_session().query(Author).where(Author.slug == slug).first()
|
author = local_session().query(Author).where(Author.slug == slug).first()
|
||||||
if author:
|
if isinstance(author, Author):
|
||||||
|
await cache_follower(follower, author, False)
|
||||||
await notify_follower(follower.dict(), author.id, "unfollow")
|
await notify_follower(follower.dict(), author.id, "unfollow")
|
||||||
|
for idx, item in enumerate(follows):
|
||||||
|
if item["id"] == author.id:
|
||||||
|
follows.pop(idx) # Remove the author_dict from the follows list
|
||||||
|
break
|
||||||
|
|
||||||
elif what == "TOPIC":
|
elif what == "TOPIC":
|
||||||
error = topic_unfollow(follower.id, slug)
|
error = topic_unfollow(follower.id, slug)
|
||||||
|
@ -91,7 +108,7 @@ async def unfollow(_, info, what, slug):
|
||||||
|
|
||||||
entity = what.lower()
|
entity = what.lower()
|
||||||
follows_str = await redis.execute("GET", f"author:{follower.id}:follows-{entity}s")
|
follows_str = await redis.execute("GET", f"author:{follower.id}:follows-{entity}s")
|
||||||
if follows_str:
|
if isinstance(follows_str, str):
|
||||||
follows = json.loads(follows_str)
|
follows = json.loads(follows_str)
|
||||||
return {"error": error, f"{entity}s": follows}
|
return {"error": error, f"{entity}s": follows}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ async def _create_reaction(session, shout, author, reaction):
|
||||||
rdict = r.dict()
|
rdict = r.dict()
|
||||||
|
|
||||||
# пересчет счетчика комментариев
|
# пересчет счетчика комментариев
|
||||||
if r.kind == ReactionKind.COMMENT.value:
|
if str(r.kind) == ReactionKind.COMMENT.value:
|
||||||
await update_author_stat(author)
|
await update_author_stat(author)
|
||||||
|
|
||||||
# collaborative editing
|
# collaborative editing
|
||||||
|
@ -151,7 +151,7 @@ async def _create_reaction(session, shout, author, reaction):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# обновление счетчика комментариев в кеше
|
# обновление счетчика комментариев в кеше
|
||||||
if r.kind == ReactionKind.COMMENT.value:
|
if str(r.kind) == ReactionKind.COMMENT.value:
|
||||||
await update_author_stat(author)
|
await update_author_stat(author)
|
||||||
|
|
||||||
rdict["shout"] = shout.dict()
|
rdict["shout"] = shout.dict()
|
||||||
|
@ -215,7 +215,6 @@ async def create_reaction(_, info, reaction):
|
||||||
if shout and author:
|
if shout and author:
|
||||||
reaction["created_by"] = author.id
|
reaction["created_by"] = author.id
|
||||||
kind = reaction.get("kind")
|
kind = reaction.get("kind")
|
||||||
shout_id = shout.id
|
|
||||||
|
|
||||||
if not kind and isinstance(reaction.get("body"), str):
|
if not kind and isinstance(reaction.get("body"), str):
|
||||||
kind = ReactionKind.COMMENT.value
|
kind = ReactionKind.COMMENT.value
|
||||||
|
@ -260,14 +259,22 @@ async def update_reaction(_, info, reaction):
|
||||||
reaction_query = reaction_query.group_by(Reaction.id)
|
reaction_query = reaction_query.group_by(Reaction.id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
[r, reacted_stat, commented_stat, likes_stat, dislikes_stat, _l] = (
|
result = session.execute(reaction_query).unique().first()
|
||||||
session.execute(reaction_query).unique().first()
|
if result:
|
||||||
)
|
[
|
||||||
|
r,
|
||||||
|
reacted_stat,
|
||||||
|
commented_stat,
|
||||||
|
likes_stat,
|
||||||
|
dislikes_stat,
|
||||||
|
last_comment,
|
||||||
|
] = result
|
||||||
if not r:
|
if not r:
|
||||||
return {"error": "invalid reaction id"}
|
return {"error": "invalid reaction id"}
|
||||||
|
|
||||||
author = session.query(Author).filter(Author.user == user_id).first()
|
author = (
|
||||||
|
session.query(Author).filter(Author.user == user_id).first()
|
||||||
|
)
|
||||||
if author:
|
if author:
|
||||||
if r.created_by != author.id and "editor" not in roles:
|
if r.created_by != author.id and "editor" not in roles:
|
||||||
return {"error": "access denied"}
|
return {"error": "access denied"}
|
||||||
|
@ -323,7 +330,7 @@ async def delete_reaction(_, info, reaction_id: int):
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
# обновление счетчика комментариев в кеше
|
# обновление счетчика комментариев в кеше
|
||||||
if r.kind == ReactionKind.COMMENT.value:
|
if str(r.kind) == ReactionKind.COMMENT.value:
|
||||||
await update_author_stat(author)
|
await update_author_stat(author)
|
||||||
await notify_reaction(reaction_dict, "delete")
|
await notify_reaction(reaction_dict, "delete")
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ async def cache_author(author: dict):
|
||||||
follower_follows_authors_str = await redis.execute(
|
follower_follows_authors_str = await redis.execute(
|
||||||
"GET", f'author:{author.get("id")}:follows-authors'
|
"GET", f'author:{author.get("id")}:follows-authors'
|
||||||
)
|
)
|
||||||
if follower_follows_authors_str:
|
if isinstance(follower_follows_authors_str, str):
|
||||||
follower_follows_authors = json.loads(follower_follows_authors_str)
|
follower_follows_authors = json.loads(follower_follows_authors_str)
|
||||||
c = 0
|
c = 0
|
||||||
for old_author in follower_follows_authors:
|
for old_author in follower_follows_authors:
|
||||||
|
@ -46,7 +46,7 @@ async def cache_author(author: dict):
|
||||||
"GET", f'author:{author.get("id")}:follows-authors'
|
"GET", f'author:{author.get("id")}:follows-authors'
|
||||||
)
|
)
|
||||||
follows_authors = []
|
follows_authors = []
|
||||||
if follows_str:
|
if isinstance(follows_str, str):
|
||||||
follows_authors = json.loads(follows_str)
|
follows_authors = json.loads(follows_str)
|
||||||
if isinstance(follows_authors, list):
|
if isinstance(follows_authors, list):
|
||||||
for followed_author in follows_authors:
|
for followed_author in follows_authors:
|
||||||
|
@ -54,7 +54,7 @@ async def cache_author(author: dict):
|
||||||
followed_author_followers_str = await redis.execute(
|
followed_author_followers_str = await redis.execute(
|
||||||
"GET", f'author:{author.get("id")}:followers'
|
"GET", f'author:{author.get("id")}:followers'
|
||||||
)
|
)
|
||||||
if followed_author_followers_str:
|
if isinstance(followed_author_followers_str, str):
|
||||||
followed_author_followers = json.loads(followed_author_followers_str)
|
followed_author_followers = json.loads(followed_author_followers_str)
|
||||||
c = 0
|
c = 0
|
||||||
for old_follower in followed_author_followers:
|
for old_follower in followed_author_followers:
|
||||||
|
@ -90,7 +90,7 @@ async def cache_follows(follower: Author, entity_type: str, entity, is_insert=Tr
|
||||||
|
|
||||||
# update follower's stats everywhere
|
# update follower's stats everywhere
|
||||||
author_str = await redis.execute("GET", f"author:{follower.id}")
|
author_str = await redis.execute("GET", f"author:{follower.id}")
|
||||||
if author_str:
|
if isinstance(author_str, str):
|
||||||
author = json.loads(author_str)
|
author = json.loads(author_str)
|
||||||
author["stat"][f"{entity_type}s"] = len(updated_data)
|
author["stat"][f"{entity_type}s"] = len(updated_data)
|
||||||
await cache_author(author)
|
await cache_author(author)
|
||||||
|
@ -114,7 +114,7 @@ async def cache_follower(follower: Author, author: Author, is_insert=True):
|
||||||
payload = json.dumps(updated_followers, cls=CustomJSONEncoder)
|
payload = json.dumps(updated_followers, cls=CustomJSONEncoder)
|
||||||
await redis.execute("SET", redis_key, payload)
|
await redis.execute("SET", redis_key, payload)
|
||||||
author_str = await redis.execute("GET", f"author:{follower.id}")
|
author_str = await redis.execute("GET", f"author:{follower.id}")
|
||||||
if author_str:
|
if isinstance(author_str, str):
|
||||||
author = json.loads(author_str)
|
author = json.loads(author_str)
|
||||||
author["stat"]["followers"] = len(updated_followers)
|
author["stat"]["followers"] = len(updated_followers)
|
||||||
await cache_author(author)
|
await cache_author(author)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user