예제 #1
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
예제 #2
0
    def validate_path(self, path, **kwargs):
        split = path.rstrip('/').split('/')[1:]
        wbpath = WaterButlerPath('/',
                                 _ids=(self.settings['project_id'], ),
                                 folder=True)

        if split:
            name_or_id = split.pop(0)
            try:
                article = yield from self._assert_contains_article(name_or_id)
            except ValueError:
                return wbpath.child(name_or_id, folder=False)
            except exceptions.ProviderError as e:
                if e.code not in (404, 401):
                    raise
                return wbpath.child(name_or_id, folder=False)

            wbpath = wbpath.child(article['title'], article['id'], folder=True)

        if split:
            provider = yield from self._make_article_provider(
                article['id'], check_parent=False)
            try:
                return (yield from
                        provider.validate_path('/'.join([''] + split),
                                               parent=wbpath))
            except exceptions.ProviderError as e:
                if e.code not in (404, 401):
                    raise
                return wbpath.child(split.pop(0), folder=False)

        return wbpath
예제 #3
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
예제 #4
0
    def validate_path(self, path, **kwargs):
        split = path.rstrip('/').split('/')[1:]
        wbpath = WaterButlerPath('/', _ids=(self.settings['project_id'], ), folder=True)

        if split:
            name_or_id = split.pop(0)
            try:
                article = yield from self._assert_contains_article(name_or_id)
            except ValueError:
                return wbpath.child(name_or_id, folder=False)
            except exceptions.ProviderError as e:
                if e.code not in (404, 401):
                    raise
                return wbpath.child(name_or_id, folder=False)

            wbpath = wbpath.child(article['title'], article['id'], folder=True)

        if split:
            provider = yield from self._make_article_provider(article['id'], check_parent=False)
            try:
                return (yield from provider.validate_path('/'.join([''] + split), parent=wbpath))
            except exceptions.ProviderError as e:
                if e.code not in (404, 401):
                    raise
                return wbpath.child(split.pop(0), folder=False)

        return wbpath
예제 #5
0
    async def revalidate_path(self, base: WaterButlerPath, path: str,
                              folder: bool=None) -> WaterButlerPath:
        # TODO Research the search api endpoint
        async with self.request(
            'GET',
            self.build_url('folders', base.identifier, 'items',
                           fields='id,name,type', limit=1000),
            expects=(200,),
            throws=exceptions.ProviderError
        ) as resp:
            data = await resp.json()
        lower_name = path.lower()

        try:
            item = next(
                x for x in data['entries']
                if x['name'].lower() == lower_name and (
                    folder is None or
                    (x['type'] == 'folder') == folder
                )
            )
            name = path  # Use path over x['name'] because of casing issues
            _id = item['id']
            folder = item['type'] == 'folder'
        except StopIteration:
            _id = None
            name = path

        return base.child(name, _id=_id, folder=folder)
예제 #6
0
    async def test_intra_move_folder(self, provider, intra_fixtures,
                                     root_provider_fixtures):
        item = intra_fixtures['intra_folder_metadata']
        list_metadata = root_provider_fixtures['folder_list_metadata']

        src_path = WaterButlerPath('/name/', _ids=(provider, item['id']))
        dest_path = WaterButlerPath('/charmander/name/',
                                    _ids=(provider, item['id']))

        file_url = provider.build_url('folders', src_path.identifier)
        list_url = provider.build_url(
            'folders',
            item['id'],
            'items',
            fields='id,name,size,modified_at,etag,total_count',
            offset=0,
            limit=1000)

        aiohttpretty.register_json_uri('PUT', file_url, body=item)
        aiohttpretty.register_json_uri('GET', list_url, body=list_metadata)

        expected_folder = BoxFolderMetadata(item, dest_path)
        expected_folder._children = []
        for child_item in list_metadata['entries']:
            child_path = dest_path.child(
                child_item['name'], folder=(child_item['type'] == 'folder'))
            serialized_child = provider._serialize_item(child_item, child_path)
            expected_folder._children.append(serialized_child)
        expected = (expected_folder, True)

        result = await provider.intra_move(provider, src_path, dest_path)

        assert result == expected
예제 #7
0
 async def _folder_metadata(
         self,
         path: WaterButlerPath,
         raw: bool = False) -> List[Union[BaseGoogleDriveMetadata, dict]]:
     query = self._build_query(path.identifier)
     built_url = self.build_url('files',
                                q=query,
                                alt='json',
                                maxResults=1000)
     full_resp = []
     while built_url:
         async with self.request(
                 'GET',
                 built_url,
                 expects=(200, ),
                 throws=exceptions.MetadataError,
         ) as resp:
             resp_json = await resp.json()
             full_resp.extend([
                 self._serialize_item(path.child(item['title']),
                                      item,
                                      raw=raw)
                 for item in resp_json['items']
             ])
             built_url = resp_json.get('nextLink', None)
     return full_resp
예제 #8
0
    async def revalidate_path(self,
                              base: WaterButlerPath,
                              name: str,
                              folder: bool = None) -> WaterButlerPath:
        # TODO Redo the logic here folders names ending in /s
        # Will probably break
        if '/' in name.lstrip('/') and '%' not in name:
            # DAZ and MnC may pass unquoted names which break
            # if the name contains a / in it
            name = parse.quote(name.lstrip('/'), safe='')

        if not name.endswith('/') and folder:
            name += '/'

        parts = await self._resolve_path_to_ids(name,
                                                start_at=[{
                                                    'title':
                                                    base.name,
                                                    'mimeType':
                                                    'folder',
                                                    'id':
                                                    base.identifier,
                                                }])
        _id, name, mime = list(
            map(parts[-1].__getitem__, ('id', 'title', 'mimeType')))
        return base.child(name, _id=_id, folder='folder' in mime)
예제 #9
0
    async def revalidate_path(self, base: wb_path.WaterButlerPath, path: str,
                              folder: bool=None) -> wb_path.WaterButlerPath:
        # TODO Research the search api endpoint
        async with self.request(
            'GET',
            self.build_url('folders', base.identifier, 'items',
                           fields='id,name,type', limit=1000),
            expects=(200,),
            throws=exceptions.ProviderError
        ) as resp:
            data = await resp.json()
        lower_name = path.lower()

        try:
            item = next(
                x for x in data['entries']
                if x['name'].lower() == lower_name and (
                    folder is None or
                    (x['type'] == 'folder') == folder
                )
            )
            name = path  # Use path over x['name'] because of casing issues
            _id = item['id']
            folder = item['type'] == 'folder'
        except StopIteration:
            _id = None
            name = path

        return base.child(name, _id=_id, folder=folder)
    async def test_intra_move_folder_replace(self, provider, intra_fixtures, root_provider_fixtures):
        item = intra_fixtures['intra_folder_metadata']
        list_metadata = root_provider_fixtures['folder_list_metadata']

        src_path = WaterButlerPath('/name/', _ids=(provider, item['id']))
        dest_path = WaterButlerPath('/charmander/name/', _ids=(provider, item['id'], item['id']))

        file_url = provider.build_url('folders', src_path.identifier)
        delete_url = provider.build_url('folders', dest_path.identifier, recursive=True)
        list_url = provider.build_url('folders', item['id'], 'items',
                                      fields='id,name,size,modified_at,etag,total_count',
                                      offset=0, limit=1000)

        aiohttpretty.register_json_uri('PUT', file_url, body=item)
        aiohttpretty.register_uri('DELETE', delete_url, status=204)
        aiohttpretty.register_json_uri('GET', list_url, body=list_metadata)

        expected_folder = BoxFolderMetadata(item, dest_path)
        expected_folder._children = []
        for child_item in list_metadata['entries']:
            child_path = dest_path.child(child_item['name'], folder=(child_item['type'] == 'folder'))
            serialized_child = provider._serialize_item(child_item, child_path)
            expected_folder._children.append(serialized_child)
        expected = (expected_folder, False)

        result = await provider.intra_move(provider, src_path, dest_path)

        assert result == expected
        assert aiohttpretty.has_call(method='DELETE', uri=delete_url)
    async def test_intra_copy_folder(self, provider, intra_fixtures, root_provider_fixtures):
        item = intra_fixtures['intra_folder_metadata']
        list_metadata = root_provider_fixtures['folder_list_metadata']

        src_path = WaterButlerPath('/name/', _ids=(provider, item['id']))
        dest_path = WaterButlerPath('/charmander/name/', _ids=(provider, item['id']))

        file_url = provider.build_url('folders', src_path.identifier, 'copy')
        list_url = provider.build_url('folders', item['id'], 'items',
                                      fields='id,name,size,modified_at,etag,total_count',
                                      offset=0, limit=1000)

        aiohttpretty.register_json_uri('GET', list_url, body=list_metadata)
        aiohttpretty.register_json_uri('POST', file_url, body=item)

        expected_folder = BoxFolderMetadata(item, dest_path)
        expected_folder._children = []
        for child_item in list_metadata['entries']:
            child_path = dest_path.child(child_item['name'], folder=(child_item['type'] == 'folder'))
            serialized_child = provider._serialize_item(child_item, child_path)
            expected_folder._children.append(serialized_child)
        expected = (expected_folder, True)

        result = await provider.intra_copy(provider, src_path, dest_path)

        assert result == expected
예제 #12
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"])))

        assert result == expected
예제 #13
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'])))

        assert result == expected
    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
예제 #15
0
    async def revalidate_path(self,
                              base: wb_path.WaterButlerPath,
                              path: str,
                              folder: bool=False) -> wb_path.WaterButlerPath:
        """Take a path and a base path and build a WaterButlerPath representing `/base/path`.  For
        id-based providers, this will need to lookup the id of the new child object.

        :param  base: ( :class:`.WaterButlerPath` ) The base folder to look under
        :param path: ( :class:`str`) the path of a child of `base`, relative to `base`
        :param folder: ( :class:`bool` )whether the returned WaterButlerPath should represent a folder
        :rtype: :class:`.WaterButlerPath`
        """
        return base.child(path, folder=folder)
예제 #16
0
    async def revalidate_path(self,
                              base: wb_path.WaterButlerPath,
                              path: str,
                              folder: bool=False) -> wb_path.WaterButlerPath:
        """Take a path and a base path and build a WaterButlerPath representing `/base/path`.  For
        id-based providers, this will need to lookup the id of the new child object.

        :param  base: ( :class:`.WaterButlerPath` ) The base folder to look under
        :param path: ( :class:`str`) the path of a child of `base`, relative to `base`
        :param folder: ( :class:`bool` )whether the returned WaterButlerPath should represent a folder
        :rtype: :class:`.WaterButlerPath`
        """
        return base.child(path, folder=folder)
예제 #17
0
    async def _get_folder_meta(
            self,
            path: WaterButlerPath,
            raw: bool = False,
            folder: bool = False) -> Union[dict, List[BoxFolderMetadata]]:
        if folder:
            response = await self.make_request(
                'GET',
                self.build_url('folders', path.identifier),
                expects=(200, ),
                throws=exceptions.MetadataError,
            )
            data = await response.json()
            return data if raw else self._serialize_item(data, path)

        # Box maximum limit is 1000
        page_count, page_total, limit = 0, None, 1000
        full_resp = {} if raw else []  # type: ignore
        while page_total is None or page_count < page_total:
            url = self.build_url(
                'folders',
                path.identifier,
                'items',
                fields='id,name,size,modified_at,etag,total_count',
                offset=(page_count * limit),
                limit=limit)
            response = await self.make_request(
                'GET',
                url,
                expects=(200, ),
                throws=exceptions.MetadataError,
            )
            resp_json = await response.json()
            if raw:
                full_resp.update(resp_json)  # type: ignore
            else:
                full_resp.extend([  # type: ignore
                    self._serialize_item(
                        each,
                        path.child(each['name'],
                                   folder=(each['type'] == 'folder')))
                    for each in resp_json['entries']
                ])

            page_count += 1
            if page_total is None:
                page_total = (
                    (resp_json['total_count'] - 1) // limit) + 1  # ceiling div
        self.metrics.add('metadata.folder.pages', page_total)
        return full_resp
예제 #18
0
 async def _folder_metadata(self,
                            path: WaterButlerPath,
                            raw: bool=False) -> List[Union[BaseGoogleDriveMetadata, dict]]:
     query = self._build_query(path.identifier)
     built_url = self.build_url('files', q=query, alt='json', maxResults=1000)
     full_resp = []
     while built_url:
         async with self.request(
             'GET',
             built_url,
             expects=(200, ),
             throws=exceptions.MetadataError,
         ) as resp:
             resp_json = await resp.json()
             full_resp.extend([
                 self._serialize_item(path.child(item['title']), item, raw=raw)
                 for item in resp_json['items']
             ])
             built_url = resp_json.get('nextLink', None)
     return full_resp
예제 #19
0
    async def revalidate_path(self,
                              base: WaterButlerPath,
                              name: str,
                              folder: bool=None) -> WaterButlerPath:
        # TODO Redo the logic here folders names ending in /s
        # Will probably break
        if '/' in name.lstrip('/') and '%' not in name:
            # DAZ and MnC may pass unquoted names which break
            # if the name contains a / in it
            name = parse.quote(name.lstrip('/'), safe='')

        if not name.endswith('/') and folder:
            name += '/'

        parts = await self._resolve_path_to_ids(name, start_at=[{
            'title': base.name,
            'mimeType': 'folder',
            'id': base.identifier,
        }])
        _id, name, mime = list(map(parts[-1].__getitem__, ('id', 'title', 'mimeType')))
        return base.child(name, _id=_id, folder='folder' in mime)
예제 #20
0
    async def test_intra_copy_folder_replace(self, provider, intra_fixtures,
                                             root_provider_fixtures):
        item = intra_fixtures['intra_folder_metadata']
        list_metadata = root_provider_fixtures['folder_list_metadata']

        src_path = WaterButlerPath('/name/', _ids=(provider, item['id']))
        dest_path = WaterButlerPath('/charmander/name/',
                                    _ids=(provider, item['id'], item['id']))

        file_url = provider.build_url('folders', src_path.identifier, 'copy')
        delete_url = provider.build_url('folders',
                                        dest_path.identifier,
                                        recursive=True)
        list_url = provider.build_url(
            'folders',
            item['id'],
            'items',
            fields='id,name,size,modified_at,etag,total_count',
            offset=0,
            limit=1000)

        aiohttpretty.register_json_uri('GET', list_url, body=list_metadata)
        aiohttpretty.register_uri('DELETE', delete_url, status=204)
        aiohttpretty.register_json_uri('POST', file_url, body=item)

        expected_folder = BoxFolderMetadata(item, dest_path)
        expected_folder._children = []
        for child_item in list_metadata['entries']:
            child_path = dest_path.child(
                child_item['name'], folder=(child_item['type'] == 'folder'))
            serialized_child = provider._serialize_item(child_item, child_path)
            expected_folder._children.append(serialized_child)
        expected = (expected_folder, False)

        result = await provider.intra_copy(provider, src_path, dest_path)

        assert result == expected
        assert aiohttpretty.has_call(method='DELETE', uri=delete_url)
예제 #21
0
    async def _get_folder_meta(self, path: WaterButlerPath, raw: bool=False,
                               folder: bool=False) -> Union[dict, List[BoxFolderMetadata]]:
        if folder:
            async with self.request(
                'GET', self.build_url('folders', path.identifier),
                expects=(200, ), throws=exceptions.MetadataError,
            ) as resp:
                data = await resp.json()
                return data if raw else self._serialize_item(data, path)

        # Box maximum limit is 1000
        page_count, page_total, limit = 0, None, 1000
        full_resp = {} if raw else []  # type: ignore
        while page_total is None or page_count < page_total:
            url = self.build_url('folders', path.identifier, 'items',
                                 fields='id,name,size,modified_at,etag,total_count',
                                 offset=(page_count * limit),
                                 limit=limit)
            async with self.request('GET', url, expects=(200, ),
                                    throws=exceptions.MetadataError) as response:
                resp_json = await response.json()
                if raw:
                    full_resp.update(resp_json)  # type: ignore
                else:
                    full_resp.extend([  # type: ignore
                        self._serialize_item(
                            each, path.child(each['name'], folder=(each['type'] == 'folder'))
                        )
                        for each in resp_json['entries']
                    ])

                page_count += 1
                if page_total is None:
                    page_total = ((resp_json['total_count'] - 1) // limit) + 1  # ceiling div
        self.metrics.add('metadata.folder.pages', page_total)
        return full_resp
예제 #22
0
 def path_from_metadata(self,
                        parent_path: wb_path.WaterButlerPath,
                        meta_data: wb_metadata.BaseMetadata) -> wb_path.WaterButlerPath:
     return parent_path.child(meta_data.name, _id=meta_data.path.strip('/'),
                              folder=meta_data.is_folder)
예제 #23
0
 def path_from_metadata(self,
                        parent_path: wb_path.WaterButlerPath,
                        meta_data: wb_metadata.BaseMetadata) -> wb_path.WaterButlerPath:
     return parent_path.child(meta_data.name, _id=meta_data.path.strip('/'),
                              folder=meta_data.is_folder)
예제 #24
0
    def test_child(self):
        path = WaterButlerPath('/this/is/a/long/')

        assert path.name == 'long'
        assert path.child('path').name == 'path'