2023-03-01 12:41:42 +11:00

191 lines
5.6 KiB
Python

"""
Views relating to importing and exporting collection items
"""
"""
from interface.views import EnsembleMixin
from library.views import WorkMixin
from django.views.generic import View
from django.http import JsonResponse
from djantic import ModelSchema
from library.models import Work, Document, Section
class DocumentSchema(ModelSchema):
class Config:
model = Document
class WorkSchema(ModelSchema):
docs: DocumentSchema
class Config:
model = Work
exclude = ['licence']
class WorkExportView(EnsembleMixin, WorkMixin, View):
def get(self, request, *args, **kwargs):
obj = self.get_queryset().get(pk=kwargs['pk'])
schema = WorkSchema.from_orm(obj)
return JsonResponse(schema.dict())
"""
from interface.views import AuthorizedResourceMixin
from rest_framework import routers, serializers, viewsets
from library.models import Collection, Work, Document, Section, WorkMeta
import requests
from io import BytesIO
import tempfile
import shutil
from django.db import transaction
from django.core.files.uploadedfile import TemporaryUploadedFile
class WorkMetaSerializer(serializers.ModelSerializer):
class Meta:
model = WorkMeta
exclude = ['id', 'work']
def to_representation(self, instance):
return f"{instance.name}:{instance.value}"
def to_internal_value(self, data):
name, _, value = data.partition(':')
return super().to_internal_value({'name': name, 'value': value})
class SectionSerializer(serializers.ModelSerializer):
class Meta:
model = Section
exclude = ['id', 'doc']
def to_representation(self, instance):
start = instance.start or 0
end = instance.end or 0
return f"{instance.tag}:{start}:{end}"
def to_internal_value(self, data):
tag, section_type, start, end = data.split(":")
try:
start = int(start)
except:
start = 0
try:
end = int(end)
except:
end = 0
return super().to_internal_value({'tag': tag, 'start': start, 'end': end})
class DocumentSerializer(serializers.ModelSerializer):
upload = serializers.URLField()
sections = SectionSerializer(many=True)
#def to_internal_value(self, data):
# r = requests.get(data['upload'], stream=True)
# with tempfile.NamedTemporaryFile('wb') as f:
# shutil.copyfileobj(r.raw, f)
# data['upload'] = f.name
# print(repr(data))
# return super().to_internal_value(data)
def to_representation(self, instance):
data = super().to_representation(instance)
data['upload'] = instance.upload.url
return data
def create(self, validated_data):
print("CREATE", validated_data)
return super().create(validated_data)
def validate(self, data):
print("VALIDATE", data)
return super().validate(data)
def validate_upload(self, value):
print("VALIDATE", value)
return value
class Meta:
model = Document
exclude = ["id", "work", "version", "created"]
# Serializers define the API representation.
class WorkSerializer(serializers.ModelSerializer):
docs = DocumentSerializer(many=True)
meta_info = WorkMetaSerializer(many=True)
class Meta:
model = Work
exclude = ['id', 'collection', 'projects', 'parent']
def create(self, validated):
with transaction.atomic():
docs = validated.pop('docs', [])
meta = validated.pop('meta_info', [])
work = Work.objects.create(**validated)
for d in docs:
sections = d.pop('sections', [])
r = requests.get(d['upload'], stream=True)
f = TemporaryUploadedFile(d['upload'], r.headers['content-type'], r.headers['content-length'], r.encoding)
shutil.copyfileobj(r.raw, f.file)
r.close()
d['upload'] = f
doc = Document.objects.create(work_id=work.pk, **d)
for s in sections:
Section.objects.create(doc_id=doc.pk, **s)
for m in meta:
WorkMeta.objects.create(work_id=work.pk, **m)
return work
class CollectionSerializer(serializers.Serializer):
works = WorkSerializer(many=True)
def create(self, validated):
s = WorkSerializer()
print(validated)
collection = validated['collection_id']
with transaction.atomic():
for work in validated['works']:
work['collection_id'] = collection
s.create(work)
return Collection.objects.get(pk=collection)
from rest_framework import generics
class CollectionExportView(AuthorizedResourceMixin, generics.RetrieveAPIView):
serializer_class = CollectionSerializer
lookup_url_kwarg = 'collection'
def get_queryset(self):
return Collection.objects.filter(administrators=self.request.user)
class WorkExportView(AuthorizedResourceMixin, generics.RetrieveAPIView):
serializer_class = WorkSerializer
def get_queryset(self):
return Work.objects.filter(collection__administrators=self.request.user, collection=self.kwargs['collection'])
class WorkImportView(AuthorizedResourceMixin, generics.CreateAPIView):
serializer_class = WorkSerializer
def perform_create(self, serializer):
serializer.save(collection_id=self.kwargs['pk'])
class CollectionImportView(AuthorizedResourceMixin, generics.CreateAPIView):
serializer_class = CollectionSerializer
def perform_create(self, serializer):
serializer.save(collection_id=self.kwargs['pk'])