192 lines
5.7 KiB
Python
192 lines
5.7 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}:{instance.type}:{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, 'type': int(section_type), 'start': start, 'end': end})
|
|
|
|
class DocumentSerializer(serializers.ModelSerializer):
|
|
|
|
upload = serializers.URLField()
|
|
sections = SectionSerializer(many=True)
|
|
#doctype = serializers.CharField(source='get_doctype_display')
|
|
|
|
#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)
|
|
if data['upload'][0] == '/':
|
|
data['upload'] = 'http://localhost:8000' + (data['upload'])
|
|
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
|
|
|
|
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)
|
|
|
|
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']) |