Esempio n. 1
0
    def setUp(self):
        # Set up an initial file upload
        self.upload_id = _get_file_id()
        self.upload_id2 = _get_file_id()
        self.file_id = _get_file_id()
        self.file_content = ('This is some test file data for an '
                             'uploaded file.')
        self.fn = 'my_test_file.txt'
        self.test_target_dirname = 'test_storage/'
        self.test_target_filename = '/test_storage/testfile.txt'
        self.test_target_filename2 = '/test_storage/testfile2.txt'
        uploaded_file = SimpleUploadedFile(self.fn,
                                           str.encode(self.file_content))
        tu = TemporaryUpload(upload_id=self.upload_id,
                             file_id=self.file_id,
                             file=uploaded_file,
                             upload_name=self.fn,
                             upload_type=TemporaryUpload.FILE_DATA)
        tu.save()

        tu2 = TemporaryUpload(upload_id=self.upload_id2,
                              file_id=self.file_id,
                              file=uploaded_file,
                              upload_name=self.fn,
                              upload_type=TemporaryUpload.FILE_DATA)
        tu2.save()
Esempio n. 2
0
    def setUp(self):
        global store_upload
        # Set storage backend to sftp storage
        local_settings.STORAGES_BACKEND = \
            'storages.backends.sftpstorage.SFTPStorage'

        # Setting up a mock for the storage backend based on examples at
        # https://docs.python.org/3.7/library/unittest.mock-examples.html# \
        # applying-the-same-patch-to-every-test-method
        patcher = patch('storages.backends.sftpstorage.SFTPStorage')
        patcher.start()
        self.addCleanup(patcher.stop)

        # Mock the temporary storage object so that we're not unnecessarily
        # saving files to the local file system.
        patcher2 = patch('django.core.files.storage.FileSystemStorage')
        patcher2.start()
        self.addCleanup(patcher2.stop)
        # Reinitialse stored upload after we changed the STORAGES_BACKEND
        # class name above. This ensures that we're looking at the mocked
        # backend class.
        import django_drf_filepond.api
        self.api = django_drf_filepond.api
        django_drf_filepond.api.storage_backend_initialised = False
        django_drf_filepond.api._init_storage_backend()
        self.mock_storage_backend = django_drf_filepond.api.storage_backend
        store_upload = django_drf_filepond.api.store_upload

        # Check that we're using a mocked storage backend
        self.assertTrue(
            isinstance(django_drf_filepond.api.storage_backend, MagicMock),
            ('The created storage backend should be mocked but it is not of '
             'type unittest.mock.MagicMock...'))

        # Set up an initial file upload
        self.upload_id = _get_file_id()
        self.upload_id2 = _get_file_id()
        self.file_id = _get_file_id()
        self.file_content = ('This is some test file data for an '
                             'uploaded file.')
        self.fn = 'my_test_file.txt'
        self.test_target_filename = '/test_storage/testfile.txt'
        self.test_target_filename2 = '/test_storage/testfile2.txt'
        uploaded_file = MagicMock(spec=SimpleUploadedFile)
        uploaded_file.name = self.fn
        tu = TemporaryUpload(upload_id=self.upload_id,
                             file_id=self.file_id,
                             file=uploaded_file,
                             upload_name=self.fn,
                             upload_type=TemporaryUpload.FILE_DATA)
        tu.save()

        tu2 = TemporaryUpload(upload_id=self.upload_id2,
                              file_id=self.file_id,
                              file=uploaded_file,
                              upload_name=self.fn,
                              upload_type=TemporaryUpload.FILE_DATA)
        tu2.save()
 def setUp(self):
     self.upload_id = _get_file_id()
     self.file_id = _get_file_id()
     self.file_content = ('This is some test file data for an '
                          'uploaded file.')
     self.fn = 'my_test_file.txt'
     uploaded_file = SimpleUploadedFile(self.fn, 
                                        str.encode(self.file_content))
     tu = TemporaryUpload(upload_id=self.upload_id,
                          file_id=self.file_id,
                          file=uploaded_file, upload_name=self.fn, 
                          upload_type=TemporaryUpload.FILE_DATA)
     tu.save()
Esempio n. 4
0
    def handle_upload(self, request, upload_id, file_id):
        # Since the upload_id and file_id are being provided here as
        # parameters, we check that they are valid. This should be done by
        # the DB and an error would be generated in the tu.save() call below
        # however SQLite doesn't handle field length validation so this won't
        # be picked up when using SQLite.
        if ((not self._file_id_valid(file_id))
                or (not self._upload_id_valid(upload_id))):
            return Response('Invalid ID for handling upload.',
                            content_type='text/plain',
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        file_obj = self._get_file_obj(request)

        # The type of parsed data should be a descendant of an UploadedFile
        # type.
        if not isinstance(file_obj, UploadedFile):
            raise ParseError('Invalid data type has been parsed.')

        # Save original file name and set name of saved file to the unique ID
        upload_filename = file_obj.name
        file_obj.name = file_id

        # Before we attempt to save the file, make sure that the upload
        # directory we're going to save to exists.
        # *** It's not necessary to explicitly create the directory since
        # *** the FileSystemStorage object creates the directory on save
        # if not os.path.exists(storage.location):
        #    LOG.debug('Filepond app: Creating file upload directory '
        #             '<%s>...' % storage.location)
        #    os.makedirs(storage.location, mode=0o700)

        LOG.debug('About to store uploaded temp file with filename: %s' %
                  (upload_filename))

        # We now need to create the temporary upload object and store the
        # file and metadata.
        tu = TemporaryUpload(upload_id=upload_id,
                             file_id=file_id,
                             file=file_obj,
                             upload_name=upload_filename,
                             upload_type=TemporaryUpload.FILE_DATA,
                             uploaded_by=_get_user(request))
        tu.save()

        response = Response(upload_id,
                            status=status.HTTP_200_OK,
                            content_type='text/plain')

        return response
Esempio n. 5
0
    def _store_upload(self, tuc):
        if not tuc.upload_complete:
            LOG.error('Attempt to store an incomplete upload with ID <%s>' %
                      (tuc.upload_id))
            raise ValueError('Attempt to store an incomplete upload with ID '
                             '<%s>' % (tuc.upload_id))

        # Load each of the file parts into a BytesIO object and store them
        # via a TemporaryUpload object.
        chunk_dir = os.path.join(storage.base_location, tuc.upload_dir)
        file_data = BytesIO()
        for i in range(1, tuc.last_chunk + 1):
            chunk_file = os.path.join(chunk_dir, '%s_%s' % (tuc.file_id, i))
            if not os.path.exists(chunk_file):
                raise FileNotFoundError('Chunk file not found for chunk <%s>' %
                                        (i))

            with open(chunk_file, 'rb') as cf:
                file_data.write(cf.read())

        # Prepare an InMemoryUploadedFile object so that the data can be
        # successfully saved via the FileField in the TemporaryUpload object
        memfile = InMemoryUploadedFile(file_data, None, tuc.file_id,
                                       'application/octet-stream',
                                       tuc.total_size, None)
        tu = TemporaryUpload(upload_id=tuc.upload_id,
                             file_id=tuc.file_id,
                             file=memfile,
                             upload_name=tuc.upload_name,
                             upload_type=TemporaryUpload.FILE_DATA,
                             uploaded_by=tuc.uploaded_by)
        tu.save()

        # Check that the final file is stored and of the correct size
        stored_file_path = os.path.join(chunk_dir, tuc.file_id)
        if ((not os.path.exists(stored_file_path))
                or (not os.path.getsize(stored_file_path) == tuc.total_size)):
            raise ValueError('Stored file size wrong or file not found.')

        LOG.debug('Full file built from chunks and saved. Deleting chunks '
                  'and TemporaryUploadChunked object.')

        for i in range(1, tuc.last_chunk + 1):
            chunk_file = os.path.join(chunk_dir, '%s_%s' % (tuc.file_id, i))
            os.remove(chunk_file)
        tuc.delete()
Esempio n. 6
0
    def setUp(self):
        # Set up an initial file upload
        self.upload_id = _get_file_id()
        self.file_id = _get_file_id()
        self.file_content = ('This is some test file data for an '
                             'uploaded file.')
        self.fn = 'my_test_file.txt'
        self.test_filename = 'sdf5dua32defh754dhsrr2'
        uploaded_file = SimpleUploadedFile(self.fn,
                                           str.encode(self.file_content))
        tu = TemporaryUpload(upload_id=self.upload_id,
                             file_id=self.file_id,
                             file=uploaded_file,
                             upload_name=self.fn,
                             upload_type=TemporaryUpload.FILE_DATA)
        tu.save()

        # Now set up a stored version of this upload
        su = StoredUpload(upload_id=self.upload_id,
                          file_path=('%s' % (self.fn)),
                          uploaded=tu.uploaded)
        su.save()
Esempio n. 7
0
    def head(self, request):
        LOG.debug('Filepond API: Fetch view HEAD called...')
        result = self._process_request(request)
        if isinstance(result, tuple):
            buf, file_id, upload_file_name, content_type = result
        elif isinstance(result, Response):
            return result
        else:
            raise ValueError('process_request result is of an unexpected type')

        file_size = buf.seek(0, os.SEEK_END)
        buf.seek(0)

        # The addressing of filepond issue #154
        # (https://github.com/pqina/filepond/issues/154) means that fetch
        # can now store a file downloaded from a remote URL and return file
        # metadata in the header if a HEAD request is received. If we get a
        # GET request then the standard approach of proxying the file back
        # to the client is used.
        upload_id = _get_file_id()
        memfile = InMemoryUploadedFile(buf, None, file_id, content_type,
                                       file_size, None)
        tu = TemporaryUpload(upload_id=upload_id,
                             file_id=file_id,
                             file=memfile,
                             upload_name=upload_file_name,
                             upload_type=TemporaryUpload.URL,
                             uploaded_by=_get_user(request))
        tu.save()

        response = Response(status=status.HTTP_200_OK)
        response['Content-Type'] = content_type
        response['Content-Length'] = file_size
        response['X-Content-Transfer-Id'] = upload_id
        response['Content-Disposition'] = ('inline; filename=%s' %
                                           upload_file_name)
        return response
Esempio n. 8
0
    def post(self, request):
        LOG.debug('Filepond API: Process view POST called...')

        # Enforce that the upload location must be a sub-directory of
        # the project base directory
        # TODO: Check whether this is necessary - maybe add a security
        # parameter that can be disabled to turn off this check if the
        # developer wishes?
        if ((not hasattr(local_settings, 'UPLOAD_TMP')) or
            (not (storage.location).startswith(local_settings.BASE_DIR))):
            return Response(
                'The file upload path settings are not '
                'configured correctly.',
                status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # Check that we've received a file and then generate a unique ID
        # for it. Also generate a unique UD for the temp upload dir
        file_id = _get_file_id()
        upload_id = _get_file_id()

        # By default the upload element name is expected to be "filepond"
        # As raised in issue #4, there are cases where there may be more
        # than one filepond instance on a page, or the developer has opted
        # not to use the name "filepond" for the filepond instance.
        # Using the example from #4, this provides support these cases.
        upload_field_name = 'filepond'
        if 'fp_upload_field' in request.data:
            upload_field_name = request.data['fp_upload_field']

        if upload_field_name not in request.data:
            raise ParseError("Invalid request data has been provided.")

        file_obj = request.data[upload_field_name]

        # Save original file name and set name of saved file to the unique ID
        upload_filename = file_obj.name
        file_obj.name = file_id

        # The type of parsed data should be a descendant of an UploadedFile
        # type.
        if not isinstance(file_obj, UploadedFile):
            raise ParseError('Invalid data type has been parsed.')

        # Before we attempt to save the file, make sure that the upload
        # directory we're going to save to exists.
        # *** It's not necessary to explicitly create the directory since
        # *** the FileSystemStorage object creates the directory on save
        # if not os.path.exists(storage.location):
        #    LOG.debug('Filepond app: Creating file upload directory '
        #             '<%s>...' % storage.location)
        #    os.makedirs(storage.location, mode=0o700)

        # We now need to create the temporary upload object and store the
        # file and metadata.
        tu = TemporaryUpload(upload_id=upload_id,
                             file_id=file_id,
                             file=file_obj,
                             upload_name=upload_filename,
                             upload_type=TemporaryUpload.FILE_DATA)
        tu.save()

        response = Response(upload_id,
                            status=status.HTTP_200_OK,
                            content_type='text/plain')
        return response