import json import logging import strawberry from sqlalchemy import and_ from sqlalchemy.exc import SQLAlchemyError from orm.notification import NotificationSeen from resolvers.model import Notification, NotificationReaction, NotificationSeenResult from services.db import local_session 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)