|
@ -1,8 +1,11 @@ |
|
|
from collections import Counter |
|
|
from collections import Counter |
|
|
|
|
|
|
|
|
from django.shortcuts import get_object_or_404 |
|
|
|
|
|
|
|
|
from django.conf import settings |
|
|
|
|
|
from django.shortcuts import get_object_or_404, redirect |
|
|
from django_filters.rest_framework import DjangoFilterBackend |
|
|
from django_filters.rest_framework import DjangoFilterBackend |
|
|
from django.db.models import Count |
|
|
from django.db.models import Count |
|
|
|
|
|
from libcloud.base import DriverType, get_driver |
|
|
|
|
|
from libcloud.storage.types import ContainerDoesNotExistError, ObjectDoesNotExistError |
|
|
from rest_framework import generics, filters, status |
|
|
from rest_framework import generics, filters, status |
|
|
from rest_framework.exceptions import ParseError, ValidationError |
|
|
from rest_framework.exceptions import ParseError, ValidationError |
|
|
from rest_framework.permissions import IsAuthenticated, IsAdminUser |
|
|
from rest_framework.permissions import IsAuthenticated, IsAdminUser |
|
@ -16,7 +19,7 @@ from .models import Project, Label, Document |
|
|
from .permissions import IsAdminUserAndWriteOnly, IsProjectUser, IsOwnAnnotation |
|
|
from .permissions import IsAdminUserAndWriteOnly, IsProjectUser, IsOwnAnnotation |
|
|
from .serializers import ProjectSerializer, LabelSerializer, DocumentSerializer, UserSerializer |
|
|
from .serializers import ProjectSerializer, LabelSerializer, DocumentSerializer, UserSerializer |
|
|
from .serializers import ProjectPolymorphicSerializer |
|
|
from .serializers import ProjectPolymorphicSerializer |
|
|
from .utils import CSVParser, JSONParser, PlainTextParser, CoNLLParser |
|
|
|
|
|
|
|
|
from .utils import CSVParser, JSONParser, PlainTextParser, CoNLLParser, iterable_to_io |
|
|
from .utils import JSONLRenderer |
|
|
from .utils import JSONLRenderer |
|
|
from .utils import JSONPainter, CSVPainter |
|
|
from .utils import JSONPainter, CSVPainter |
|
|
|
|
|
|
|
@ -180,14 +183,26 @@ class TextUploadAPI(APIView): |
|
|
def post(self, request, *args, **kwargs): |
|
|
def post(self, request, *args, **kwargs): |
|
|
if 'file' not in request.data: |
|
|
if 'file' not in request.data: |
|
|
raise ParseError('Empty content') |
|
|
raise ParseError('Empty content') |
|
|
project = get_object_or_404(Project, pk=self.kwargs['project_id']) |
|
|
|
|
|
parser = self.select_parser(request.data['format']) |
|
|
|
|
|
data = parser.parse(request.data['file']) |
|
|
|
|
|
storage = project.get_storage(data) |
|
|
|
|
|
storage.save(self.request.user) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.save_file( |
|
|
|
|
|
user=request.user, |
|
|
|
|
|
file=request.data['file'], |
|
|
|
|
|
file_format=request.data['format'], |
|
|
|
|
|
project_id=kwargs['project_id'], |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
return Response(status=status.HTTP_201_CREATED) |
|
|
return Response(status=status.HTTP_201_CREATED) |
|
|
|
|
|
|
|
|
def select_parser(self, format): |
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
|
def save_file(cls, user, file, file_format, project_id): |
|
|
|
|
|
project = get_object_or_404(Project, pk=project_id) |
|
|
|
|
|
parser = cls.select_parser(file_format) |
|
|
|
|
|
data = parser.parse(file) |
|
|
|
|
|
storage = project.get_storage(data) |
|
|
|
|
|
storage.save(user) |
|
|
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
|
def select_parser(cls, format): |
|
|
if format == 'plain': |
|
|
if format == 'plain': |
|
|
return PlainTextParser() |
|
|
return PlainTextParser() |
|
|
elif format == 'csv': |
|
|
elif format == 'csv': |
|
@ -200,6 +215,50 @@ class TextUploadAPI(APIView): |
|
|
raise ValidationError('format {} is invalid.'.format(format)) |
|
|
raise ValidationError('format {} is invalid.'.format(format)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CloudUploadAPI(APIView): |
|
|
|
|
|
permission_classes = TextUploadAPI.permission_classes |
|
|
|
|
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs): |
|
|
|
|
|
try: |
|
|
|
|
|
project_id = request.query_params['project_id'] |
|
|
|
|
|
file_format = request.query_params['upload_format'] |
|
|
|
|
|
cloud_container = request.query_params['container'] |
|
|
|
|
|
cloud_object = request.query_params['object'] |
|
|
|
|
|
except KeyError as ex: |
|
|
|
|
|
raise ValidationError('query parameter {} is missing'.format(ex)) |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
cloud_file = self.get_cloud_object_as_io(cloud_container, cloud_object) |
|
|
|
|
|
except ContainerDoesNotExistError: |
|
|
|
|
|
raise ValidationError('cloud container {} does not exist'.format(cloud_container)) |
|
|
|
|
|
except ObjectDoesNotExistError: |
|
|
|
|
|
raise ValidationError('cloud object {} does not exist'.format(cloud_object)) |
|
|
|
|
|
|
|
|
|
|
|
TextUploadAPI.save_file( |
|
|
|
|
|
user=request.user, |
|
|
|
|
|
file=cloud_file, |
|
|
|
|
|
file_format=file_format, |
|
|
|
|
|
project_id=project_id, |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
next_url = request.query_params.get('next') |
|
|
|
|
|
return redirect(next_url) if next_url else Response(status=status.HTTP_201_CREATED) |
|
|
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
|
def get_cloud_object_as_io(cls, container_name, object_name): |
|
|
|
|
|
provider = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_PROVIDER.lower() |
|
|
|
|
|
account = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_ACCOUNT |
|
|
|
|
|
key = settings.CLOUD_BROWSER_APACHE_LIBCLOUD_SECRET_KEY |
|
|
|
|
|
|
|
|
|
|
|
driver = get_driver(DriverType.STORAGE, provider) |
|
|
|
|
|
client = driver(account, key) |
|
|
|
|
|
|
|
|
|
|
|
cloud_container = client.get_container(container_name) |
|
|
|
|
|
cloud_object = cloud_container.get_object(object_name) |
|
|
|
|
|
|
|
|
|
|
|
return iterable_to_io(cloud_object.as_stream()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TextDownloadAPI(APIView): |
|
|
class TextDownloadAPI(APIView): |
|
|
permission_classes = (IsAuthenticated, IsProjectUser, IsAdminUser) |
|
|
permission_classes = (IsAuthenticated, IsProjectUser, IsAdminUser) |
|
|
renderer_classes = (CSVRenderer, JSONLRenderer) |
|
|
renderer_classes = (CSVRenderer, JSONLRenderer) |
|
|