This commit is contained in:
parent
674bc9ce63
commit
dbe4dd760b
|
@ -1,13 +1,12 @@
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from resolvers.model import (
|
from resolvers.model import (
|
||||||
NotificationReaction,
|
NotificationReaction,
|
||||||
Notification as NotificationMessage,
|
|
||||||
NotificationGroup,
|
NotificationGroup,
|
||||||
NotificationShout,
|
NotificationShout,
|
||||||
NotificationAuthor,
|
NotificationAuthor,
|
||||||
NotificationsResult,
|
NotificationsResult,
|
||||||
)
|
)
|
||||||
from orm.notification import NotificationSeen
|
from orm.notification import NotificationSeen, Notification
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
import time, json
|
import time, json
|
||||||
import strawberry
|
import strawberry
|
||||||
|
@ -15,20 +14,18 @@ from sqlalchemy.orm import aliased
|
||||||
from sqlalchemy import select, and_
|
from sqlalchemy import select, and_
|
||||||
|
|
||||||
|
|
||||||
async def get_notifications_grouped(
|
async def get_notifications_grouped(author_id: int, after: int = 0, limit: int = 10, offset: int = 0):
|
||||||
author_id: int, after: int = 0, limit: int = 10, offset: int = 0, mark_as_read=False
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Retrieves notifications for a given author.
|
Retrieves notifications for a given author.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
author_id (int): The ID of the author for whom notifications are retrieved.
|
author_id (int): The ID of the author for whom notifications are retrieved.
|
||||||
session: Database connection session
|
after (int, optional): If provided, selects only notifications created after this timestamp will be considered.
|
||||||
after (int, optional): If provided, only notifications created after this timestamp will be considered.
|
limit (int, optional): The maximum number of groupa to retrieve.
|
||||||
limit (int, optional): The maximum number of notifications to retrieve.
|
offset (int, optional): Offset for pagination
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Dict[str, NotificationGroup]: A dictionary where keys are thread IDs and values are NotificationGroup objects.
|
Dict[str, NotificationGroup], int, int: A dictionary where keys are thread IDs and values are NotificationGroup objects, unread and total amounts.
|
||||||
|
|
||||||
This function queries the database to retrieve notifications for the specified author, considering optional filters.
|
This function queries the database to retrieve notifications for the specified author, considering optional filters.
|
||||||
The result is a dictionary where each key is a thread ID, and the corresponding value is a NotificationGroup
|
The result is a dictionary where each key is a thread ID, and the corresponding value is a NotificationGroup
|
||||||
|
@ -43,18 +40,19 @@ async def get_notifications_grouped(
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
NotificationSeenAlias = aliased(NotificationSeen)
|
NotificationSeenAlias = aliased(NotificationSeen)
|
||||||
query = select(NotificationMessage, NotificationSeenAlias.viewer.label("seen")).outerjoin(
|
query = select(Notification, NotificationSeenAlias.viewer.label("seen")).outerjoin(
|
||||||
NotificationSeen,
|
NotificationSeen,
|
||||||
and_(NotificationSeen.viewer == author_id, NotificationSeen.notification == NotificationMessage.id),
|
and_(NotificationSeen.viewer == author_id, NotificationSeen.notification == Notification.id),
|
||||||
)
|
)
|
||||||
if after:
|
if after:
|
||||||
query = query.filter(NotificationMessage.created_at > after)
|
query = query.filter(Notification.created_at > after)
|
||||||
query = query.group_by(NotificationSeen.notification)
|
query = query.group_by(NotificationSeen.notification)
|
||||||
|
|
||||||
notifications: Dict[str, NotificationGroup] = {}
|
groups_amount = 0
|
||||||
counter = 0
|
|
||||||
unread = 0
|
unread = 0
|
||||||
total = 0
|
total = 0
|
||||||
|
notifications_by_thread: Dict[str, List[Notification]] = {}
|
||||||
|
groups_by_thread: Dict[str, NotificationGroup] = {}
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
notifications_result = session.execute(query)
|
notifications_result = session.execute(query)
|
||||||
for n, seen in notifications_result:
|
for n, seen in notifications_result:
|
||||||
|
@ -63,26 +61,28 @@ async def get_notifications_grouped(
|
||||||
thread_id = ""
|
thread_id = ""
|
||||||
payload = json.loads(n.payload)
|
payload = json.loads(n.payload)
|
||||||
print(f"[resolvers.schema] {n.action} {n.entity}: {payload}")
|
print(f"[resolvers.schema] {n.action} {n.entity}: {payload}")
|
||||||
if n.entity == "shout":
|
if n.entity == "shout" and n.action == "create":
|
||||||
shout: NotificationShout = payload
|
shout: NotificationShout = payload
|
||||||
thread_id += f"{shout.id}"
|
thread_id += f"{shout.id}"
|
||||||
if n.action == "delete":
|
print(f"[resolvers.schema] create shout: {shout}")
|
||||||
del notifications[thread_id]
|
group = groups_by_thread.get(thread_id) or NotificationGroup(
|
||||||
elif n.action == "create":
|
id=thread_id,
|
||||||
print(f"[resolvers.schema] create shout: {shout}")
|
entity=n.entity,
|
||||||
notification_group = NotificationGroup(
|
shout=shout,
|
||||||
id=thread_id,
|
authors=shout.authors,
|
||||||
entity=n.entity,
|
updated_at=shout.created_at,
|
||||||
shout=shout,
|
reactions=[],
|
||||||
authors=shout.authors,
|
action="create",
|
||||||
updated_at=shout.created_at,
|
seen=author_id in n.seen
|
||||||
reactions=[],
|
)
|
||||||
action="create",
|
# store group in result
|
||||||
)
|
groups_by_thread[thread_id] = group
|
||||||
# store group in result
|
notifications = notifications_by_thread.get(thread_id, [])
|
||||||
notifications[thread_id] = notification_group
|
if n not in notifications:
|
||||||
counter += 1
|
notifications.append(n)
|
||||||
elif n.entity == "reaction":
|
notifications_by_thread[thread_id] = notifications
|
||||||
|
groups_amount += 1
|
||||||
|
elif n.entity == "reaction" and n.action == "create":
|
||||||
reaction: NotificationReaction = payload
|
reaction: NotificationReaction = payload
|
||||||
shout: NotificationShout = reaction.shout
|
shout: NotificationShout = reaction.shout
|
||||||
thread_id += f"{reaction.shout}"
|
thread_id += f"{reaction.shout}"
|
||||||
|
@ -92,25 +92,31 @@ async def get_notifications_grouped(
|
||||||
elif reaction.kind == "COMMENT":
|
elif reaction.kind == "COMMENT":
|
||||||
if reaction.reply_to:
|
if reaction.reply_to:
|
||||||
thread_id += f"{'::' + str(reaction.reply_to)}"
|
thread_id += f"{'::' + str(reaction.reply_to)}"
|
||||||
notification_group: NotificationGroup | None = notifications.get(thread_id)
|
group: NotificationGroup | None = groups_by_thread.get(thread_id)
|
||||||
if notification_group:
|
notifications: List[Notification] = notifications_by_thread.get(thread_id)
|
||||||
notification_group.shout = shout
|
if group and notifications:
|
||||||
notification_group.authors.append(reaction.created_by)
|
group.seen = False # any not seen notification make it false
|
||||||
if not notification_group.reactions:
|
group.shout = shout
|
||||||
notification_group.reactions = []
|
group.authors.append(reaction.created_by)
|
||||||
notification_group.reactions.append(reaction.id)
|
if not group.reactions:
|
||||||
|
group.reactions = []
|
||||||
|
group.reactions.append(reaction.id)
|
||||||
# store group in result
|
# store group in result
|
||||||
notifications[thread_id] = notification_group
|
groups_by_thread[thread_id] = group
|
||||||
counter += 1
|
notifications = notifications_by_thread.get(thread_id, [])
|
||||||
|
if n not in notifications:
|
||||||
|
notifications.append(n)
|
||||||
|
notifications_by_thread[thread_id] = notifications
|
||||||
|
groups_amount += 1
|
||||||
else:
|
else:
|
||||||
counter += 1
|
groups_amount += 1
|
||||||
if counter > limit:
|
if groups_amount > limit:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# init notification group
|
# init notification group
|
||||||
reactions = []
|
reactions = []
|
||||||
reactions.append(reaction.id)
|
reactions.append(reaction.id)
|
||||||
notification_group = NotificationGroup(
|
group = NotificationGroup(
|
||||||
id=thread_id,
|
id=thread_id,
|
||||||
action=n.action,
|
action=n.action,
|
||||||
entity=n.entity,
|
entity=n.entity,
|
||||||
|
@ -120,15 +126,19 @@ async def get_notifications_grouped(
|
||||||
authors=[
|
authors=[
|
||||||
reaction.created_by,
|
reaction.created_by,
|
||||||
],
|
],
|
||||||
|
seen=author_id in n.seen
|
||||||
)
|
)
|
||||||
# store group in result
|
# store group in result
|
||||||
notifications[thread_id] = notification_group
|
groups_by_thread[thread_id] = group
|
||||||
|
notifications = notifications_by_thread.get(thread_id, [])
|
||||||
|
if n not in notifications:
|
||||||
|
notifications.append(n)
|
||||||
|
notifications_by_thread[thread_id] = notifications
|
||||||
|
|
||||||
elif n.entity == "follower":
|
elif n.entity == "follower":
|
||||||
thread_id = "followers"
|
thread_id = "followers"
|
||||||
follower: NotificationAuthor = payload
|
follower: NotificationAuthor = payload
|
||||||
notification_group = notifications.get(thread_id)
|
group = groups_by_thread.get(thread_id) or NotificationGroup(
|
||||||
if not notification_group:
|
|
||||||
notification_group = NotificationGroup(
|
|
||||||
id=thread_id,
|
id=thread_id,
|
||||||
authors=[follower],
|
authors=[follower],
|
||||||
updated_at=int(time.time()),
|
updated_at=int(time.time()),
|
||||||
|
@ -136,18 +146,22 @@ async def get_notifications_grouped(
|
||||||
reactions=[],
|
reactions=[],
|
||||||
entity="follower",
|
entity="follower",
|
||||||
action="follow",
|
action="follow",
|
||||||
|
seen=author_id in n.seen
|
||||||
)
|
)
|
||||||
else:
|
group.authors = [follower, ]
|
||||||
notification_group.authors = [follower, ]
|
group.updated_at = int(time.time())
|
||||||
notification_group.updated_at = int(time.time())
|
|
||||||
# store group in result
|
# store group in result
|
||||||
notifications[thread_id] = notification_group
|
groups_by_thread[thread_id] = group
|
||||||
counter += 1
|
notifications = notifications_by_thread.get(thread_id, [])
|
||||||
|
if n not in notifications:
|
||||||
|
notifications.append(n)
|
||||||
|
notifications_by_thread[thread_id] = notifications
|
||||||
|
groups_amount += 1
|
||||||
|
|
||||||
if counter > limit:
|
if groups_amount > limit:
|
||||||
break
|
break
|
||||||
|
|
||||||
return notifications, unread, total
|
return groups_by_thread, unread, total
|
||||||
|
|
||||||
|
|
||||||
@strawberry.type
|
@strawberry.type
|
||||||
|
|
|
@ -59,6 +59,7 @@ class NotificationGroup:
|
||||||
action: Optional[str]
|
action: Optional[str]
|
||||||
shout: Optional[NotificationShout]
|
shout: Optional[NotificationShout]
|
||||||
reactions: Optional[List[int]]
|
reactions: Optional[List[int]]
|
||||||
|
seen: Optional[bool]
|
||||||
# latest reaction.created_at for reactions-updates
|
# latest reaction.created_at for reactions-updates
|
||||||
# no timestamp for followers-updates
|
# no timestamp for followers-updates
|
||||||
# latest shout.created_at for shouts-updates
|
# latest shout.created_at for shouts-updates
|
||||||
|
|
Loading…
Reference in New Issue
Block a user