core/services/triggers.py

164 lines
5.7 KiB
Python
Raw Normal View History

2024-04-09 08:17:32 +00:00
import asyncio
2024-04-09 13:59:41 +00:00
import json
2024-04-09 08:17:32 +00:00
from sqlalchemy import event, select
from orm.author import Author, AuthorFollower
from orm.reaction import Reaction
from orm.shout import Shout, ShoutAuthor
2024-04-19 15:22:07 +00:00
from orm.topic import Topic, TopicFollower
2024-04-09 08:17:32 +00:00
from resolvers.stat import get_with_stat
2024-05-06 21:02:15 +00:00
from services.cache import cache_author, cache_follow_author_change, cache_follows
2024-04-09 13:59:41 +00:00
from services.encoders import CustomJSONEncoder
2024-04-09 08:17:32 +00:00
from services.logger import root_logger as logger
2024-04-19 15:22:07 +00:00
from services.rediscache import redis
2024-04-09 08:17:32 +00:00
DEFAULT_FOLLOWS = {
2024-04-17 15:32:23 +00:00
"topics": [],
"authors": [],
"communities": [{"id": 1, "name": "Дискурс", "slug": "discours", "pic": ""}],
2024-04-09 08:17:32 +00:00
}
2024-04-17 15:32:23 +00:00
async def handle_author_follower_change(
author_id: int, follower_id: int, is_insert: bool
):
2024-04-09 13:59:41 +00:00
logger.info(author_id)
author_query = select(Author).select_from(Author).filter(Author.id == author_id)
[author] = get_with_stat(author_query)
follower_query = select(Author).select_from(Author).filter(Author.id == follower_id)
[follower] = get_with_stat(follower_query)
if follower and author:
await cache_author(author.dict())
2024-05-06 21:06:31 +00:00
await cache_follows(
follower.dict(), "author", author.dict(), is_insert
) # cache_author(follower_dict) inside
await cache_follow_author_change(
follower.dict(), author.dict(), is_insert
) # cache_author(follower_dict) inside
2024-04-09 13:59:41 +00:00
2024-04-17 15:32:23 +00:00
async def handle_topic_follower_change(
topic_id: int, follower_id: int, is_insert: bool
):
2024-04-09 13:59:41 +00:00
logger.info(topic_id)
topic_query = select(Topic).filter(Topic.id == topic_id)
[topic] = get_with_stat(topic_query)
follower_query = select(Author).filter(Author.id == follower_id)
[follower] = get_with_stat(follower_query)
if follower and topic:
await cache_author(follower.dict())
2024-04-17 15:32:23 +00:00
await redis.execute(
"SET", f"topic:{topic.id}", json.dumps(topic.dict(), cls=CustomJSONEncoder)
)
2024-04-19 15:22:07 +00:00
await cache_follows(follower.dict(), "topic", topic.dict(), is_insert)
2024-04-09 13:59:41 +00:00
# handle_author_follow and handle_topic_follow -> cache_author, cache_follows, cache_followers
2024-04-09 08:17:32 +00:00
def after_shout_update(_mapper, _connection, shout: Shout):
2024-04-17 15:32:23 +00:00
logger.info("after shout update")
2024-04-09 08:17:32 +00:00
# Main query to get authors associated with the shout through ShoutAuthor
authors_query = (
select(Author)
.select_from(ShoutAuthor) # Select from ShoutAuthor
.join(Author, Author.id == ShoutAuthor.author) # Join with Author
.filter(ShoutAuthor.shout == shout.id) # Filter by shout.id
)
for author_with_stat in get_with_stat(authors_query):
asyncio.create_task(cache_author(author_with_stat.dict()))
def after_reaction_update(mapper, connection, reaction: Reaction):
2024-04-17 15:32:23 +00:00
logger.info("after reaction update")
2024-04-09 08:17:32 +00:00
try:
author_subquery = select(Author).where(Author.id == reaction.created_by)
replied_author_subquery = (
select(Author)
.join(Reaction, Author.id == Reaction.created_by)
.where(Reaction.id == reaction.reply_to)
)
author_query = (
select(author_subquery.subquery())
.select_from(author_subquery.subquery())
.union(
select(replied_author_subquery.subquery()).select_from(
replied_author_subquery.subquery()
)
)
)
for author_with_stat in get_with_stat(author_query):
asyncio.create_task(cache_author(author_with_stat.dict()))
shout = connection.execute(
select(Shout).select_from(Shout).where(Shout.id == reaction.shout)
).first()
if shout:
after_shout_update(mapper, connection, shout)
except Exception as exc:
logger.error(exc)
import traceback
traceback.print_exc()
def after_author_update(_mapper, _connection, author: Author):
2024-04-17 15:32:23 +00:00
logger.info("after author update")
2024-04-09 08:17:32 +00:00
q = select(Author).where(Author.id == author.id)
result = get_with_stat(q)
if result:
[author_with_stat] = result
2024-05-05 17:16:45 +00:00
if author_with_stat:
_task = asyncio.create_task(cache_author(author_with_stat.dict()))
2024-04-09 08:17:32 +00:00
def after_topic_follower_insert(_mapper, _connection, target: TopicFollower):
logger.info(target)
asyncio.create_task(
2024-05-05 17:17:07 +00:00
handle_topic_follower_change(target.topic, target.follower, True) # type: ignore
2024-04-09 08:17:32 +00:00
)
def after_topic_follower_delete(_mapper, _connection, target: TopicFollower):
logger.info(target)
asyncio.create_task(
2024-05-05 17:17:07 +00:00
handle_topic_follower_change(target.topic, target.follower, False) # type: ignore
2024-04-09 08:17:32 +00:00
)
def after_author_follower_insert(_mapper, _connection, target: AuthorFollower):
logger.info(target)
asyncio.create_task(
2024-05-05 17:17:07 +00:00
handle_author_follower_change(target.author, target.follower, True) # type: ignore
2024-04-09 08:17:32 +00:00
)
def after_author_follower_delete(_mapper, _connection, target: AuthorFollower):
logger.info(target)
asyncio.create_task(
2024-05-05 17:17:07 +00:00
handle_author_follower_change(target.author, target.follower, False) # type: ignore
2024-04-09 08:17:32 +00:00
)
def events_register():
2024-04-17 15:32:23 +00:00
event.listen(Shout, "after_insert", after_shout_update)
event.listen(Shout, "after_update", after_shout_update)
2024-04-09 08:17:32 +00:00
2024-04-17 15:32:23 +00:00
event.listen(Reaction, "after_insert", after_reaction_update)
event.listen(Reaction, "after_update", after_reaction_update)
2024-04-09 08:17:32 +00:00
2024-04-17 15:32:23 +00:00
event.listen(Author, "after_insert", after_author_update)
event.listen(Author, "after_update", after_author_update)
2024-04-09 08:17:32 +00:00
2024-04-17 15:32:23 +00:00
event.listen(AuthorFollower, "after_insert", after_author_follower_insert)
event.listen(AuthorFollower, "after_delete", after_author_follower_delete)
2024-04-09 08:17:32 +00:00
2024-04-17 15:32:23 +00:00
event.listen(TopicFollower, "after_insert", after_topic_follower_insert)
event.listen(TopicFollower, "after_delete", after_topic_follower_delete)
2024-04-09 08:17:32 +00:00
2024-04-17 15:32:23 +00:00
logger.info("cache events were registered!")