from rest_framework import generics, views, status from rest_framework.response import Response from django.shortcuts import get_list_or_404 from rest_framework.permissions import IsAuthenticated from photo_log.models import ( PhotoGroup, Photo, PhotoLog, PhotoTag, PhotoLogTemplate, ) from .serializers import ( PhotoGroupSerializer, PhotosSerializer, PhotoSerializer, AddPhotoSerializer, PhotoUpdateSerializer, PhotoLogSerializer, PhotoLogsSerializer, PhotoTagSerializer, PhotoLogTemplateSerializer, UserSerializer, ) from photo_log import tasks from django.db.models import FileField from django.core.files.uploadedfile import InMemoryUploadedFile from django.core.files.base import ContentFile from django.contrib.auth import get_user_model from io import BytesIO from PIL import Image, ExifTags class PhotoTagsAPIView(generics.ListAPIView): queryset = PhotoTag.objects.all() serializer_class = PhotoTagSerializer class CreatePhotoTagAPIView(generics.CreateAPIView): queryset = PhotoTag.objects.all() serializer_class = PhotoTagSerializer class RetrieveUpdateDestroyPhotoTagAPIView(generics.RetrieveUpdateDestroyAPIView): queryset = PhotoTag.objects.all() serializer_class = PhotoTagSerializer class PhotoLogTemplatesAPIView(generics.ListAPIView): queryset = PhotoLogTemplate.objects.all() serializer_class = PhotoLogTemplateSerializer class CreatePhotoLogTemplateAPIView(generics.CreateAPIView): queryset = PhotoLogTemplate.objects.all() serializer_class = PhotoLogTemplateSerializer class RetrieveUpdateDestroyPhotoLogTemplateAPIView(generics.RetrieveUpdateDestroyAPIView): queryset = PhotoLogTemplate.objects.all() serializer_class = PhotoLogTemplateSerializer class PhotoGroupAPIView(generics.ListAPIView): serializer_class = PhotoGroupSerializer permission_classes = [IsAuthenticated] def get_queryset(self): queryset = PhotoGroup.objects.all() user = self.request.user if not user.is_superuser: queryset = queryset.filter(owner=user) return queryset class PhotosAPIView(generics.ListAPIView): serializer_class = PhotoSerializer permission_classes = [IsAuthenticated] def get_queryset(self): queryset = Photo.objects.all() user = self.request.user if not user.is_superuser: queryset = queryset.filter(owner=user) self.serializer_class = PhotosSerializer photogroup = self.request.query_params.get('photogroup') if photogroup is not None: queryset = get_list_or_404(queryset, group=photogroup) self.serializer_class = PhotoSerializer return queryset class PhotoAPIView(generics.RetrieveAPIView): serializer_class = PhotoSerializer queryset = Photo.objects.all() class AddPhotoAPIView(generics.CreateAPIView): queryset = Photo.objects.all() serializer_class = AddPhotoSerializer permission_classes = [IsAuthenticated] def perform_create(self, serializer): serializer.save(owner=self.request.user) class AddPhotoGroupAPIView(generics.CreateAPIView): queryset = PhotoGroup.objects.all() serializer_class = PhotoGroupSerializer permission_classes = [IsAuthenticated] def perform_create(self, serializer): serializer.save(owner=self.request.user) class PhotoLogAPIView(generics.RetrieveAPIView): serializer_class = PhotoLogSerializer queryset = PhotoLog.objects.all() class PhotoLogsAPIView(generics.ListAPIView): serializer_class = PhotoLogsSerializer queryset = PhotoLog.objects.all() class AddPhotoLogAPIView(generics.CreateAPIView): queryset = PhotoLog.objects.all() serializer_class = PhotoLogSerializer class DestroyPhotoLogAPIView(generics.DestroyAPIView): queryset = PhotoLog.objects.all() serializer_class = PhotoLogSerializer class DestroyPhotoAPIView(generics.DestroyAPIView): queryset = Photo.objects.all() serializer_class = PhotoSerializer class UpdatePhotoLogAPIView(generics.UpdateAPIView): queryset = PhotoLog.objects.all() serializer_class = PhotoLogSerializer lookup_field = 'pk' def update(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return Response({'ok'}) else: return Response({"error": serializer.errors}, status=status.HTTP_400_BAD_REQUEST) class UpdatePhotoAPIView(generics.UpdateAPIView): queryset = Photo.objects.all() serializer_class = PhotoUpdateSerializer lookup_field = 'pk' def update(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return Response({'ok'}) else: return Response({"error": serializer.errors}, status=status.HTTP_400_BAD_REQUEST) class GeneratePhotoLogAPIView(generics.RetrieveAPIView): queryset = PhotoLog.objects.all() serializer_class = PhotoLogSerializer def get(self, request, *args, **kwargs): photolog = self.get_object() photolog_data = self.get_serializer(photolog).data if photolog_data: tasks.generate_photo_log_chain( photolog_data['id'], ) return Response({'status': 'task created'}) return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND) class AutoCropPhotoAPIView(generics.RetrieveAPIView): queryset = Photo.objects.all() serializer_class = PhotoSerializer def get(self, request, *args, **kwargs): photo = None photo_data = self.get_serializer(self.get_object()).data if photo_data: photo_id = photo_data['id'] if photo_id: if not 'mode' in request.query_params: return Response({'error':'cropping mode not specified (auto, bbox or inters)'}, status=status.HTTP_400_BAD_REQUEST) mode = request.query_params.get('mode') photo = Photo.objects.get(id=photo_id) cropped_img = photo.cropped_image if cropped_img: cropped_img = cropped_img.name else: cropped_img = None if mode == 'bbox': tasks.crop_image_bbox_chain( photo.id, photo.original_image.name, photo.bbox_coords, photo.rotate, cropped_img ) elif mode == 'auto' or mode == 'inters': # TODO: mode 'inters': just calculate intersections w/o saving the cropped image tasks.crop_image_auto_chain( photo.id, photo.original_image.name, cropped_img ) else: return Response({'error':'invalid cropping mode (auto, bbox or inters)'}, status=status.HTTP_400_BAD_REQUEST) if photo: return self.retrieve(request, *args, **kwargs) return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND) class UsersAPIView(generics.ListAPIView): queryset = get_user_model().objects.all() serializer_class = UserSerializer