Ejemplo n.º 1
0
    async def _get_file_meta(self,
                             path: wb_path.WaterButlerPath,
                             raw: bool=False,
                             revision: str=None) -> typing.Union[dict, BoxFileMetadata]:
        if revision:
            url = self.build_url('files', path.identifier, 'versions')
        else:
            url = self.build_url('files', path.identifier)

        async with self.request(
            'GET', url,
            expects=(200, ),
            throws=exceptions.MetadataError,
        ) as resp:
            data = await resp.json()

        if revision:
            try:
                data = next(x for x in data['entries'] if x['id'] == revision)
            except StopIteration:
                raise exceptions.NotFoundError(str(path))

        if not data:
            raise exceptions.NotFoundError(str(path))

        return data if raw else BoxFileMetadata(data, path)
Ejemplo n.º 2
0
    async def upload(
            self,  # type: ignore
            stream: streams.BaseStream,
            path: WaterButlerPath,
            conflict: str = 'replace',
            **kwargs) -> Tuple[BoxFileMetadata, bool]:
        """Upload a file to Box.  If the file is less than ``NONCHUNKED_UPLOAD_LIMIT``, upload in
        a single request.  Otherwise, use Box's chunked upload interface to send it across multiple
        requests.
        """

        if path.identifier and conflict == 'keep':
            path, _ = await self.handle_name_conflict(path,
                                                      conflict=conflict,
                                                      kind='folder')
            path._parts[-1]._id = None

        if stream.size > self.NONCHUNKED_UPLOAD_LIMIT:
            entry = await self._chunked_upload(path, stream)
        else:
            entry = await self._contiguous_upload(path, stream)

        created = path.identifier is None
        path._parts[-1]._id = entry['id']

        return BoxFileMetadata(entry, path), created
Ejemplo n.º 3
0
    def upload(self, stream, path, conflict='replace', **kwargs):
        if path.identifier and conflict == 'keep':
            path, _ = self.handle_name_conflict(path, conflict=conflict, kind='folder')
            path._parts[-1]._id = None

        data_stream = streams.FormDataStream(
            attributes=json.dumps({
                'name': path.name,
                'parent': {
                    'id': path.parent.identifier
                }
            })
        )
        data_stream.add_file('file', stream, path.name, disposition='form-data')

        resp = yield from self.make_request(
            'POST',
            self._build_upload_url(*filter(lambda x: x is not None, ('files', path.identifier, 'content'))),
            data=data_stream,
            headers=data_stream.headers,
            expects=(201,),
            throws=exceptions.UploadError,
        )

        data = yield from resp.json()
        return BoxFileMetadata(data['entries'][0], path), path.identifier is None
Ejemplo n.º 4
0
    def test_upload_create(self, provider, folder_object_metadata,
                           folder_list_metadata, file_metadata, file_stream,
                           settings):
        path = WaterButlerPath('/newfile', _ids=(provider.folder, None))

        upload_url = provider._build_upload_url('files', 'content')
        folder_object_url = provider.build_url('folders',
                                               path.parent.identifier)
        folder_list_url = provider.build_url('folders', path.parent.identifier,
                                             'items')

        aiohttpretty.register_json_uri('POST',
                                       upload_url,
                                       status=201,
                                       body=file_metadata)

        metadata, created = yield from provider.upload(file_stream, path)

        expected = BoxFileMetadata(file_metadata['entries'][0],
                                   path).serialized()

        assert metadata.serialized() == expected
        assert created is True
        assert path.identifier_path == metadata.path
        assert aiohttpretty.has_call(method='POST', uri=upload_url)
Ejemplo n.º 5
0
    def test_metadata(self, provider, folder_object_metadata,
                      folder_list_metadata):
        path = WaterButlerPath('/', _ids=(provider.folder, ))

        list_url = provider.build_url('folders',
                                      provider.folder,
                                      'items',
                                      fields='id,name,size,modified_at,etag')

        aiohttpretty.register_json_uri('GET',
                                       list_url,
                                       body=folder_list_metadata)

        result = yield from provider.metadata(path)

        expected = []

        for x in folder_list_metadata['entries']:
            if x['type'] == 'file':
                expected.append(BoxFileMetadata(x, path.child(x['name'])))
            else:
                expected.append(
                    BoxFolderMetadata(x, path.child(x['name'], folder=True)))

        assert result == expected
Ejemplo n.º 6
0
    async def test_metadata(self, provider, root_provider_fixtures):
        path = WaterButlerPath('/', _ids=(provider.folder, ))

        list_url = provider.build_url(
            'folders',
            provider.folder,
            'items',
            fields='id,name,size,modified_at,etag,total_count',
            offset=0,
            limit=1000)

        list_metadata = root_provider_fixtures['folder_list_metadata']
        aiohttpretty.register_json_uri('GET', list_url, body=list_metadata)

        result = await provider.metadata(path)

        expected = []

        for x in list_metadata['entries']:
            if x['type'] == 'file':
                expected.append(BoxFileMetadata(x, path.child(x['name'])))
            else:
                expected.append(
                    BoxFolderMetadata(x, path.child(x['name'], folder=True)))

        assert result == expected
Ejemplo n.º 7
0
    def test_metadata_nested(self, provider, file_metadata):
        item = file_metadata['entries'][0]
        path = WaterButlerPath('/name.txt', _ids=(provider, item['id']))

        file_url = provider.build_url('files', path.identifier)
        aiohttpretty.register_json_uri('GET', file_url, body=item)

        result = yield from provider.metadata(path)

        expected = BoxFileMetadata(item, path)
        assert result == expected
        assert aiohttpretty.has_call(method='GET', uri=file_url)
Ejemplo n.º 8
0
    def test_upload_update(self, provider, folder_object_metadata, folder_list_metadata, file_metadata, file_stream, settings):
        item = folder_list_metadata['entries'][0]
        path = WaterButlerPath('/newfile', _ids=(provider.folder, item['id']))
        upload_url = provider._build_upload_url('files', item['id'], 'content')
        aiohttpretty.register_json_uri('POST', upload_url, status=201, body=file_metadata)

        metadata, created = yield from provider.upload(file_stream, path)

        expected = BoxFileMetadata(file_metadata['entries'][0], path).serialized()

        assert metadata == expected
        assert created is False
        assert aiohttpretty.has_call(method='POST', uri=upload_url)
Ejemplo n.º 9
0
    def _get_file_meta(self, path, raw=False):
        resp = yield from self.make_request(
            'GET',
            self.build_url('files', path.identifier),
            expects=(200, ),
            throws=exceptions.MetadataError,
        )
        data = yield from resp.json()

        if not data:
            raise exceptions.NotFoundError(str(path))

        return data if raw else BoxFileMetadata(data, path)
Ejemplo n.º 10
0
    async def test_intra_move_file(self, provider, root_provider_fixtures):
        item = root_provider_fixtures['file_metadata']['entries'][0]
        src_path = WaterButlerPath('/name.txt', _ids=(provider, item['id']))
        dest_path = WaterButlerPath('/charmander/name.txt',
                                    _ids=(provider, item['id']))

        file_url = provider.build_url('files', src_path.identifier)
        aiohttpretty.register_json_uri('PUT', file_url, body=item)

        result = await provider.intra_move(provider, src_path, dest_path)
        expected = (BoxFileMetadata(item, dest_path), True)

        assert result == expected
Ejemplo n.º 11
0
    async def test_revision_metadata(self, provider, root_provider_fixtures,
                                     revision_fixtures):
        list_metadata = revision_fixtures['revisions_list_metadata']
        item = list_metadata['entries'][0]

        path = WaterButlerPath('/goats', _ids=(provider.folder, item['id']))
        url = provider.build_url('files', path.identifier, 'versions')

        aiohttpretty.register_json_uri('GET', url, body=list_metadata)

        result = await provider.metadata(path, revision=item['id'])
        expected = BoxFileMetadata(item, path)

        assert result == expected
Ejemplo n.º 12
0
    async def test_intra_copy_file_replace(self, provider,
                                           root_provider_fixtures):
        item = root_provider_fixtures['file_metadata']['entries'][0]
        src_path = WaterButlerPath('/name.txt', _ids=(provider, item['id']))
        dest_path = WaterButlerPath('/charmander/name.txt',
                                    _ids=(provider, item['id'], item['id']))

        file_url = provider.build_url('files', src_path.identifier, 'copy')
        delete_url = provider.build_url('files', dest_path.identifier)
        aiohttpretty.register_uri('DELETE', delete_url, status=204)
        aiohttpretty.register_json_uri('POST', file_url, body=item)

        result = await provider.intra_copy(provider, src_path, dest_path)
        expected = (BoxFileMetadata(item, dest_path), False)

        assert result == expected
Ejemplo n.º 13
0
    async def upload(
            self,  # type: ignore
            stream: streams.BaseStream,
            path: WaterButlerPath,
            conflict: str = 'replace',
            **kwargs) -> Tuple[BoxFileMetadata, bool]:
        if path.identifier and conflict == 'keep':
            path, _ = await self.handle_name_conflict(path,
                                                      conflict=conflict,
                                                      kind='folder')
            path._parts[-1]._id = None

        stream.add_writer('sha1', streams.HashStreamWriter(hashlib.sha1))

        data_stream = streams.FormDataStream(
            attributes=json.dumps({
                'name': path.name,
                'parent': {
                    'id': path.parent.identifier
                }
            }))
        data_stream.add_file('file',
                             stream,
                             path.name,
                             disposition='form-data')

        async with self.request(
                'POST',
                self._build_upload_url(
                    *filter(lambda x: x is not None, ('files', path.identifier,
                                                      'content'))),
                data=data_stream,
                headers=data_stream.headers,
                expects=(201, ),
                throws=exceptions.UploadError,
        ) as resp:
            data = await resp.json()

        entry = data['entries'][0]
        if stream.writers['sha1'].hexdigest != entry['sha1']:
            raise exceptions.UploadChecksumMismatchError()

        created = path.identifier is None
        path._parts[-1]._id = entry['id']
        return BoxFileMetadata(entry, path), created
Ejemplo n.º 14
0
    async def test_metadata_nested(self, provider, root_provider_fixtures):
        item = root_provider_fixtures['file_metadata']['entries'][0]
        path = WaterButlerPath('/name.txt', _ids=(provider, item['id']))

        file_url = provider.build_url('files', path.identifier)
        aiohttpretty.register_json_uri('GET', file_url, body=item)

        result = await provider.metadata(path)

        expected = BoxFileMetadata(item, path)
        assert result == expected
        assert aiohttpretty.has_call(method='GET', uri=file_url)
        assert result.extra == {
            'etag': '3',
            'hashes': {
                'sha1': '134b65991ed521fcfe4724b7d814ab8ded5185dc',
            },
        }
Ejemplo n.º 15
0
    async def test_upload_create(self, provider, root_provider_fixtures,
                                 file_stream):
        path = WaterButlerPath('/newfile', _ids=(provider.folder, None))
        upload_url = provider._build_upload_url('files', 'content')
        upload_metadata = root_provider_fixtures['upload_metadata']
        aiohttpretty.register_json_uri('POST',
                                       upload_url,
                                       status=201,
                                       body=upload_metadata)

        metadata, created = await provider.upload(file_stream, path)
        expected = BoxFileMetadata(upload_metadata['entries'][0],
                                   path).serialized()

        assert metadata.serialized() == expected
        assert created is True
        assert path.identifier_path == metadata.path
        assert aiohttpretty.has_call(method='POST', uri=upload_url)
Ejemplo n.º 16
0
    async def test_upload_conflict_keep(self, provider, root_provider_fixtures,
                                        file_stream):
        upload_metadata = root_provider_fixtures['upload_metadata']
        item = upload_metadata['entries'][0]
        path = WaterButlerPath('/newfile', _ids=(provider.folder, item['id']))

        upload_url = provider._build_upload_url('files', 'content')
        aiohttpretty.register_json_uri('POST',
                                       upload_url,
                                       status=201,
                                       body=upload_metadata)

        metadata_url = provider.build_url('files', path.identifier)
        aiohttpretty.register_json_uri('GET',
                                       metadata_url,
                                       body=upload_metadata)

        list_url = provider.build_url(
            'folders',
            item['path_collection']['entries'][1]['id'],
            'items',
            fields='id,name,type',
            limit=1000)
        aiohttpretty.register_json_uri(
            'GET',
            list_url,
            body=root_provider_fixtures['folder_list_metadata'])

        metadata, created = await provider.upload(file_stream,
                                                  path,
                                                  conflict='keep')
        expected = BoxFileMetadata(item, path).serialized()

        # since the metadata for the renamed conflict file isn't actually saved, this one is odd to
        # test.
        assert metadata.serialized() == expected
        assert created is True
        assert path.identifier_path == metadata.path
        assert aiohttpretty.has_call(method='POST', uri=upload_url)
Ejemplo n.º 17
0
    async def test_upload_update(self, provider, root_provider_fixtures,
                                 file_stream):
        upload_metadata = root_provider_fixtures['upload_metadata']
        item_to_overwrite = root_provider_fixtures['folder_list_metadata'][
            'entries'][0]
        path = WaterButlerPath('/newfile',
                               _ids=(provider.folder, item_to_overwrite['id']))
        upload_url = provider._build_upload_url('files',
                                                item_to_overwrite['id'],
                                                'content')
        aiohttpretty.register_json_uri('POST',
                                       upload_url,
                                       status=201,
                                       body=upload_metadata)

        metadata, created = await provider.upload(file_stream, path)
        expected = BoxFileMetadata(upload_metadata['entries'][0],
                                   path).serialized()

        assert metadata.serialized() == expected
        assert created is False
        assert aiohttpretty.has_call(method='POST', uri=upload_url)
Ejemplo n.º 18
0
    def _get_file_meta(self, path, raw=False, revision=None):
        if revision:
            url = self.build_url('files', path.identifier, 'versions')
        else:
            url = self.build_url('files', path.identifier)

        resp = yield from self.make_request(
            'GET', url,
            expects=(200, ),
            throws=exceptions.MetadataError,
        )
        data = yield from resp.json()

        if revision:
            try:
                data = next(x for x in data['entries'] if x['id'] == revision)
            except StopIteration:
                raise exceptions.NotFoundError(str(path))

        if not data:
            raise exceptions.NotFoundError(str(path))

        return data if raw else BoxFileMetadata(data, path)
Ejemplo n.º 19
0
    def test_file_metadata(self, root_provider_fixtures):
        item = root_provider_fixtures['file_metadata']['entries'][0]
        dest_path = WaterButlerPath('/charmander/name.txt',
                                    _ids=('0', item['id'], item['id']))
        data = BoxFileMetadata(item, dest_path)
        assert data.name == 'tigers.jpeg'
        assert data.path == '/5000948880'
        assert data.provider == 'box'
        assert data.size == 629644
        assert data.size_as_int == 629644
        assert type(data.size_as_int) == int
        assert data.modified == '2012-12-12T11:04:26-08:00'
        assert data.created_utc == '2012-12-12T18:55:30+00:00'
        assert data.content_type is None
        assert data.etag == '3::5000948880'
        assert data.extra == {
            'etag': '3',
            'hashes': {
                'sha1': '134b65991ed521fcfe4724b7d814ab8ded5185dc'
            }
        }

        assert data.serialized() == {
            'extra': {
                'etag': '3',
                'hashes': {
                    'sha1': '134b65991ed521fcfe4724b7d814ab8ded5185dc'
                }
            },
            'kind': 'file',
            'name': 'tigers.jpeg',
            'path': '/5000948880',
            'provider': 'box',
            'materialized': '/charmander/name.txt',
            'etag':
            'c14cacfd0701ec2d45e0b8cb89e996f00e2ec861897e8a9656adc12781c889f8',
            'contentType': None,
            'modified': '2012-12-12T11:04:26-08:00',
            'modified_utc': '2012-12-12T19:04:26+00:00',
            'created_utc': '2012-12-12T18:55:30+00:00',
            'size': 629644,
            'sizeInt': 629644,
        }
        assert data.kind == 'file'
        assert data.modified_utc == '2012-12-12T19:04:26+00:00'
        assert data.json_api_serialized('cn42d') == {
            'id': 'box/5000948880',
            'type': 'files',
            'attributes': {
                'extra': {
                    'etag': '3',
                    'hashes': {
                        'sha1': '134b65991ed521fcfe4724b7d814ab8ded5185dc'
                    }
                },
                'kind': 'file',
                'name': 'tigers.jpeg',
                'path': '/5000948880',
                'provider': 'box',
                'materialized': '/charmander/name.txt',
                'etag':
                'c14cacfd0701ec2d45e0b8cb89e996f00e2ec861897e8a9656adc12781c889f8',
                'contentType': None,
                'modified': '2012-12-12T11:04:26-08:00',
                'modified_utc': '2012-12-12T19:04:26+00:00',
                'created_utc': '2012-12-12T18:55:30+00:00',
                'size': 629644,
                'sizeInt': 629644,
                'resource': 'cn42d'
            },
            'links': {
                'move':
                'http://localhost:7777/v1/resources/cn42d/providers/box/5000948880',
                'upload': ('http://localhost:7777/v1/resources'
                           '/cn42d/providers/box/5000948880?kind=file'),
                'delete':
                'http://localhost:7777/v1/resources/cn42d/providers/box/5000948880',
                'download':
                'http://localhost:7777/v1/resources/cn42d/providers/box/5000948880'
            }
        }