Skip to content

Instantly share code, notes, and snippets.

@ariel-devsar
Created June 17, 2020 03:52
Show Gist options
  • Select an option

  • Save ariel-devsar/d127fa3ccf7321a63812afd9af48da55 to your computer and use it in GitHub Desktop.

Select an option

Save ariel-devsar/d127fa3ccf7321a63812afd9af48da55 to your computer and use it in GitHub Desktop.
from __future__ import unicode_literals
import logging
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, get_list_or_404
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from apps.common.permissions import is_tagger_admin
from rest_framework.response import Response
from rest_framework.filters import OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.permissions import IsAuthenticated
from apps.common.filters import SearchByProperty
from apps.common.pagination import Mp20Pagination
from rest_framework.status import (HTTP_201_CREATED, HTTP_200_OK, HTTP_202_ACCEPTED,
HTTP_400_BAD_REQUEST, HTTP_403_FORBIDDEN)
from rest_framework.generics import ListCreateAPIView, GenericAPIView
from apps.mp_user.models import MPUser
from apps.tagger.models import TaggerJob, Label, SemanticTag
from apps.tagger.filters import TaggerJobViewableBackend
from apps.tagger.serializers import (TaggerJobSerializer, TaggerJobShortSummarySerializer,
SemanticTagSerializer, LabelSerializer)
from apps.tagger.tasks import saveCompleteTaggerJob
from apps.scan_model.cdn import get_cdn
from apps.scan_model.models import ModelFile
from apps.scan_model.serializers import ModelFileSerializer
logger = logging.getLogger(__name__)
class TaggerJobsView(ListCreateAPIView):
queryset = TaggerJob.objects.all()
serializer_class = TaggerJobShortSummarySerializer
permission_classes = (IsAuthenticated,)
filter_backends = (OrderingFilter,
DjangoFilterBackend,
TaggerJobViewableBackend,
SearchByProperty('name', 'uuid', 'creator'))
ordering = '-created'
pagination_class = Mp20Pagination
def get_serializer_class(self):
if self.request.method == 'POST':
return TaggerJobDetailView.serializer_class
return super(TaggerJobsView, self).get_serializer_class()
def post(self, request, *args, **kwargs):
if request.method == 'POST' and not is_tagger_admin(request.user):
return Response(status=HTTP_403_FORBIDDEN)
return super(TaggerJobsView, self).post(self.request, *args, **kwargs)
class TaggerJobDetailView(RetrieveUpdateDestroyAPIView):
queryset = TaggerJob.objects.all()
serializer_class = TaggerJobSerializer
# lookup_field = 'uuid'
lookup_url_kwarg = "uuid"
permission_classes = (IsAuthenticated,)
def get(self, request, *args, **kwargs):
user = self.request.user
uuid = self.kwargs.get(self.lookup_url_kwarg)
job = get_object_or_404(TaggerJob, uuid=uuid)
if user not in job.users.all():
job.users.add(user)
job.save()
return Response(data=TaggerJobSerializer(job).data,
status=HTTP_200_OK)
def patch(self, request, *args, **kwargs):
"""
This is called when a user is completing a job, not for editing
"""
active_user = MPUser.objects.get(sid=request.data.get('userSid', None))
job = TaggerJob.objects.get(uuid=request.data.get('uuid'), users__sid=active_user.sid)
if active_user == request.user or job.creator == request.user:
job.completed.add(active_user)
else:
return Response(data="Requester is not admin or active user",
status=HTTP_403_FORBIDDEN)
job.save()
saveCompleteTaggerJob.delay(job.uuid, active_user.sid)
return Response(status=HTTP_202_ACCEPTED)
def delete(self, request, *args, **kwargs):
"""
Removes the job and tags related to the job
"""
user = self.request.user
uuid = self.kwargs.get(self.lookup_url_kwarg)
job = get_object_or_404(TaggerJob, uuid=uuid)
if job.creator == user:
job.delete()
return Response(status=HTTP_200_OK)
return Response(status=HTTP_403_FORBIDDEN)
class AvailableFiles(GenericAPIView):
"""
Returns a list of csvs for each job.
"""
queryset = TaggerJob.objects.all()
lookup_field = 'uuid'
def get(self, request, uuid, *args, **kwargs):
if not request.user.is_authenticated:
return Response(status=HTTP_403_FORBIDDEN)
job = get_object_or_404(self.queryset, uuid=uuid)
return Response(self.get_files(job), status=HTTP_200_OK)
def get_files(self, job):
"""
Gets the list.
"""
files = []
cdn = get_cdn()
if cdn is None:
raise Exception("No CDN configured.")
job_uuid = job.uuid.hex
for user in job.completed.all():
files.append(
ModelFile(
name="{}.csv".format(user.sid),
file_type="text/csv",
url=cdn.make_url("apifs/tagger-jobs/{}/{}.csv".format(
job_uuid,
user.sid),
timeout=300)
)
)
serializer = ModelFileSerializer(files, many=True)
return serializer.data
class TaggerTagsView(GenericAPIView):
queryset = SemanticTag.objects.all()
permission_classes = (IsAuthenticated,)
multiple_lookup_fields = ['job', 'scanmodel', 'model', 'user']
def get(self, request, *args, **kwargs):
job = request.query_params.get('job', None)
user = request.query_params.get('user', None)
if user != request.user and job.creator != request.user:
return Response(data="Requester is not admin or active user",
status=HTTP_403_FORBIDDEN)
scanmodel = request.query_params.get('model', None)
queryset = SemanticTag.objects.all()
objs = get_list_or_404(queryset, job=job, user=user, scanmodel=scanmodel)
tags = {}
tags['tags'] = [{'label': x.label.name} for x in objs]
return Response(data=tags, status=HTTP_200_OK)
def post(self, request, *args, **kwargs):
serializer = SemanticTagSerializer(data=request.data)
if not serializer.is_valid():
return Response(data=serializer.errors,
status=HTTP_400_BAD_REQUEST)
job = TaggerJob.objects.get(uuid=serializer.validated_data['job'].uuid)
active_user = serializer.validated_data.get('user', None)
if active_user == request.user or job.creator == request.user:
job.update_user_last_tagged(active_user, serializer.validated_data.get('scanmodel').sid)
else:
return Response(data="Requester must be the creator for this action",
status=HTTP_403_FORBIDDEN)
tags = SemanticTag.objects.filter(
job=job,
user=active_user,
scanmodel=serializer.validated_data.get('scanmodel'),
label=serializer.validated_data.get('label'))
if not tags.count():
serializer.save()
job.used = True
job.save()
return Response(data=serializer.data,
status=HTTP_201_CREATED)
def delete(self, request, *args, **kwargs):
serializer = SemanticTagSerializer(data=request.query_params)
if not serializer.is_valid():
return Response(data=serializer.errors,
status=HTTP_400_BAD_REQUEST)
job = TaggerJob.objects.get(uuid=serializer.validated_data['job'].uuid)
active_user = serializer.validated_data.get('user', None)
if active_user == request.user or job.creator == request.user:
job.update_user_last_tagged(active_user, serializer.validated_data.get('scanmodel').sid)
else:
return Response(data="Requester is not admin or active user",
status=HTTP_403_FORBIDDEN)
tags = SemanticTag.objects.filter(
job=job,
user=active_user,
scanmodel=serializer.validated_data.get('scanmodel'),
label=serializer.validated_data.get('label'))
if tags.count():
tags.delete()
data = serializer.data
data['deleted'] = True
return Response(data=data,
status=HTTP_202_ACCEPTED)
class TaggerLabelView(ListCreateAPIView):
queryset = Label.objects.all()
serializer_class = LabelSerializer
permission_classes = (IsAuthenticated,)
def post(self, request, *args, **kwargs):
if not is_tagger_admin(request.user):
raise PermissionDenied
serializer = LabelSerializer(data=request.data)
if not serializer.is_valid():
return Response(data=serializer.errors,
status=HTTP_400_BAD_REQUEST)
serializer.save()
return Response(data=serializer.data,
status=HTTP_201_CREATED)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment