From a892b0bc41d47188e4c691b512dab7de1666e8b0 Mon Sep 17 00:00:00 2001 From: Tris Forster Date: Thu, 2 Mar 2023 07:09:38 +1100 Subject: [PATCH] Got api work import working --- app/library/tests.py | 29 +++++++++++++++++++++++------ app/library/views/api.py | 12 ++++++++---- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/library/tests.py b/app/library/tests.py index 3009f39..b6c6a1a 100644 --- a/app/library/tests.py +++ b/app/library/tests.py @@ -1,10 +1,12 @@ from interface.tests import AccessTestCase -from django.contrib.auth.models import User -from interface.models import Ensemble, Project +from byostorage.user import UserStorage from . import models from .views.api import WorkSerializer +import tempfile +import json + class LibraryTestCase(AccessTestCase): USERS = ( @@ -32,6 +34,7 @@ class LibraryTestCase(AccessTestCase): WORKS = ( {'name': 'Baby on Board', 'collection': 'ned', 'docs': [{'upload': 'local:baby_on_board.pdf'}]}, + {'name': 'Star Spangled Banner', 'collection': 'sel'}, ) PROTECTED_URLS = ( @@ -45,8 +48,8 @@ class LibraryTestCase(AccessTestCase): '/collections/2/docs/1/annotate', # Need to add storage before we can test these - #'/api/collections/2', - #'/api/collections/2/works/1', + '/api/collections/2', + '/api/collections/2/works/1', '/admin/library/collection/', '/admin/library/document/', @@ -60,10 +63,13 @@ class LibraryTestCase(AccessTestCase): def setUpTestData(cls): super().setUpTestData() + cls.temp_dir = tempfile.TemporaryDirectory() + cls.storage = UserStorage.objects.create(name='local', storage='django.core.files.storage.FileSystemStorage', + settings_data=json.dumps({'location': cls.temp_dir.name, 'base_url': 'file://' + cls.temp_dir.name})) cls.collections = {} for details in cls.COLLECTIONS: admins = details.pop('admins', []) - obj = models.Collection.objects.create(**details) + obj = models.Collection.objects.create(storage=cls.storage, **details) for admin in admins: obj.administrators.add(cls.users[admin]) cls.collections[details['prefix']] = obj @@ -83,6 +89,12 @@ class LibraryTestCase(AccessTestCase): cls.works[details['name']] = obj + def setUp(self): + pass + + @classmethod + def tearDownClass(cls): + cls.temp_dir.cleanup() def test_integration(self): @@ -128,7 +140,12 @@ class LibraryTestCase(AccessTestCase): '/collections/2': False, '/collections/2/works/1': False, }) - + + def test_export_and_import(self): + self.login('admin', 'secret') + data = self.client.get('/api/collections/1/works/2', HTTP_ACCEPT="application/json").json() + response = self.client.post('/api/collections/2/import', data, "application/json") + self.assertEqual(response.status_code, 201) def test_movement_from_large_work(self): ''' diff --git a/app/library/views/api.py b/app/library/views/api.py index 1358d5a..fa1b2b5 100644 --- a/app/library/views/api.py +++ b/app/library/views/api.py @@ -41,8 +41,9 @@ from library.models import Collection, Work, Document, Section, WorkMeta import requests from io import BytesIO -import tempfile +import urllib import shutil +import os.path from django.db import transaction from django.core.files.uploadedfile import TemporaryUploadedFile @@ -70,7 +71,7 @@ class SectionSerializer(serializers.ModelSerializer): return f"{instance.tag}:{start}:{end}" def to_internal_value(self, data): - tag, section_type, start, end = data.split(":") + tag, start, end = data.split(":") try: start = int(start) except: @@ -134,8 +135,11 @@ class WorkSerializer(serializers.ModelSerializer): for d in docs: sections = d.pop('sections', []) + url = urllib.parse.urlparse(d['upload']) + filename = os.path.basename(url.path) + r = requests.get(d['upload'], stream=True) - f = TemporaryUploadedFile(d['upload'], r.headers['content-type'], r.headers['content-length'], r.encoding) + f = TemporaryUploadedFile(filename, r.headers['content-type'], r.headers['content-length'], r.encoding) shutil.copyfileobj(r.raw, f.file) r.close() d['upload'] = f @@ -186,7 +190,7 @@ class WorkImportView(AuthorizedResourceMixin, generics.CreateAPIView): serializer_class = WorkSerializer def perform_create(self, serializer): - serializer.save(collection_id=self.kwargs['pk']) + serializer.save(collection_id=self.kwargs['collection']) class CollectionImportView(AuthorizedResourceMixin, generics.CreateAPIView): serializer_class = CollectionSerializer