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()
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