shout-following-upgrade
All checks were successful
Deploy on push / deploy (push) Successful in 5m59s
All checks were successful
Deploy on push / deploy (push) Successful in 5m59s
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -183,3 +183,5 @@ docs/progress/*
|
|||||||
panel/graphql/generated
|
panel/graphql/generated
|
||||||
|
|
||||||
test_e2e.db*
|
test_e2e.db*
|
||||||
|
|
||||||
|
uv.lock
|
||||||
@@ -18,7 +18,7 @@ from cache.cache import (
|
|||||||
from orm.author import Author, AuthorFollower
|
from orm.author import Author, AuthorFollower
|
||||||
from orm.community import Community, CommunityAuthor, CommunityFollower
|
from orm.community import Community, CommunityAuthor, CommunityFollower
|
||||||
from orm.reaction import Reaction
|
from orm.reaction import Reaction
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
from orm.shout import Shout, ShoutAuthor, ShoutReactionsFollower, ShoutTopic
|
||||||
from orm.topic import Topic
|
from orm.topic import Topic
|
||||||
from resolvers.stat import get_with_stat
|
from resolvers.stat import get_with_stat
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
@@ -974,12 +974,23 @@ async def get_author_follows(
|
|||||||
has_access = is_admin or (viewer_id is not None and str(viewer_id) == str(temp_author.id))
|
has_access = is_admin or (viewer_id is not None and str(viewer_id) == str(temp_author.id))
|
||||||
followed_authors.append(temp_author.dict(has_access))
|
followed_authors.append(temp_author.dict(has_access))
|
||||||
|
|
||||||
|
# Получаем подписанные шауты
|
||||||
|
followed_shouts = []
|
||||||
|
with local_session() as session:
|
||||||
|
shout_followers = (
|
||||||
|
session.query(ShoutReactionsFollower).filter(ShoutReactionsFollower.follower == author_id).all()
|
||||||
|
)
|
||||||
|
for sf in shout_followers:
|
||||||
|
shout = session.query(Shout).filter(Shout.id == sf.shout).first()
|
||||||
|
if shout:
|
||||||
|
followed_shouts.append(shout.dict())
|
||||||
|
|
||||||
followed_communities = DEFAULT_COMMUNITIES # TODO: get followed communities
|
followed_communities = DEFAULT_COMMUNITIES # TODO: get followed communities
|
||||||
return {
|
return {
|
||||||
"authors": followed_authors,
|
"authors": followed_authors,
|
||||||
"topics": followed_topics,
|
"topics": followed_topics,
|
||||||
"communities": followed_communities,
|
"communities": followed_communities,
|
||||||
"shouts": [],
|
"shouts": followed_shouts,
|
||||||
"error": None,
|
"error": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from orm.notification import (
|
|||||||
NotificationEntity,
|
NotificationEntity,
|
||||||
NotificationSeen,
|
NotificationSeen,
|
||||||
)
|
)
|
||||||
from orm.shout import Shout
|
from orm.shout import Shout, ShoutReactionsFollower
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from storage.db import local_session
|
from storage.db import local_session
|
||||||
from storage.schema import mutation, query
|
from storage.schema import mutation, query
|
||||||
@@ -57,6 +57,37 @@ def query_notifications(author_id: int, after: int = 0) -> tuple[int, int, list[
|
|||||||
return total, unread, notifications
|
return total, unread, notifications
|
||||||
|
|
||||||
|
|
||||||
|
def check_subscription(shout_id: int, current_author_id: int) -> bool:
|
||||||
|
"""
|
||||||
|
Проверяет подписку пользователя на уведомления о шауте.
|
||||||
|
|
||||||
|
Проверяет наличие записи в ShoutReactionsFollower:
|
||||||
|
- Запись есть → подписан
|
||||||
|
- Записи нет → не подписан (отписался или никогда не подписывался)
|
||||||
|
|
||||||
|
Автоматическая подписка (auto=True) создается при:
|
||||||
|
- Создании поста
|
||||||
|
- Первом комментарии/реакции
|
||||||
|
|
||||||
|
Отписка = удаление записи из таблицы
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True если подписан на уведомления
|
||||||
|
"""
|
||||||
|
with local_session() as session:
|
||||||
|
# Проверяем наличие записи в ShoutReactionsFollower
|
||||||
|
follow = (
|
||||||
|
session.query(ShoutReactionsFollower)
|
||||||
|
.filter(
|
||||||
|
ShoutReactionsFollower.follower == current_author_id,
|
||||||
|
ShoutReactionsFollower.shout == shout_id,
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
return follow is not None
|
||||||
|
|
||||||
|
|
||||||
def group_notification(
|
def group_notification(
|
||||||
thread: str,
|
thread: str,
|
||||||
authors: list[Any] | None = None,
|
authors: list[Any] | None = None,
|
||||||
@@ -118,15 +149,20 @@ def get_notifications_grouped(author_id: int, after: int = 0, limit: int = 10, o
|
|||||||
if str(notification.entity) == NotificationEntity.SHOUT.value:
|
if str(notification.entity) == NotificationEntity.SHOUT.value:
|
||||||
shout = payload
|
shout = payload
|
||||||
shout_id = shout.get("id")
|
shout_id = shout.get("id")
|
||||||
author_id = shout.get("created_by")
|
shout_author_id = shout.get("created_by")
|
||||||
thread_id = f"shout-{shout_id}"
|
thread_id = f"shout-{shout_id}"
|
||||||
|
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
author = session.query(Author).where(Author.id == author_id).first()
|
author = session.query(Author).where(Author.id == shout_author_id).first()
|
||||||
shout = session.query(Shout).where(Shout.id == shout_id).first()
|
shout = session.query(Shout).where(Shout.id == shout_id).first()
|
||||||
if author and shout:
|
if author and shout:
|
||||||
|
# Проверяем подписку - если не подписан, пропускаем это уведомление
|
||||||
|
if not check_subscription(shout_id, author_id):
|
||||||
|
continue
|
||||||
|
|
||||||
author_dict = author.dict()
|
author_dict = author.dict()
|
||||||
shout_dict = shout.dict()
|
shout_dict = shout.dict()
|
||||||
|
|
||||||
group = group_notification(
|
group = group_notification(
|
||||||
thread_id,
|
thread_id,
|
||||||
shout=shout_dict,
|
shout=shout_dict,
|
||||||
@@ -164,6 +200,10 @@ def get_notifications_grouped(author_id: int, after: int = 0, limit: int = 10, o
|
|||||||
existing_group["reactions"].append(reaction)
|
existing_group["reactions"].append(reaction)
|
||||||
groups_by_thread[thread_id] = existing_group
|
groups_by_thread[thread_id] = existing_group
|
||||||
else:
|
else:
|
||||||
|
# Проверяем подписку - если не подписан, пропускаем это уведомление
|
||||||
|
if not check_subscription(shout_id, author_id):
|
||||||
|
continue
|
||||||
|
|
||||||
group = group_notification(
|
group = group_notification(
|
||||||
thread_id,
|
thread_id,
|
||||||
authors=[author_dict],
|
authors=[author_dict],
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ type AuthorFollowsResult {
|
|||||||
topics: [Topic]
|
topics: [Topic]
|
||||||
authors: [Author]
|
authors: [Author]
|
||||||
communities: [Community]
|
communities: [Community]
|
||||||
|
shouts: [Shout]
|
||||||
error: String
|
error: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
uv.lock
generated
2
uv.lock
generated
@@ -425,7 +425,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "discours-core"
|
name = "discours-core"
|
||||||
version = "0.9.28"
|
version = "0.9.32"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "ariadne" },
|
{ name = "ariadne" },
|
||||||
|
|||||||
Reference in New Issue
Block a user