Exemplo n.º 1
0
    def retrieve(self, request, pk=None):
        # get database adapter
        adapter = DatabaseAdapter()

        # get the schema_name and the table_name from the settings
        schema_name = settings.ARCHIVE_SCHEMA
        table_name = settings.ARCHIVE_TABLE

        # get collecions for this user
        collections = [
            collection.name for collection in
            Collection.objects.filter_by_access_level(request.user)
        ]

        # fetch the path for this file from the database
        row = adapter.fetch_row(schema_name,
                                table_name, ['path'],
                                filters={
                                    'id': pk,
                                    'collection': collections
                                })

        if row:
            if request.GET.get('download', True):
                # create a stats record for this download
                Record.objects.create(time=now(),
                                      resource_type='ARCHIVE_DOWNLOAD',
                                      resource=row[0],
                                      client_ip=get_client_ip(request),
                                      user=request.user if
                                      request.user.is_authenticated else None)

                # send the file to the client
                file_path = os.path.join(settings.ARCHIVE_BASE_PATH, row[0])
                return sendfile(request, file_path, attachment=True)
            else:
                # send an empty response
                return Response()

        # if the file was not found, return 404
        raise NotFound()
Exemplo n.º 2
0
    def process(self):
        # get collections for the owner of this download job
        collections = [
            collection.name for collection in
            Collection.objects.filter_by_access_level(self.owner)
        ]

        # get database adapter
        adapter = DatabaseAdapter()

        # get the schema_name and the table_name from the settings
        schema_name = settings.ARCHIVE_SCHEMA
        table_name = settings.ARCHIVE_TABLE

        # prepare list of files for this archive job
        files = []

        if 'file_ids' in self.data:
            if isinstance(self.data, QueryDict):
                file_ids = self.data.getlist('file_ids')
            else:
                file_ids = self.data.get('file_ids')

            for file_id in file_ids:
                # validate that the file_id is a valid UUID4
                try:
                    uuid.UUID(file_id, version=4)
                except ValueError:
                    raise ValidationError({
                        'files': [
                            _('One or more of the identifiers are not valid UUIDs.'
                              )
                        ]
                    })

                # fetch the path for this file from the database
                row = adapter.fetch_row(schema_name,
                                        table_name, ['path'],
                                        filters={
                                            'id': file_id,
                                            'collection': collections
                                        })

                # append the file to the list of files only if it exists in the database and on the filesystem
                if row and os.path.isfile(
                        os.path.join(settings.ARCHIVE_BASE_PATH, row[0])):
                    files.append(row[0])
                else:
                    raise ValidationError({
                        'files':
                        [_('One or more of the files cannot be found.')]
                    })

        elif 'search' in self.data:
            # retrieve the pathes of all file matching the search criteria
            rows = adapter.fetch_rows(schema_name,
                                      table_name,
                                      page_size=0,
                                      search=self.data['search'],
                                      filters={'collection': collections})

            # get the index of the path column in the row
            path_index = next(
                (i for i, column in enumerate(settings.ARCHIVE_COLUMNS)
                 if column['name'] == 'path'))

            for row in rows:
                # append the file to the list of files only if it exists on the filesystem
                if os.path.isfile(
                        os.path.join(settings.ARCHIVE_BASE_PATH,
                                     row[path_index])):
                    files.append(row[path_index])
                else:
                    raise ValidationError({
                        'files':
                        [_('One or more of the files cannot be found.')]
                    })

        else:
            raise ValidationError({[_('No data received.')]})

        # set files and file_path for this archive job
        self.files = files

        # set clean flag
        self.is_clean = True