def import_article(identifier): """Import a new article from arXiv or Crossref based on the identifier. This function attempts to parse and normalize the identifier as a valid arXiv id or DOI. If the identifier is valid and there is no record in Inspire matching the ID, it queries the arXiv/CrossRef APIs and parses the record to make it inspire compliant. Args: identifier(str): the ID of the record to import Returns: dict: the serialized article Raises: ExistingArticleError: if the record is already in Inspire. ImportArticleError: if no article is found. ImportConnectionError: if the importing request fails. ImportParsingError: if an error occurs while parsing the result. UnknownIdentifierError: if the identifier is neither "arxiv" or "doi". """ if is_arxiv(identifier): pid_type = "arxiv" pid_value = normalize_arxiv(identifier) elif is_doi(identifier): pid_type = "doi" pid_value = normalize_doi(identifier) else: raise UnknownImportIdentifierError(identifier) pid = PersistentIdentifier.query.filter_by( pid_type=pid_type, pid_value=pid_value).one_or_none() if pid: raise ExistingArticleError( f"Article {identifier} already in Inspire. UUID: {pid.object_uuid}" ) importers = {"arxiv": import_arxiv, "doi": import_doi} importer = importers.get(pid_type, UnknownImportIdentifierError) article = importer(pid_value) if not article: raise ImportArticleError(f"No article found for {identifier}") if pid_type == "arxiv": article = merge_article_with_crossref_data(article) return article
def import_article(identifier): """Import a new article from arXiv or Crossref based on the identifier. This function attempts to parse and normalize the identifier as a valid arXiv id or DOI. If the identifier is valid and there is no record in Inspire matching the ID, it queries the arXiv/CrossRef APIs and parses the record to make it inspire compliant. Args: identifier(str): the ID of the record to import Returns: dict: the serialized article Raises: ExistingArticleError: if the record is already in Inspire. ImportArticleNotFoundError: if no article is found. ImportParsingError: if an error occurs while parsing the result. UnknownIdentifierError: if the identifier is neither "arxiv" or "doi". """ if is_arxiv(identifier): pid_type = "arxiv" pid_value = normalize_arxiv(identifier) elif is_doi(identifier): pid_type = "doi" pid_value = normalize_doi(identifier).lower() else: raise UnknownImportIdentifierError(identifier) recid = get_pid_for_pid(pid_type, pid_value, provider="recid") if recid: raise ExistingArticleError( f"The article {identifier} already exists in Inspire", recid) importers = {"arxiv": import_arxiv, "doi": import_doi} importer = importers.get(pid_type, UnknownImportIdentifierError) article = importer(pid_value) if not article: raise ImportArticleNotFoundError(f"No article found for {identifier}") if pid_type == "arxiv": article = merge_article_with_crossref_data(article) return article
def test_is_arxiv_accepts_valid_categories_only(): assert utils.is_arxiv('math/0312.059758') is False
def test_is_arxiv_accepts_valid_categories_only(): assert utils.is_arxiv('math.ACS/0312059') is False
def test_is_arxiv_accepts_valid_categories_only(): assert utils.is_arxiv('CBO/9780511') is False
def test_is_arxiv_handles_uppercase_with_cls(): assert utils.is_arxiv('MatH.AC/0312059')
def test_is_arxiv_handles_uppercase(): assert utils.is_arxiv('MATH/0312059')
def test_is_arxiv_new_with_class_wo_prefix(): assert utils.is_arxiv('hep-th/1601.07616')
def test_is_arxiv_new_with_class(): assert utils.is_arxiv('arXiv:hep-th/1601.07616')
def test_is_arxiv_old_identifier(): assert utils.is_arxiv('hep-th/0603001')
def test_is_arxiv_new_identifier(): assert utils.is_arxiv('arXiv:1501.00001v1')
def test_is_arxiv_accepts_valid_category_in_brackets(): assert utils.is_arxiv('arXiv:1406.1599v2[physics.ins-det]')