From d6ab091e5c7ead3f011b494d99ccd6ec1ce12817 Mon Sep 17 00:00:00 2001 From: "J. Antognini" Date: Sun, 5 Aug 2018 00:00:20 -0700 Subject: [PATCH] Only allow one of doi, arxiv, or isbn to pubs_add Also includes some minor refactoring. --- pubs/apis.py | 41 +++++++++++++++++++++++++++++++++++++++- pubs/commands/add_cmd.py | 25 +++++++----------------- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/pubs/apis.py b/pubs/apis.py index 82cb8f1..014217f 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -11,6 +11,45 @@ class ReferenceNotFoundException(Exception): pass +def get_bibentry_from_api(id_str, id_type, rp): + """Return a bibtex string from various ID methods. + + This is a wrapper around functions that will return a bibtex string given + one of: + + * DOI + * IBSN + * arXiv ID + + Args: + id_str: A string with the ID. + id_type: Name of the ID type. Must be one of `doi`, `isbn`, or `arxiv`. + rp: A `Repository` object. + + Returns: + A bibtex string. + + Raises: + ValueError: if `id_type` is not one of `doi`, `isbn`, or `arxiv`. + """ + + id_fns = { + 'doi': doi2bibtex, + 'isbn': isbn2bibtex, + 'arxiv': arxiv2bibtex, + } + + if id_type not in id_fns.keys(): + raise ValueError('id_type must be one of `doi`, `isbn`, or `arxiv`.') + + bibentry_raw = id_fns[id_type](id_str) + bibentry = rp.databroker.verify(bibentry_raw) + if bibentry is None: + raise ReferenceNotFoundException( + 'invalid {} {} or unable to retrieve bibfile from it.'.format(id_type, id_str)) + return bibentry + + def doi2bibtex(doi): """Return a bibtex string of metadata from a DOI""" @@ -52,7 +91,7 @@ def arxiv2bibtex(arxiv_id): author_str = ' and '.join( [author['name'] for author in entry['authors']]) db.entries = [{ - 'ENTRYTYPE': 'misc', + 'ENTRYTYPE': 'article', 'ID': arxiv_id, 'author': author_str, 'title': entry['title'], diff --git a/pubs/commands/add_cmd.py b/pubs/commands/add_cmd.py index e3632f4..3ae8f70 100644 --- a/pubs/commands/add_cmd.py +++ b/pubs/commands/add_cmd.py @@ -26,9 +26,10 @@ def parser(subparsers, conf): parser = subparsers.add_parser('add', help='add a paper to the repository') parser.add_argument('bibfile', nargs='?', default=None, help='bibtex file') - parser.add_argument('-D', '--doi', help='doi number to retrieve the bibtex entry, if it is not provided', default=None, action=ValidateDOI) - parser.add_argument('-I', '--isbn', help='isbn number to retrieve the bibtex entry, if it is not provided', default=None) - parser.add_argument('-X', '--arxiv', help='arXiv ID to retrieve the bibtex entry, if it is not provided', default=None) + id_arg = parser.add_mutually_exclusive_group() + id_arg.add_argument('-D', '--doi', help='doi number to retrieve the bibtex entry, if it is not provided', default=None, action=ValidateDOI) + id_arg.add_argument('-I', '--isbn', help='isbn number to retrieve the bibtex entry, if it is not provided', default=None) + id_arg.add_argument('-X', '--arxiv', help='arXiv ID to retrieve the bibtex entry, if it is not provided', default=None) parser.add_argument('-d', '--docfile', help='pdf or ps file', default=None) parser.add_argument('-t', '--tags', help='tags associated to the paper, separated by commas', default=None @@ -92,25 +93,13 @@ def command(conf, args): bibentry = None try: if args.doi is not None: - bibentry_raw = apis.doi2bibtex(args.doi) - bibentry = rp.databroker.verify(bibentry_raw) - if bibentry is None: - raise apis.ReferenceNotFoundException( - 'invalid doi {} or unable to retrieve bibfile from it.'.format(args.doi)) + bibentry = apis.get_bibentry_from_api(args.doi, 'doi', rp) elif args.isbn is not None: - bibentry_raw = apis.isbn2bibtex(args.isbn) - bibentry = rp.databroker.verify(bibentry_raw) - if bibentry is None: - raise apis.ReferenceNotFoundException( - 'invalid isbn {} or unable to retrieve bibfile from it.'.format(args.isbn)) + bibentry = apis.get_bibentry_from_api(args.isbn, 'isbn', rp) # TODO distinguish between cases, offer to open the error page in a webbrowser. # TODO offer to confirm/change citekey elif args.arxiv is not None: - bibentry_raw = apis.arxiv2bibtex(args.arxiv) - bibentry = rp.databroker.verify(bibentry_raw) - if bibentry is None: - raise apis.ReferenceNotFoundException( - 'invalid arxiv id {} or unable to retrieve bibfile from it.'.format(args.arxiv_id)) + bibentry = apis.get_bibentry_from_api(args.arxiv, 'arxiv', rp) except apis.ReferenceNotFoundException as e: ui.error(e.message) ui.exit(1)