Пример #1
0
    def setContentHeaders(self, file, offset, endByte, contentDisposition=None):
        """
        Sets the Content-Length, Content-Disposition, Content-Type, and also
        the Content-Range header if this is a partial download.

        :param file: The file being downloaded.
        :param offset: The start byte of the download.
        :type offset: int
        :param endByte: The end byte of the download (non-inclusive).
        :type endByte: int
        :param contentDisposition: Content-Disposition response header
            disposition-type value, if None, Content-Disposition will
            be set to 'attachment; filename=$filename'.
        :type contentDisposition: str or None
        """
        setResponseHeader(
            'Content-Type',
            file.get('mimeType') or 'application/octet-stream')
        setContentDisposition(file['name'], contentDisposition or 'attachment')
        setResponseHeader('Content-Length', max(endByte - offset, 0))

        if (offset or endByte < file['size']) and file['size']:
            setResponseHeader(
                'Content-Range',
                'bytes %d-%d/%d' % (offset, endByte - 1, file['size']))
    def setContentHeaders(self,
                          file,
                          offset,
                          endByte,
                          contentDisposition=None):
        """
        Sets the Content-Length, Content-Disposition, Content-Type, and also
        the Content-Range header if this is a partial download.

        :param file: The file being downloaded.
        :param offset: The start byte of the download.
        :type offset: int
        :param endByte: The end byte of the download (non-inclusive).
        :type endByte: int
        :param contentDisposition: Content-Disposition response header
            disposition-type value, if None, Content-Disposition will
            be set to 'attachment; filename=$filename'.
        :type contentDisposition: str or None
        """
        isRangeRequest = cherrypy.request.headers.get('Range')
        setResponseHeader('Content-Type',
                          file.get('mimeType') or 'application/octet-stream')
        setContentDisposition(file['name'], contentDisposition or 'attachment')
        setResponseHeader('Content-Length', max(endByte - offset, 0))

        if (offset or endByte < file['size']
                or isRangeRequest) and file['size']:
            setResponseHeader(
                'Content-Range',
                'bytes %d-%d/%d' % (offset, endByte - 1, file['size']))
Пример #3
0
    def pathDownload(self, path):
        user = self.getCurrentUser()
        path = '/'.join(path)
        resource = path_util.lookUpPath(path, user)['document']
        if resource['_modelType'] == 'file':
            singleFile = resource
        else:
            model = self._getResourceModel(resource['_modelType'], 'fileList')
            singleFile = None
            for _path, file in model.fileList(doc=resource, user=user, subpath=True, data=False):
                if singleFile is None:
                    singleFile = file
                else:
                    singleFile = False
                    break
        if singleFile is not False and singleFile is not None:
            offset, endByte = 0, None
            rangeHeader = cherrypy.lib.httputil.get_ranges(
                cherrypy.request.headers.get('Range'), singleFile.get('size', 0))
            if rangeHeader and len(rangeHeader):
                offset, endByte = rangeHeader[0]
            singleFile = File().load(singleFile['_id'], user=user, level=AccessType.READ)
            return File().download(singleFile, offset, endByte=endByte)
        setResponseHeader('Content-Type', 'application/zip')
        setContentDisposition(resource.get('name', 'Resources') + '.zip')

        def stream():
            zip = ziputil.ZipGenerator()
            for (path, file) in model.fileList(
                    doc=resource, user=user, subpath=True):
                for data in zip.addFile(file, path):
                    yield data
            yield zip.footer()
        return stream
Пример #4
0
 def _set_content_disposition(self,
                              name,
                              content_disposition,
                              mime_type=None):
     setResponseHeader('Content-Type', mime_type
                       or 'application/octet-stream')
     setContentDisposition(name, content_disposition or 'attachment')
Пример #5
0
    def download(self, assign_id, image_name):

        assignment = self.folder_m.load(assign_id,
                                        user=self.getCurrentUser(),
                                        level=AccessType.READ)

        label_folder = find_folder(p_folder=assignment,
                                   name=image_name,
                                   user=self.getCurrentUser(),
                                   create=True)

        folder = find_folder(p_folder=label_folder,
                             name=self.label_image_folder_name,
                             user=self.getCurrentUser(),
                             create=True)

        printOk(folder)

        setResponseHeader('Content-Type', 'application/zip')
        setContentDisposition(label_folder['name'] + '.zip')
        user = self.getCurrentUser()

        def stream():
            zip = ziputil.ZipGenerator(folder['name'])
            for (path, file) in self.folder_m.fileList(folder,
                                                       user=user,
                                                       subpath=False):
                for data in zip.addFile(file, path):
                    yield data
            yield zip.footer()

        return stream
Пример #6
0
    def exportTale(self, tale, params):
        user = self.getCurrentUser()
        folder = self.model('folder').load(tale['folderId'],
                                           user=user,
                                           level=AccessType.READ,
                                           exc=True)
        image = self.model('image', 'wholetale').load(tale['imageId'],
                                                      user=user,
                                                      level=AccessType.READ,
                                                      exc=True)
        recipe = self.model('recipe', 'wholetale').load(image['recipeId'],
                                                        user=user,
                                                        level=AccessType.READ,
                                                        exc=True)

        # Construct a sanitized name for the ZIP archive using a whitelist
        # approach
        zip_name = re.sub('[^a-zA-Z0-9-]', '_', tale['title'])

        setResponseHeader('Content-Type', 'application/zip')
        setContentDisposition(zip_name + '.zip')

        # Temporary: Fetch the GitHub archive of the recipe. Note that this is
        # done in a streaming fashion because ziputil makes use of generators
        # when files are added to the zip
        url = '{}/archive/{}.tar.gz'.format(recipe['url'], recipe['commitId'])
        req = requests.get(url, stream=True)

        def stream():
            zip = ziputil.ZipGenerator(zip_name)

            # Add files from the Tale folder
            for (path, f) in self.model('folder').fileList(folder,
                                                           user=user,
                                                           subpath=False):

                for data in zip.addFile(f, path):
                    yield data

            # Temporary: Add Image metadata
            for data in zip.addFile(lambda: image.__str__(), 'image.txt'):
                yield data

            # Temporary: Add Recipe metadata
            for data in zip.addFile(lambda: recipe.__str__(), 'recipe.txt'):
                yield data

            # Temporary: Add a zip of the recipe archive
            # TODO: Grab proper filename from header
            # e.g. 'Content-Disposition': 'attachment; filename= \
            # jupyter-base-b45f9a575602e6038b4da6333f2c3e679ee01c58.tar.gz'
            for data in zip.addFile(req.iter_content, 'archive.tar.gz'):
                yield data

            yield zip.footer()

        return stream
Пример #7
0
    def exportTale(self, tale, taleFormat):
        user = self.getCurrentUser()
        zip_name = str(tale['_id'])

        if taleFormat == 'bagit':
            exporter = BagTaleExporter(tale, user, expand_folders=True)
        elif taleFormat == 'native':
            exporter = NativeTaleExporter(tale, user)

        setResponseHeader('Content-Type', 'application/zip')
        setContentDisposition(zip_name + '.zip')
        return exporter.stream
Пример #8
0
    def download(self, colormap, name):
        setContentDisposition(name)

        def stream():
            yield json.dumps({
                'colormap': colormap['colormap']
            },
                             sort_keys=True,
                             allow_nan=False,
                             cls=JsonEncoder).encode('utf8')

        setResponseHeader('Content-Type', 'application/json')
        return stream
Пример #9
0
    def downloadKeyFile(self, file, algo):
        self._validateAlgo(algo)

        if algo not in file:
            raise RestException('This file does not have the %s hash computed.' % algo)
        keyFileBody = '%s\n' % file[algo]
        name = '.'.join((file['name'], algo))

        setResponseHeader('Content-Length', len(keyFileBody))
        setResponseHeader('Content-Type', 'text/plain')
        setContentDisposition(name)
        setRawResponse()

        return keyFileBody
Пример #10
0
    def downloadKeyFile(self, file, algo):
        self._validateAlgo(algo)

        if algo not in file:
            raise RestException('This file does not have the %s hash computed.' % algo)
        keyFileBody = '%s\n' % file[algo]
        name = '.'.join((file['name'], algo))

        setResponseHeader('Content-Length', len(keyFileBody))
        setResponseHeader('Content-Type', 'text/plain')
        setContentDisposition(name)
        setRawResponse()

        return keyFileBody
Пример #11
0
    def export(self, folder, params):
        setResponseHeader('Content-Type', 'application/zip')
        setContentDisposition(folder['name'] + '.zip')

        def stream():
            zip = ziputil.ZipGenerator(folder['name'])

            for data in zip.addFile(DetectionResource.generateKPFContent(folder), folder['name'] + '.geom.kpf'):
                yield data
            for data in zip.addFile(TypesResource.generateKPFContent(folder), folder['name'] + '.types.kpf'):
                yield data
            for data in zip.addFile(ActivitiesResource.generateKPFContent(folder), folder['name'] + '.activities.kpf'):
                yield data
            yield zip.footer()
        return stream
Пример #12
0
    def iter(self, fields, files):
        encoder = codecs.getencoder('utf-8')
        for (key, value) in fields:
            key = self.u(key)
            yield encoder('--%s\r\n' % self.boundary)
            yield encoder(
                self.u('Content-Disposition: form-data; '
                       'name="%s"\r\n') % key)
            yield encoder('\r\n')
            if isinstance(value, int) or isinstance(value, float):
                value = str(value)
            yield encoder(self.u(value))
            yield encoder('\r\n')
        for (key, filename, content) in files:
            key = self.u(key)
            filename = self.u(filename)
            yield encoder('--%s\r\n' % self.boundary)
            disposition = setContentDisposition(filename,
                                                'form-data; name="%s"' % key,
                                                False)
            yield encoder(
                self.u('Content-Disposition: ') + self.u(disposition))
            yield encoder('Content-Type: application/octet-stream\r\n')
            yield encoder('\r\n')

            yield (content, len(content))
            yield encoder('\r\n')
        yield encoder('--%s--\r\n' % self.boundary)
Пример #13
0
    def export_all(self, folder, excludeBelowThreshold):
        _, gen = self._generate_detections(folder, excludeBelowThreshold)
        setResponseHeader('Content-Type', 'application/zip')
        setContentDisposition(folder['name'] + '.zip')
        user = self.getCurrentUser()

        def stream():
            z = ziputil.ZipGenerator(folder['name'])
            for (path, file) in Folder().fileList(folder, user=user, subpath=False):
                for data in z.addFile(file, path):
                    yield data
            for data in z.addFile(gen, "output_tracks.csv"):
                yield data
            yield z.footer()

        return stream
Пример #14
0
 def _getRequestHeaders(self, upload):
     return {
         'Content-Disposition': setContentDisposition(upload['name'], setHeader=False),
         'Content-Type': upload.get('mimeType', ''),
         'x-amz-acl': 'private',
         'x-amz-meta-uploader-id': str(upload['userId']),
         'x-amz-meta-uploader-ip': str(cherrypy.request.remote.ip)
     }
Пример #15
0
    def _getRequestHeaders(self, upload):
        headers = {
            'Content-Disposition': setContentDisposition(upload['name'], setHeader=False),
            'Content-Type': upload.get('mimeType', ''),
            'x-amz-acl': 'private',
            'x-amz-meta-uploader-id': str(upload['userId']),
            'x-amz-meta-uploader-ip': str(cherrypy.request.remote.ip)
        }
        if self.assetstore.get('serverSideEncryption'):
            headers['x-amz-server-side-encryption'] = 'AES256'

        return headers
Пример #16
0
    def _getRequestHeaders(self, upload):
        headers = {
            'Content-Disposition': setContentDisposition(upload['name'], setHeader=False),
            'Content-Type': upload.get('mimeType', ''),
            'x-amz-acl': 'private',
            'x-amz-meta-uploader-id': str(upload['userId']),
            'x-amz-meta-uploader-ip': str(cherrypy.request.remote.ip)
        }
        if self.assetstore.get('serverSideEncryption'):
            headers['x-amz-server-side-encryption'] = 'AES256'

        return headers
Пример #17
0
def downloadArchiveFile(self, file, path, offset, endByte, contentDisposition,
                        extraParameters):
    """
    Requires read permission on the folder that contains the file's item.
    """
    with ArchiveFileHandle(File(), file, path) as fileobj:
        info = fileobj.info()
        rangeHeader = cherrypy.lib.httputil.get_ranges(
            cherrypy.request.headers.get('Range'), info['size'])
        # The HTTP Range header takes precedence over query params
        if rangeHeader and len(rangeHeader):
            # Currently we only support a single range.
            offset, endByte = rangeHeader[0]
        if offset:
            fileobj.seek(offset)
        else:
            offset = 0
        if endByte is None or endByte > info['size']:
            endByte = info['size']
        setResponseHeader('Accept-Ranges', 'bytes')
        setResponseHeader('Content-Type', 'application/octet-stream')
        setContentDisposition(os.path.basename(path), contentDisposition
                              or 'attachment')
        setResponseHeader('Content-Length', max(endByte - offset, 0))

        if (offset or endByte < file['size']) and file['size']:
            setResponseHeader(
                'Content-Range',
                'bytes %d-%d/%d' % (offset, endByte - 1, file['size']))

        def downloadGenerator():
            pos = offset
            while pos < endByte:
                data = fileobj.read(min(65536, endByte - pos))
                yield data
                pos += len(data)
                if pos >= endByte:
                    break

        return downloadGenerator
Пример #18
0
    def download_folder(self, event, path, root, user=None):
        self.is_dir(path, root["_id"])
        setResponseHeader("Content-Type", "application/zip")
        setContentDisposition(path.name + ".zip")

        def stream():
            def recursive_file_list(p):
                for obj in p.iterdir():
                    if obj.is_file():
                        yield obj
                    elif obj.is_dir():
                        yield from recursive_file_list(obj)

            zip_stream = ziputil.ZipGenerator(rootPath="")
            for obj in recursive_file_list(path):
                zip_path = os.path.relpath(obj.as_posix(), path.as_posix())
                for data in zip_stream.addFile(lambda: file_stream(obj),
                                               zip_path):
                    yield data
            yield zip_stream.footer()

        event.preventDefault().addResponse(stream)
Пример #19
0
 def _getRequestHeaders(self, upload):
     return {
         'Content-Disposition':
         setContentDisposition(upload['name'], setHeader=False),
         'Content-Type':
         upload.get('mimeType', ''),
         'x-amz-acl':
         'private',
         'x-amz-meta-uploader-id':
         str(upload['userId']),
         'x-amz-meta-uploader-ip':
         str(cherrypy.request.remote.ip)
     }
Пример #20
0
    def iter(self, fields, files):
        encoder = codecs.getencoder('utf-8')
        for (key, value) in fields:
            key = self.u(key)
            yield encoder('--%s\r\n' % self.boundary)
            yield encoder(self.u('Content-Disposition: form-data; '
                                 'name="%s"\r\n') % key)
            yield encoder('\r\n')
            if isinstance(value, int) or isinstance(value, float):
                value = str(value)
            yield encoder(self.u(value))
            yield encoder('\r\n')
        for (key, filename, content) in files:
            key = self.u(key)
            filename = self.u(filename)
            yield encoder('--%s\r\n' % self.boundary)
            disposition = setContentDisposition(filename, 'form-data; name="%s"' % key, False)
            yield encoder(self.u('Content-Disposition: ') + self.u(disposition))
            yield encoder('Content-Type: application/octet-stream\r\n')
            yield encoder('\r\n')

            yield (content, len(content))
            yield encoder('\r\n')
        yield encoder('--%s--\r\n' % self.boundary)
Пример #21
0
def testSetContentDisposition(name, disp, expected):
    if disp is None:
        assert rest.setContentDisposition(name, setHeader=False) == expected
    else:
        assert rest.setContentDisposition(name, disp,
                                          setHeader=False) == expected
Пример #22
0
def testSetContentDispositionFails(name, disp, msg):
    with pytest.raises(rest.RestException, match=msg):
        rest.setContentDisposition(name, disp, setHeader=False)
Пример #23
0
 def testSetContentDisposition(self):
     with six.assertRaisesRegex(
             self, rest.RestException,
             'Error: Content-Disposition \(.*\) is not a recognized value.'):
         rest.setContentDisposition('filename', 'unknown', False)
     with six.assertRaisesRegex(
             self, rest.RestException, 'Error: Content-Disposition filename is empty.'):
         rest.setContentDisposition('', setHeader=False)
     self.assertEqual(rest.setContentDisposition(
         'filename', setHeader=False),
         'attachment; filename="filename"')
     self.assertEqual(rest.setContentDisposition(
         'filename', 'inline', setHeader=False),
         'inline; filename="filename"')
     self.assertEqual(rest.setContentDisposition(
         'filename', 'form-data; name="chunk"', setHeader=False),
         'form-data; name="chunk"; filename="filename"')
     self.assertEqual(rest.setContentDisposition(
         'file "name"', setHeader=False),
         'attachment; filename="file \\"name\\""')
     self.assertEqual(rest.setContentDisposition(
         'file\\name', setHeader=False),
         'attachment; filename="file\\\\name"')
     self.assertEqual(rest.setContentDisposition(
         u'\u043e\u0431\u0440\u0430\u0437\u0435\u0446', setHeader=False),
         'attachment; filename=""; filename*=UTF-8\'\''
         '%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%B5%D1%86')
     self.assertEqual(rest.setContentDisposition(
         u'\U0001f603', setHeader=False),
         'attachment; filename=""; filename*=UTF-8\'\'%F0%9F%98%83')
 def export_detections(self, folder, excludeBelowThreshold):
     filename, gen = self._generate_detections(folder,
                                               excludeBelowThreshold)
     setContentDisposition(filename)
     return gen
Пример #25
0
def testSetContentDisposition(name, disp, expected):
    if disp is None:
        assert rest.setContentDisposition(name, setHeader=False) == expected
    else:
        assert rest.setContentDisposition(name, disp, setHeader=False) == expected
Пример #26
0
 def testSetContentDisposition(self):
     with six.assertRaisesRegex(
             self, rest.RestException,
             'Error: Content-Disposition \(.*\) is not a recognized value.'
     ):
         rest.setContentDisposition('filename', 'unknown', False)
     with six.assertRaisesRegex(
             self, rest.RestException,
             'Error: Content-Disposition filename is empty.'):
         rest.setContentDisposition('', setHeader=False)
     self.assertEqual(
         rest.setContentDisposition('filename', setHeader=False),
         'attachment; filename="filename"')
     self.assertEqual(
         rest.setContentDisposition('filename', 'inline', setHeader=False),
         'inline; filename="filename"')
     self.assertEqual(
         rest.setContentDisposition('filename',
                                    'form-data; name="chunk"',
                                    setHeader=False),
         'form-data; name="chunk"; filename="filename"')
     self.assertEqual(
         rest.setContentDisposition('file "name"', setHeader=False),
         'attachment; filename="file \\"name\\""')
     self.assertEqual(
         rest.setContentDisposition('file\\name', setHeader=False),
         'attachment; filename="file\\\\name"')
     self.assertEqual(
         rest.setContentDisposition(
             u'\u043e\u0431\u0440\u0430\u0437\u0435\u0446',
             setHeader=False),
         'attachment; filename=""; filename*=UTF-8\'\''
         '%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%B5%D1%86')
     self.assertEqual(
         rest.setContentDisposition(u'\U0001f603', setHeader=False),
         'attachment; filename=""; filename*=UTF-8\'\'%F0%9F%98%83')
Пример #27
0
def testSetContentDispositionFails(name, disp, msg):
    with pytest.raises(rest.RestException, match=msg):
        rest.setContentDisposition(name, disp, setHeader=False)
Пример #28
0
 def csvExportDownload(self, params):
     setResponseHeader('Content-Type', 'text/csv')
     setContentDisposition('_output.csv')
     output = self.getExportCSV()
     return lambda: [(yield x) for x in output.getvalue()]