from sqlalchemy import and_ from orm.notification import NotificationSeen from services.db import local_session from resolvers.model import Notification, NotificationSeenResult, NotificationReaction import strawberry import logging import json from sqlalchemy.exc import SQLAlchemyError logger = logging.getLogger(__name__) @strawberry.type class Mutation: @strawberry.mutation async def mark_seen(self, info, notification_id: int) -> NotificationSeenResult: author_id = info.context.get("author_id") if author_id: with local_session() as session: try: ns = NotificationSeen(notification=notification_id, viewer=author_id) session.add(ns) session.commit() except SQLAlchemyError as e: session.rollback() logger.error( f"[mark_notification_as_read] Ошибка при обновлении статуса прочтения уведомления: {str(e)}" ) return NotificationSeenResult(error="cant mark as read") return NotificationSeenResult(error=None) @strawberry.mutation async def mark_seen_after(self, info, after: int) -> NotificationSeenResult: # TODO: use latest loaded notification_id as input offset parameter error = None try: author_id = info.context.get("author_id") if author_id: with local_session() as session: nnn = session.query(Notification).filter(and_(Notification.created_at > after)).all() for n in nnn: try: ns = NotificationSeen(notification=n.id, viewer=author_id) session.add(ns) session.commit() except SQLAlchemyError: session.rollback() except Exception as e: print(e) error = "cant mark as read" return NotificationSeenResult(error=error) @strawberry.mutation async def mark_seen_thread(self, info, thread: str, after: int) -> NotificationSeenResult: error = None author_id = info.context.get("author_id") if author_id: [shout_id, reply_to_id] = thread.split("::") with local_session() as session: # TODO: handle new follower and new shout notifications new_reaction_notifications = ( session.query(Notification) .filter( Notification.action == "create", Notification.entity == "reaction", Notification.created_at > after, ) .all() ) removed_reaction_notifications = ( session.query(Notification) .filter( Notification.action == "delete", Notification.entity == "reaction", Notification.created_at > after, ) .all() ) exclude = set([]) for nr in removed_reaction_notifications: reaction: NotificationReaction = json.loads(nr.payload) exclude.add(reaction.id) for n in new_reaction_notifications: reaction: NotificationReaction = json.loads(n.payload) if ( reaction.id not in exclude and str(reaction.shout) == str(shout_id) and str(reaction.reply_to) == str(reply_to_id) ): try: ns = NotificationSeen(notification=n.id, viewer=author_id) session.add(ns) session.commit() except Exception: session.rollback() else: error = "You are not logged in" return NotificationSeenResult(error=error)