""" 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 library.views import WorkMixin from interface.views import EnsembleMixin from rest_framework import routers, serializers, viewsets from library.models import Collection, Work, Document, Section import requests from io import BytesIO import tempfile import shutil from django.db import transaction from django.core.files.uploadedfile import TemporaryUploadedFile 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) class Meta: model = Work exclude = ['id', 'collection', 'projects', 'parent'] def create(self, validated): with transaction.atomic(): docs = validated.pop('docs', []) 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) return work class CollectionSerializer(serializers.Serializer): works = WorkSerializer(many=True) from rest_framework import generics class CollectionExportView(generics.RetrieveAPIView): serializer_class = CollectionSerializer def get_queryset(self): return Collection.objects.filter(administrators=self.request.user) class WorkExportView(generics.RetrieveAPIView): serializer_class = WorkSerializer def get_queryset(self): return Work.objects.filter(collection__administrators=self.request.user) class WorkImportView(generics.CreateAPIView): serializer_class = WorkSerializer def perform_create(self, serializer): serializer.save(collection_id=self.kwargs['pk'])