diff --git a/pubs/apis.py b/pubs/apis.py index 5fe06ce..cb1046f 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -1,12 +1,24 @@ """Interface for Remote Bibliographic APIs""" import requests +from bs4 import BeautifulSoup def doi2bibtex(doi): - """Return a bibtex string of metadata from a DOI""" + """Return a bibtex string of metadata from a DOI""" - url = 'http://dx.doi.org/{}'.format(doi) - headers = {'accept': 'application/x-bibtex'} - r = requests.get(url, headers=headers) + url = 'http://dx.doi.org/{}'.format(doi) + headers = {'accept': 'application/x-bibtex'} + r = requests.get(url, headers=headers) + + return r.text + +def isbn2bibtex(isbn): + """Return a bibtex string of metadata from a DOI""" + + url = 'http://www.ottobib.com/isbn/{}/bibtex'.format(isbn) + r = requests.get(url) + soup = BeautifulSoup(r.text) + citation = soup.find("textarea").text + + return citation - return r.text diff --git a/pubs/commands/add_cmd.py b/pubs/commands/add_cmd.py index f7c371c..39d0b0c 100644 --- a/pubs/commands/add_cmd.py +++ b/pubs/commands/add_cmd.py @@ -15,15 +15,14 @@ def parser(subparsers): 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) + parser.add_argument('-I', '--isbn', help='isbn number 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) parser.add_argument('-k', '--citekey', help='citekey associated with the paper;\nif not provided, one will be generated automatically.', default=None) - parser.add_argument('-c', '--copy', action='store_true', default=True, - help="copy document files into library directory (default)") - parser.add_argument('-C', '--nocopy', action='store_false', dest='copy', - help="don't copy document files (opposite of -c)") + parser.add_argument('-L', '--link', action='store_false', dest='copy', default=True, + help="don't copy document files, just create a link.") return parser @@ -71,14 +70,22 @@ def command(args): # get bibtex entry if bibfile is None: - if args.doi is None: + if args.doi is None and args.isbn is None: bibdata = bibdata_from_editor(ui, rp) else: - bibdata_raw = apis.doi2bibtex(args.doi) - bibdata = rp.databroker.verify(bibdata_raw) - if bibdata is None: - ui.error('invalid doi {} or unable to retrieve bibfile.'.format(args.doi)) - ui.exit(1) + if args.doi is not None: + bibdata_raw = apis.doi2bibtex(args.doi) + bibdata = rp.databroker.verify(bibdata_raw) + if bibdata is None: + ui.error('invalid doi {} or unable to retrieve bibfile from it.'.format(args.doi)) + if args.isbn is None: + ui.exit(1) + if args.isbn is not None: + bibdata_raw = apis.isbn2bibtex(args.isbn) + bibdata = rp.databroker.verify(bibdata_raw) + if bibdata is None: + ui.error('invalid isbn {} or unable to retrieve bibfile from it.'.format(args.isbn)) + ui.exit(1) # TODO distinguish between cases, offer to open the error page in a webbrowser. # TODO offer to confirm/change citekey else: diff --git a/pubs/commands/import_cmd.py b/pubs/commands/import_cmd.py index 98f909a..bf331d0 100644 --- a/pubs/commands/import_cmd.py +++ b/pubs/commands/import_cmd.py @@ -16,10 +16,8 @@ def parser(subparsers): help='import paper(s) to the repository') parser.add_argument('bibpath', help='path to bibtex, bibtexml or bibyaml file (or directory)') - parser.add_argument('-c', '--copy', action='store_true', default=None, - help="copy document files into library directory (default)") - parser.add_argument('-C', '--nocopy', action='store_false', dest='copy', - help="don't copy document files (opposite of -c)") + parser.add_argument('-L', '--link', action='store_false', dest='copy', default=True, + help="don't copy document files, just create a link.") parser.add_argument('keys', nargs='*', help="one or several keys to import from the file") return parser diff --git a/pubs/paper.py b/pubs/paper.py index 5abc3be..c137ce2 100644 --- a/pubs/paper.py +++ b/pubs/paper.py @@ -38,6 +38,9 @@ class Paper(object): if self.citekey is None: self.citekey = bibstruct.extract_citekey(self.bibdata) bibstruct.check_citekey(self.citekey) + else: + def_citekey = bibstruct.extract_citekey(self.bibdata) + self.bibdata = {citekey: self.bibdata[def_citekey]} def __eq__(self, other): return (isinstance(self, Paper) and type(other) is type(self) diff --git a/pubs/utils.py b/pubs/utils.py index de6497b..5e05982 100644 --- a/pubs/utils.py +++ b/pubs/utils.py @@ -1,6 +1,7 @@ # Function here may belong somewhere else. In the mean time... from . import color +from . import pretty def resolve_citekey(repo, citekey, ui=None, exit_on_fail=True): """Check that a citekey exists, or autocompletes it if not ambiguous.""" @@ -18,8 +19,12 @@ def resolve_citekey(repo, citekey, ui=None, exit_on_fail=True): citekey = citekeys[0] elif citekey not in citekeys: if ui is not None: - ui.error("be more specific; provided citekey '{}' matches multiples citekeys: {}".format( - citekey, ', '.join(color.dye(citekey, color.citekey) for citekey in citekeys))) + citekeys = sorted(citekeys) + ui.error("be more specific; provided citekey '{}' matches multiples citekeys:".format( + citekey)) + for c in citekeys: + p = repo.pull_paper(c) + ui.print_(u' {}'.format(pretty.paper_oneliner(p))) if exit_on_fail: ui.exit() return citekey