old_console/ncircc/views/notification_api.py
2024-11-02 14:12:45 +03:00

134 lines
5.3 KiB
Python

import logging
from django.db.models import Count, Q
from django.http import Http404
from rest_framework.decorators import action
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from core.mixins import ApiPermissionCheckMixin
from ncircc.models.comments import Comment
from ncircc.models.notification import Notification
from ncircc.serializers.comments import CommentCreateSerializer, CommentRetrieveSerializer
from ncircc.serializers.notification import NotificationSerializer
from ncircc.services.comments import CommentSenderService
from ncircc.services.notification import NotificationSenderCreateService, NotificationUpdateSenderService, \
NotificationUploadFileService, NOCRCCCreateException
from perms.models import Perm
_log = logging.getLogger(__name__)
class NotificationApiViewSet(ApiPermissionCheckMixin,
ListModelMixin,
RetrieveModelMixin,
CreateModelMixin,
UpdateModelMixin,
GenericViewSet):
"""View Set for getting list for creating/updating notification ncircc events."""
serializer_class = NotificationSerializer
queryset = Notification.objects.order_by('updated')
console_permissions = {
'list': [Perm.can_view_message_list],
'retrieve': [Perm.can_view_message_card],
'update': [Perm.can_edit_message_card],
'create': [Perm.can_edit_message_card],
'comments': [Perm.can_view_message_card],
'comments_create': ['can_view_message_card'],
}
def create(self, request, *args, **kwargs) -> Response:
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid():
errors = serializer.errors
_log.error(f'Error: {errors}')
return Response(errors, status=400)
instance = serializer.save()
try:
sender = NotificationSenderCreateService(instance.pk)
except NOCRCCCreateException as err:
instance.delete()
return Response({'error': str(err)}, status=400)
msg, status = sender.send()
if status == 400:
instance.delete()
_log.error(f'Error: {msg}')
return Response({'error': msg}, status=400)
return Response(serializer.data, status=201)
def update(self, request, *args, **kwargs) -> Response:
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
if not serializer.is_valid():
errors = serializer.errors
_log.error(f'Error: {errors}')
return Response(errors, status=400)
serializer.save()
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
sender = NotificationUpdateSenderService(instance.pk)
msg, status = sender.send()
if status == 400:
_log.error(f'Error:{msg}')
return Response({'error': msg}, status=status)
return Response(serializer.data, status=200)
@action(detail=True, methods=['Get'], name='Comment list')
def comments(self, request, pk=None) -> Response:
"""Return comment list."""
if not Notification.objects.filter(pk=pk).exists():
raise Http404
comments = Comment.objects.filter(notification=pk)
data = CommentRetrieveSerializer(comments, many=True).data
comments.update(is_read=True)
return Response(data)
@comments.mapping.post
def comments_create(self, request, pk=None) -> Response:
"""Create comments to ncitcc."""
if not Notification.objects.filter(pk=pk).exists():
raise Http404
serializer = CommentCreateSerializer(data=request.data)
if not serializer.is_valid():
errors = serializer.errors
_log.error(f'Error: {errors}')
return Response(errors, status=400)
text = serializer.data.get('text', '')
sender = CommentSenderService(text, int(pk), request.user)
msg, status = sender.send()
if status == 400:
_log.error(f'Error: {msg}')
return Response({'error': msg}, status=400)
return Response(msg, status=201)
@action(detail=True, methods=['POST'], name='Upload File')
def upload(self, request, pk=None) -> Response:
"""Upload file data."""
file = request.FILES
file_name = file['files'].name
file_data = file['files'].file
uploader = NotificationUploadFileService(pk, file_data, file_name)
msg, status = uploader.send()
if status == 200:
return Response({}, status=200)
else:
return Response({'error': msg}, status=status)
def get_queryset(self):
qs = super().get_queryset()
qs = qs.annotate(new_comment_count=Count('comment', filter=Q(comment__is_read=False)))
return qs
class Meta:
model = Notification