def test_project_article_file(self, project_provider, list_project_articles, article_metadata, file_metadata): file_id = file_metadata['id'] article_id = str(list_project_articles[0]['id']) article_metadata_url = project_provider.build_url( 'articles', article_id) list_articles_url = project_provider.build_url( 'projects', project_provider.project_id, 'articles') aiohttpretty.register_json_uri('GET', list_articles_url, body=list_project_articles) aiohttpretty.register_json_uri('GET', article_metadata_url, body=article_metadata) path = yield from project_provider.validate_path('/{}/{}'.format( article_id, file_id)) result = yield from project_provider.metadata(path) expected = metadata.FigshareFileMetadata( file_metadata, parent=article_metadata['items'][0], child=True).serialized() assert result == expected
def test_project_article_upload(self, project_provider, list_project_articles, article_metadata, upload_metadata, file_content, file_stream): article_id = str(list_project_articles[0]['id']) list_articles_url = project_provider.build_url( 'projects', project_provider.project_id, 'articles') article_metadata_url = project_provider.build_url( 'articles', article_id) article_upload_url = project_provider.build_url( 'articles', article_id, 'files') aiohttpretty.register_json_uri('GET', list_articles_url, body=list_project_articles) aiohttpretty.register_json_uri('GET', article_metadata_url, body=article_metadata) aiohttpretty.register_json_uri('PUT', article_upload_url, body=upload_metadata) file_name = 'barricade.gif' path = yield from project_provider.validate_path('/{}/{}'.format( article_id, file_name)) result, created = yield from project_provider.upload(file_stream, path) expected = metadata.FigshareFileMetadata( upload_metadata, parent=article_metadata['items'][0], child=True).serialized() assert aiohttpretty.has_call(method='PUT', uri=article_upload_url) assert result == expected
async def metadata(self, path, **kwargs): """Return metadata for entity identified by ``path`` under the parent project. :param FigsharePath path: entity whose metadata will be returned :rtype: FigshareFileMetadata obj or list of Metadata objs """ if path.is_root: path.is_public = False contents = await asyncio.gather(*[ # TODO: collections may need to use each['url'] for correct URN # Use _get_url_super ? figshare API needs to get fixed first. self._get_article_metadata(str(each['id']), path.is_public) for each in await self._get_all_articles() ]) return [each for each in contents if each] if not path.parts[-1].identifier: raise exceptions.NotFoundError(str(path)) if len(path.parts) > 3: raise exceptions.NotFoundError(str(path)) article_response = await self.make_request( 'GET', self.build_url(path.is_public, *self.root_path_parts, 'articles', path.parts[1].identifier), expects=(200, 404), ) if article_response.status == 404: raise exceptions.NotFoundError(str(path)) article_json = await article_response.json() if len(path.parts) == 2: if article_json['defined_type'] not in settings.FOLDER_TYPES: raise exceptions.NotFoundError(str(path)) contents = [] for file in article_json['files']: contents.append( metadata.FigshareFileMetadata(article_json, raw_file=file)) return contents elif len(path.parts) == 3: for file in article_json['files']: if file['id'] == int(path.parts[2].identifier): return metadata.FigshareFileMetadata(article_json, raw_file=file) raise exceptions.NotFoundError(path.path) else: raise exceptions.NotFoundError( '{} is not a valid path.'.format(path))
async def metadata(self, path, **kwargs): """Return metadata for entity identified by ``path``. May be the containing article or a file in a fileset article. :param FigsharePath path: entity whose metadata will be returned :rtype FigshareFileMetadata obj or list of Metadata objs: """ article = await self._get_article(not path.is_public) if path.is_root: # list files in article contents = [] for file in article['files']: contents.append(metadata.FigshareFileMetadata(article, raw_file=file)) return contents elif len(path.parts) == 2: # metadata for a particular file for file in article['files']: if str(file['id']) == path.parts[1].identifier: return metadata.FigshareFileMetadata(article, raw_file=file) # Invalid path, e.g. /422313/67709/1234 raise exceptions.NotFoundError(str(path))
def upload(self, stream, path, **kwargs): article_json = yield from self._get_article_json() stream = streams.FormDataStream(filedata=(stream, path.name)) response = yield from self.make_request( 'PUT', self.build_url('articles', self.article_id, 'files'), data=stream, expects=(200, ), headers=stream.headers, ) data = yield from response.json() return metadata.FigshareFileMetadata( data, parent=article_json, child=self.child).serialized(), True
async def test_project_upload(self, project_provider, list_project_articles, base_article_metadata, article_metadata, upload_metadata, file_content, file_stream): article_id = str(list_project_articles[0]['id']) list_articles_url = project_provider.build_url( 'projects', project_provider.project_id, 'articles') article_metadata_url = project_provider.build_url( 'articles', article_id) article_upload_url = project_provider.build_url( 'articles', article_id, 'files') create_article_url = project_provider.build_url('articles') add_article_url = project_provider.build_url( 'projects', project_provider.project_id, 'articles') aiohttpretty.register_json_uri('GET', list_articles_url, body=list_project_articles) aiohttpretty.register_json_uri('GET', article_metadata_url, body=article_metadata) aiohttpretty.register_json_uri('PUT', article_upload_url, body=upload_metadata) aiohttpretty.register_json_uri('POST', create_article_url, body=base_article_metadata) aiohttpretty.register_json_uri('PUT', add_article_url) file_name = 'barricade.gif' path = await project_provider.validate_path('/' + file_name) result, created = await project_provider.upload(file_stream, path) expected = metadata.FigshareFileMetadata( upload_metadata, parent=base_article_metadata, child=True, ) assert aiohttpretty.has_call(method='POST', uri=create_article_url, data=json.dumps({ 'title': 'barricade.gif', 'defined_type': 'dataset', })) assert aiohttpretty.has_call(method='PUT', uri=article_upload_url) assert aiohttpretty.has_call(method='PUT', uri=add_article_url, data=json.dumps( {'article_id': int(article_id)})) assert result == expected
async def _get_article_metadata(self, article_id, is_public: bool): """Return Figshare*Metadata object for given article_id. Returns a FolderMetadata object for filesets, a FileMetadat object for other article types, and ``None`` if the article is not a fileset and has no files attached. Defined separately to allow for taking advantage of ``asyncio.gather``. :param str article_id: id of article whose metadata is requested :param bool is_public: ``True`` if article is accessed through public URN """ response = await self.make_request( 'GET', self.build_url(is_public, *self.root_path_parts, 'articles', article_id), expects=(200, ), ) article_json = await response.json() if article_json['defined_type'] in settings.FOLDER_TYPES: return metadata.FigshareFolderMetadata(article_json) elif article_json['files']: return metadata.FigshareFileMetadata(article_json) return None # article without attached file