mirror of
https://github.com/leaders-of-digital-9-task/backend.git
synced 2024-11-21 17:06:33 +03:00
added archive and list of files upload
This commit is contained in:
parent
e3aa26a7df
commit
a40bc6ad5b
|
@ -5,6 +5,7 @@ from dicom.api.views import (
|
|||
RetrieveUpdateDeleteCircleApi,
|
||||
RetrieveUpdateDeleteDicomApi,
|
||||
RetrieveUpdateDeletePolygonApi,
|
||||
SmartFileUploadApi,
|
||||
)
|
||||
from django.urls import include, path
|
||||
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
|
||||
|
@ -26,6 +27,7 @@ urlpatterns = [
|
|||
include(
|
||||
[
|
||||
path("", ListCreateDicomApi.as_view(), name="list_create_dicom"),
|
||||
path("upload", SmartFileUploadApi.as_view(), name="upload_dicom_api"),
|
||||
path(
|
||||
"<str:slug>",
|
||||
RetrieveUpdateDeleteDicomApi.as_view(),
|
||||
|
|
|
@ -142,6 +142,10 @@ MIDDLEWARE = [
|
|||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
FILE_UPLOAD_HANDLERS = [
|
||||
"django.core.files.uploadhandler.TemporaryFileUploadHandler",
|
||||
]
|
||||
|
||||
# STATIC
|
||||
# ------------------------------------------------------------------------------
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#static-root
|
||||
|
|
|
@ -112,3 +112,7 @@ class CircleSerializer(serializers.ModelSerializer):
|
|||
obj.radius = validated_data["radius"]
|
||||
obj.save()
|
||||
return obj
|
||||
|
||||
|
||||
class SmartFileUploadSerializer(serializers.ModelSerializer):
|
||||
file = serializers.FileField()
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
from drf_spectacular.utils import extend_schema
|
||||
from rest_framework import generics
|
||||
from rest_framework import generics, status
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.parsers import FormParser, MultiPartParser
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from ..models import Circle, Dicom, Polygon
|
||||
from ..services import process_files
|
||||
from .serializers import (
|
||||
CircleSerializer,
|
||||
DicomSerializer,
|
||||
|
@ -19,18 +23,6 @@ class ListCreateDicomApi(generics.ListCreateAPIView):
|
|||
def get_queryset(self):
|
||||
return Dicom.objects.filter(user=self.request.user)
|
||||
|
||||
@extend_schema(
|
||||
operation_id="upload_file",
|
||||
request={
|
||||
"multipart/form-data": {
|
||||
"type": "object",
|
||||
"properties": {"file": {"type": "string", "format": "binary"}},
|
||||
}
|
||||
},
|
||||
)
|
||||
def post(self, request, *args, **kwargs):
|
||||
return self.create(request, *args, **kwargs)
|
||||
|
||||
|
||||
class RetrieveUpdateDeleteDicomApi(generics.RetrieveUpdateDestroyAPIView):
|
||||
def get_queryset(self):
|
||||
|
@ -80,3 +72,16 @@ class RetrieveUpdateDeleteCircleApi(generics.RetrieveUpdateDestroyAPIView):
|
|||
@extend_schema(description="Note: coordinated are dropped on update")
|
||||
def put(self, request, *args, **kwargs):
|
||||
return self.update(request, *args, **kwargs)
|
||||
|
||||
|
||||
class SmartFileUploadApi(APIView):
|
||||
parser_classes = [MultiPartParser, FormParser]
|
||||
|
||||
def post(self, request):
|
||||
if "file" not in request.data:
|
||||
raise ValidationError("no files")
|
||||
d_list = process_files(request.FILES.getlist("file"), request.user)
|
||||
return Response(
|
||||
DicomSerializer(d_list.files.all(), many=True).data,
|
||||
status=status.HTTP_201_CREATED,
|
||||
)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# flake8: noqa
|
||||
from .base import Dicom
|
||||
from .base import Dicom, ListOfDicom
|
||||
from .blocks import BaseShape, Circle, Coordinate, Polygon
|
||||
|
|
|
@ -6,6 +6,10 @@ from utils.files import media_upload_path
|
|||
User = get_user_model()
|
||||
|
||||
|
||||
class ListOfDicom(models.Model):
|
||||
pass
|
||||
|
||||
|
||||
class Dicom(models.Model):
|
||||
class PathologyType(models.IntegerChoices):
|
||||
no_pathology = 0, "Без патологий"
|
||||
|
@ -17,7 +21,10 @@ class Dicom(models.Model):
|
|||
file = models.FileField(upload_to=media_upload_path)
|
||||
uploaded = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
pathology_type = models.IntegerField(choices=PathologyType.choices)
|
||||
pathology_type = models.IntegerField(choices=PathologyType.choices, default=0)
|
||||
list = models.ForeignKey(
|
||||
ListOfDicom, related_name="files", null=True, on_delete=models.SET_NULL
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.file.name
|
||||
|
|
|
@ -19,8 +19,8 @@ class BaseShape(PolymorphicModel):
|
|||
|
||||
|
||||
class Coordinate(models.Model):
|
||||
x = models.IntegerField()
|
||||
y = models.IntegerField()
|
||||
x = models.FloatField()
|
||||
y = models.FloatField()
|
||||
|
||||
shape = models.ForeignKey(
|
||||
to=BaseShape,
|
||||
|
|
39
image_markuper/dicom/services.py
Normal file
39
image_markuper/dicom/services.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
import magic
|
||||
from dicom.models import Dicom, ListOfDicom
|
||||
from django.core.files import File
|
||||
from django.core.files.uploadedfile import InMemoryUploadedFile, TemporaryUploadedFile
|
||||
from utils.generators import generate_charset
|
||||
|
||||
|
||||
def process_files(files: list[TemporaryUploadedFile | InMemoryUploadedFile], user):
|
||||
d_list = ListOfDicom.objects.create()
|
||||
for file in files:
|
||||
content_type = magic.from_file(file.temporary_file_path())
|
||||
if content_type == "DICOM medical imaging data":
|
||||
Dicom.objects.create(file=file, list=d_list, user=user)
|
||||
elif "Zip" in content_type:
|
||||
dit_path = f"/tmp/{generate_charset(10)}"
|
||||
os.mkdir(dit_path)
|
||||
with zipfile.ZipFile(file.temporary_file_path(), "r") as zip_ref:
|
||||
zip_ref.extractall(dit_path)
|
||||
files = glob.glob(dit_path + "/**/*", recursive=True)
|
||||
|
||||
for file_in_d in files:
|
||||
if not os.path.isdir(file_in_d):
|
||||
content_type = magic.from_file(file_in_d)
|
||||
if content_type == "DICOM medical imaging data":
|
||||
path = Path(file_in_d)
|
||||
with path.open(mode="rb") as f:
|
||||
Dicom.objects.create(
|
||||
file=File(f, name=file_in_d.split("/")[-1]),
|
||||
list=d_list,
|
||||
user=user,
|
||||
)
|
||||
shutil.rmtree(dit_path)
|
||||
return d_list
|
|
@ -1,4 +1,5 @@
|
|||
pytz==2022.5 # https://github.com/stub42/pytz
|
||||
python-magic==0.4.27
|
||||
python-slugify==6.1.2 # https://github.com/un33k/python-slugify
|
||||
Pillow==9.2.0 # https://github.com/python-pillow/Pillow
|
||||
argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
|
||||
|
|
Loading…
Reference in New Issue
Block a user