From f3c83668f9b1689a166c6e8b0e1ebb4bd75a8d79 Mon Sep 17 00:00:00 2001 From: Joe Antognini Date: Mon, 23 Jul 2018 18:23:36 -0600 Subject: [PATCH 01/20] Allow bibtex to be added from arxiv id. This allows the user to add a reference via an arXiv ID similarly to how a reference can be added from a DOI or ISBN. If the arXiv ID has a DOI associated with it (according to the arXiv server), the DOI will be used. If it does not (perhaps the paper is unpublished), then a bibtex entry will automatically be generated from the reference's metadata. Note that a potential issue with this addition is that if a paper is added before it is published (i.e., there is no DOI associated with it), and the paper is later published, the updated information will have to be manually added. --- pubs/apis.py | 31 +++++++++++++++++++++++++++++++ pubs/commands/add_cmd.py | 25 ++++++++++++++++++++++--- requirements.txt | 1 + tests/test_apis.py | 27 ++++++++++++++++++++++++++- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/pubs/apis.py b/pubs/apis.py index 0812ba5..a627cf5 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -1,7 +1,9 @@ """Interface for Remote Bibliographic APIs""" import requests +import feedparser from bs4 import BeautifulSoup +from uis import get_ui def doi2bibtex(doi): @@ -25,3 +27,32 @@ def isbn2bibtex(isbn): citation = soup.find("textarea").text return citation + + +def arxiv2bibtex(arxiv_id): + """Return a bibtex string of metadata from an arXiv ID""" + + url = 'https://export.arxiv.org/api/query?id_list=' + arxiv_id + r = requests.get(url) + feed = feedparser.parse(r.text) + entry = feed.entries[0] + + if 'title' not in entry: + ui = get_ui() + ui.error('malformed arXiv ID: {}'.format(arxiv_id)) + if 'arxiv_doi' in entry: + return doi2bibtex(entry['arxiv_doi']) + else: + # Create a bibentry from the metadata. + bibtext = '@misc{{{},\n'.format(arxiv_id) + bibtext += 'Author = {' + for i, author in enumerate(entry['authors']): + bibtext += author['name'] + if i < len(entry['authors']) - 1: + bibtext += ' and ' + bibtext += '},\n' + bibtext += 'Title = {{{}}},\n'.format(entry['title'].strip('\n')) + bibtext += 'Year = {{{}}},\n'.format(entry['published_parsed'].tm_year) + bibtext += 'Eprint = {{arXiv:{}}},\n'.format(arxiv_id) + bibtext += '}' + return bibtext diff --git a/pubs/commands/add_cmd.py b/pubs/commands/add_cmd.py index a22c0a5..d4031f6 100644 --- a/pubs/commands/add_cmd.py +++ b/pubs/commands/add_cmd.py @@ -27,6 +27,7 @@ def parser(subparsers, conf): 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) 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 @@ -67,6 +68,19 @@ def bibentry_from_editor(conf, ui, rp): return bibentry +def api_call(fn, arg): + """Calls the appropriate API command. + + :param fn: The API function to call. + :param arg: The argument to give the API call. + """ + bibentry_raw = fn(arg) + bibentry = rp.databroker.verify(bibentry_raw) + return bibentry + if bibentry is None: + ui.error('invalid doi {} or unable to retrieve bibfile from it.'.format(args.doi)) + + def command(conf, args): """ :param bibfile: bibtex file (in .bib, .bibml or .yaml format. @@ -86,21 +100,26 @@ def command(conf, args): if args.doi is None and args.isbn is None: bibentry = bibentry_from_editor(conf, ui, rp) else: + bibentry = None if args.doi is not None: bibentry_raw = apis.doi2bibtex(args.doi) bibentry = rp.databroker.verify(bibentry_raw) if bibentry 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: bibentry_raw = apis.isbn2bibtex(args.isbn) bibentry = rp.databroker.verify(bibentry_raw) if bibentry 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 + if args.arxiv is not None: + bibentry_raw = apis.arxiv2bibtex(args.arxiv) + bibentry = rp.databroker.verify(bibentry_raw) + if bibentry is None: + ui.error('invalid arxiv id {} or unable to retrieve bibfile from it.'.format(args.arxiv_id)) + if bibentry is None: + ui.exit(1) else: bibentry_raw = content.get_content(bibfile, ui=ui) bibentry = rp.databroker.verify(bibentry_raw) diff --git a/requirements.txt b/requirements.txt index 4e10580..da1abec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ python-dateutil requests configobj beautifulsoup4 +feedparser diff --git a/tests/test_apis.py b/tests/test_apis.py index 087f32f..8c2017c 100644 --- a/tests/test_apis.py +++ b/tests/test_apis.py @@ -7,7 +7,7 @@ import dotdot from pubs.p3 import ustr from pubs.endecoder import EnDecoder -from pubs.apis import doi2bibtex, isbn2bibtex +from pubs.apis import arxiv2bibtex, doi2bibtex, isbn2bibtex class TestDOI2Bibtex(unittest.TestCase): @@ -60,5 +60,30 @@ class TestISBN2Bibtex(unittest.TestCase): self.endecoder.decode_bibdata(bib) +class TestArxiv2Bibtex(unittest.TestCase): + + def setUp(self): + self.endecoder = EnDecoder() + + def test_parses_to_bibtex_with_doi(self): + bib = arxiv2bibtex('astro-ph/9812133') + b = self.endecoder.decode_bibdata(bib) + self.assertEqual(len(b), 1) + entry = b[list(b)[0]] + self.assertEqual(entry['author'][0], 'Perlmutter, S.') + self.assertEqual(entry['year'], '1999') + + def test_parses_to_bibtex_without_doi(self): + bib = arxiv2bibtex('math/0211159') + b = self.endecoder.decode_bibdata(bib) + self.assertEqual(len(b), 1) + entry = b[list(b)[0]] + self.assertEqual(entry['author'][0], 'Perelman, Grisha') + self.assertEqual(entry['year'], '2002') + self.assertEqual( + entry['title'], + 'The entropy formula for the Ricci flow and its geometric applications') + + # Note: apparently ottobib.com uses caracter modifiers for accents instead # of the correct unicode characters. TODO: Should we convert them? From 35f209a98a09a4afacce1a5feff0421e5b4428e0 Mon Sep 17 00:00:00 2001 From: Joe Antognini Date: Mon, 23 Jul 2018 23:33:05 -0700 Subject: [PATCH 02/20] Remove unnecessary function from earlier commit. --- pubs/commands/add_cmd.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pubs/commands/add_cmd.py b/pubs/commands/add_cmd.py index d4031f6..74522b0 100644 --- a/pubs/commands/add_cmd.py +++ b/pubs/commands/add_cmd.py @@ -68,19 +68,6 @@ def bibentry_from_editor(conf, ui, rp): return bibentry -def api_call(fn, arg): - """Calls the appropriate API command. - - :param fn: The API function to call. - :param arg: The argument to give the API call. - """ - bibentry_raw = fn(arg) - bibentry = rp.databroker.verify(bibentry_raw) - return bibentry - if bibentry is None: - ui.error('invalid doi {} or unable to retrieve bibfile from it.'.format(args.doi)) - - def command(conf, args): """ :param bibfile: bibtex file (in .bib, .bibml or .yaml format. From 30f5f86c9d7f7ebd496442325ccee8ccdc09283c Mon Sep 17 00:00:00 2001 From: Joe Antognini Date: Mon, 23 Jul 2018 23:37:12 -0700 Subject: [PATCH 03/20] Don't immediately exit on malformed arxiv id. To be consistent with errors in other uses of `pubs add`, we only exit when the returned bibentry is None. --- pubs/apis.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/pubs/apis.py b/pubs/apis.py index a627cf5..aa04fb9 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -40,19 +40,20 @@ def arxiv2bibtex(arxiv_id): if 'title' not in entry: ui = get_ui() ui.error('malformed arXiv ID: {}'.format(arxiv_id)) - if 'arxiv_doi' in entry: - return doi2bibtex(entry['arxiv_doi']) + bibtex = None + elif 'arxiv_doi' in entry: + bibtex = doi2bibtex(entry['arxiv_doi']) else: # Create a bibentry from the metadata. - bibtext = '@misc{{{},\n'.format(arxiv_id) - bibtext += 'Author = {' + bibtex = '@misc{{{},\n'.format(arxiv_id) + bibtex += 'Author = {' for i, author in enumerate(entry['authors']): - bibtext += author['name'] + bibtex += author['name'] if i < len(entry['authors']) - 1: - bibtext += ' and ' - bibtext += '},\n' - bibtext += 'Title = {{{}}},\n'.format(entry['title'].strip('\n')) - bibtext += 'Year = {{{}}},\n'.format(entry['published_parsed'].tm_year) - bibtext += 'Eprint = {{arXiv:{}}},\n'.format(arxiv_id) - bibtext += '}' - return bibtext + bibtex += ' and ' + bibtex += '},\n' + bibtex += 'Title = {{{}}},\n'.format(entry['title'].strip('\n')) + bibtex += 'Year = {{{}}},\n'.format(entry['published_parsed'].tm_year) + bibtex += 'Eprint = {{arXiv:{}}},\n'.format(arxiv_id) + bibtex += '}' + return bibtex From ccdbe72eb7bffa11c8cc8e9d5377ec519ce43486 Mon Sep 17 00:00:00 2001 From: "J. Antognini" Date: Sat, 28 Jul 2018 22:37:14 -0700 Subject: [PATCH 04/20] Address omangin's code review. * This fixes the logic in the `pubs add` command so that an arxiv ID doesn't overwrite a DOI. This also changes the logic so that if an invalid DOI, ISBN, or arXiv ID is provided the program will raise an error. * The code now uses the bibtexparser package to generate the bibtex file for arxiv papers. * A dedicated exception is added for references that can't be found. --- pubs/apis.py | 34 +++++++++++++++++-------------- pubs/commands/add_cmd.py | 43 ++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/pubs/apis.py b/pubs/apis.py index aa04fb9..82cb8f1 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -1,9 +1,14 @@ """Interface for Remote Bibliographic APIs""" import requests +import bibtexparser +from bibtexparser.bibdatabase import BibDatabase import feedparser from bs4 import BeautifulSoup -from uis import get_ui + + +class ReferenceNotFoundException(Exception): + pass def doi2bibtex(doi): @@ -38,22 +43,21 @@ def arxiv2bibtex(arxiv_id): entry = feed.entries[0] if 'title' not in entry: - ui = get_ui() - ui.error('malformed arXiv ID: {}'.format(arxiv_id)) - bibtex = None + raise ReferenceNotFoundException('arXiv ID not found.') elif 'arxiv_doi' in entry: bibtex = doi2bibtex(entry['arxiv_doi']) else: # Create a bibentry from the metadata. - bibtex = '@misc{{{},\n'.format(arxiv_id) - bibtex += 'Author = {' - for i, author in enumerate(entry['authors']): - bibtex += author['name'] - if i < len(entry['authors']) - 1: - bibtex += ' and ' - bibtex += '},\n' - bibtex += 'Title = {{{}}},\n'.format(entry['title'].strip('\n')) - bibtex += 'Year = {{{}}},\n'.format(entry['published_parsed'].tm_year) - bibtex += 'Eprint = {{arXiv:{}}},\n'.format(arxiv_id) - bibtex += '}' + db = BibDatabase() + author_str = ' and '.join( + [author['name'] for author in entry['authors']]) + db.entries = [{ + 'ENTRYTYPE': 'misc', + 'ID': arxiv_id, + 'author': author_str, + 'title': entry['title'], + 'year': str(entry['published_parsed'].tm_year), + 'Eprint': arxiv_id, + }] + bibtex = bibtexparser.dumps(db) return bibtex diff --git a/pubs/commands/add_cmd.py b/pubs/commands/add_cmd.py index 74522b0..4930b6b 100644 --- a/pubs/commands/add_cmd.py +++ b/pubs/commands/add_cmd.py @@ -84,28 +84,33 @@ def command(conf, args): # get bibtex entry if bibfile is None: - if args.doi is None and args.isbn is None: + if args.doi is None and args.isbn is None and args.arxiv is None: bibentry = bibentry_from_editor(conf, ui, rp) else: bibentry = None - if args.doi is not None: - bibentry_raw = apis.doi2bibtex(args.doi) - bibentry = rp.databroker.verify(bibentry_raw) - if bibentry is None: - ui.error('invalid doi {} or unable to retrieve bibfile from it.'.format(args.doi)) - if args.isbn is not None: - bibentry_raw = apis.isbn2bibtex(args.isbn) - bibentry = rp.databroker.verify(bibentry_raw) - if bibentry is None: - ui.error('invalid isbn {} or unable to retrieve bibfile from it.'.format(args.isbn)) - # TODO distinguish between cases, offer to open the error page in a webbrowser. - # TODO offer to confirm/change citekey - if args.arxiv is not None: - bibentry_raw = apis.arxiv2bibtex(args.arxiv) - bibentry = rp.databroker.verify(bibentry_raw) - if bibentry is None: - ui.error('invalid arxiv id {} or unable to retrieve bibfile from it.'.format(args.arxiv_id)) - if bibentry is 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)) + 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)) + # 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)) + except apis.ReferenceNotFoundException as e: + ui.error(e.message) ui.exit(1) else: bibentry_raw = content.get_content(bibfile, ui=ui) From d6ab091e5c7ead3f011b494d99ccd6ec1ce12817 Mon Sep 17 00:00:00 2001 From: "J. Antognini" Date: Sun, 5 Aug 2018 00:00:20 -0700 Subject: [PATCH 05/20] 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) From bf46702374385a3e7923a0e75e908aa3ad08a44b Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Fri, 3 Aug 2018 17:26:16 +0900 Subject: [PATCH 06/20] pytest fixes pytest will automatically run/collect anything that begins with "test". Renamed a few thing to avoid false positive. --- tests/test_events.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/test_events.py b/tests/test_events.py index 32e0a4c..9834cfb 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -7,7 +7,7 @@ from pubs.events import Event _output = None -class TestEvent(Event): +class StringEvent(Event): def __init__(self, string): self.string = string @@ -34,20 +34,20 @@ class SpecificInfo(Info): self.specific = specific -@TestEvent.listen(12, 15) -def display(TestEventInstance, nb1, nb2): +@StringEvent.listen(12, 15) +def display(StringEventInstance, nb1, nb2): _output.append("%s %s %s" - % (TestEventInstance.string, nb1, nb2)) + % (StringEventInstance.string, nb1, nb2)) -@TestEvent.listen() -def hello_word(TestEventInstance): +@StringEvent.listen() +def hello_word(StringEventInstance): _output.append('Helloword') -@TestEvent.listen() -def print_it(TestEventInstance): - TestEventInstance.print_one() +@StringEvent.listen() +def print_it(StringEventInstance): + StringEventInstance.print_one() @AddEvent.listen() @@ -56,7 +56,7 @@ def do_it(AddEventInstance): @Info.listen() -def test_info_instance(infoevent): +def collect_info_instance(infoevent): _output.append(infoevent.info) if isinstance(infoevent, SpecificInfo): _output.append(infoevent.specific) @@ -68,9 +68,9 @@ class TestEvents(unittest.TestCase): global _output _output = [] - def test_listen_TestEvent(self): + def test_listen_StringEvent(self): # using the callback system - myevent = TestEvent('abcdefghijklmnopqrstuvwxyz') + myevent = StringEvent('abcdefghijklmnopqrstuvwxyz') myevent.send() # this one call three function correct = ['abcdefghijklmnopqrstuvwxyz 12 15', 'Helloword', From be253f9084fd4ca5f9fad0075cc15cdc6e78f4b1 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Sun, 5 Aug 2018 21:33:25 +0900 Subject: [PATCH 07/20] handling of arxiv errors --- pubs/apis.py | 157 +++++++++++++++++++++++++++++++++++++-------- setup.py | 2 +- tests/test_apis.py | 26 ++++++-- 3 files changed, 154 insertions(+), 31 deletions(-) diff --git a/pubs/apis.py b/pubs/apis.py index 014217f..5c30bf6 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -1,4 +1,6 @@ """Interface for Remote Bibliographic APIs""" +import re +import datetime import requests import bibtexparser @@ -7,7 +9,7 @@ import feedparser from bs4 import BeautifulSoup -class ReferenceNotFoundException(Exception): +class ReferenceNotFoundError(Exception): pass @@ -50,53 +52,156 @@ def get_bibentry_from_api(id_str, id_type, rp): return bibentry + +def _get_request(url, headers=None): + """GET requests to a url. Return the `requests` object. + + :raise ConnectionError: if anything goes bad (connection refused, timeout + http status error (401, 404, etc)). + """ + try: + r = requests.get(url, headers=headers) + r.raise_for_status() + return r + except requests.exceptions.RequestException as e: + raise ReferenceNotFoundError(e.args) + + + ## DOI support + def doi2bibtex(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) + r = _get_request(url, headers=headers) if r.encoding is None: r.encoding = 'utf8' # Do not rely on guessing from request return r.text + ## ISBN support + def isbn2bibtex(isbn): """Return a bibtex string of metadata from an ISBN""" url = 'http://www.ottobib.com/isbn/{}/bibtex'.format(isbn) - r = requests.get(url) + r = _get_request(url) soup = BeautifulSoup(r.text, "html.parser") citation = soup.find("textarea").text return citation + # Note: apparently ottobib.com uses caracter modifiers for accents instead + # of the correct unicode characters. TODO: Should we convert them? + + + ## arXiv support -def arxiv2bibtex(arxiv_id): - """Return a bibtex string of metadata from an arXiv ID""" +_months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', + 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'] - url = 'https://export.arxiv.org/api/query?id_list=' + arxiv_id - r = requests.get(url) +def _is_arxiv_oldstyle(arxiv_id): + return re.match(r"(arXiv\:)?[a-z\-]+\/[0-9]+(v[0-9]+)?", arxiv_id) is not None + +def _extract_arxiv_id(entry): + pattern = r"http[s]?://arxiv.org/abs/(?P.+)" + return re.search(pattern, entry['id']).groupdict()['entry_id'] + + +def arxiv2bibtex(arxiv_id, try_doi=True, ui=None): + """Return a bibtex string of metadata from an arXiv ID + + :param arxiv_id: arXiv id, with or without the `arXiv:` prefix and version + suffix (e.g. `v1`). Old an new style are accepted. Here are + example of accepted identifiers: `1510.00322`, + `arXiv:1510.00322`, `0901.0512`, `arXiv:0901.0512`, + `hep-ph/9409201` or `arXiv:hep-ph/9409201`. + Note that the `arXiv:` prefix will be automatically + removed, and the version suffix automatically added if + missing. + :param try_doi: if a DOI is referenced in the arXiv metadata, + try to download it instead. If that fails for any reason, + falls back to the arXiv, with a warning message, if the + UI is provided. + :param ui: if not None, will display a warning if the doi request + fails. + """ + ## handle errors + url = 'https://export.arxiv.org/api/query?id_list={}'.format(arxiv_id) + try: + r = requests.get(url) + if r.status_code == 400: # bad request + msg = ("the arXiv server returned a bad request error. The " + "arXiv id {} is possibly invalid or malformed.".format(arxiv_id)) + raise ReferenceNotFoundError(msg) + r.raise_for_status() # raise an exception for HTTP errors: + # 401, 404, 400 if `ui` is None, etc. + except requests.exceptions.RequestException as e: + msg = ("connection error while retrieving arXiv data for " + "'{}': {}".format(arxiv_id, e)) + raise ReferenceNotFoundError(msg) + + # print("TEXT = '{}'".format(r.text)) feed = feedparser.parse(r.text) - entry = feed.entries[0] + if len(feed.entries) == 0: # no results. + msg = "no results for arXiv id {}".format(arxiv_id) + raise ReferenceNotFoundError(msg) + if len(feed.entries) > 1: # I don't know how that could happen, but let's + # be ready for it. + results = '\n'.join('{}. {}'.format(i, entry['title']) + for entry in feed.entries) + msg = ("multiple results for arXiv id {}:\n{}\nThis is unexpected. " + "Please submit an issue at " + "https://github.com/pubs/pubs/issues").format(arxiv_id, choices) + raise ReferenceNotFoundError(msg) - if 'title' not in entry: - raise ReferenceNotFoundException('arXiv ID not found.') - elif 'arxiv_doi' in entry: - bibtex = doi2bibtex(entry['arxiv_doi']) - else: - # Create a bibentry from the metadata. - db = BibDatabase() - author_str = ' and '.join( - [author['name'] for author in entry['authors']]) - db.entries = [{ - 'ENTRYTYPE': 'article', - 'ID': arxiv_id, - 'author': author_str, - 'title': entry['title'], - 'year': str(entry['published_parsed'].tm_year), - 'Eprint': arxiv_id, - }] - bibtex = bibtexparser.dumps(db) + entry = feed.entries[0] + if 'arxiv.org/api/errors' in entry['id']: # server is returning an error message. + msg = 'the arXiv server returned an error message: {}'.format(entry['summary']) + raise ReferenceNotFoundError(msg) + # import pprint + # pprint.pprint(entry) + + + ## try to return a doi instead of the arXiv reference + if try_doi and 'arxiv_doi' in entry: + try: + return doi2bibtex(entry['arxiv_doi']) + except ReferenceNotFoundError as e: + if ui is not None: + ui.warning(str(e)) + + ## create a bibentry from the arXiv response. + db = BibDatabase() + entry_id = _extract_arxiv_id(entry) + author_str = ' and '.join( + [author['name'] for author in entry['authors']]) + db.entries = [{ + 'ENTRYTYPE': 'article', + 'ID': entry_id, + 'author': author_str, + 'title': entry['title'], + 'year': str(entry['published_parsed'].tm_year), + 'month': _months[entry['published_parsed'].tm_mon-1], + 'eprint': entry_id, + 'eprinttype': 'arxiv', + 'date': entry['published'], # not really standard, but a resolution more + # granular than months is increasinlgy relevant. + 'url': entry['link'], + 'urldate': datetime.datetime.utcnow().isoformat(timespec='seconds') + 'Z' # can't hurt. + }] + # we don't add eprintclass for old-style ids, as it is in the id already. + if not _is_arxiv_oldstyle(entry_id): + db.entries[0]['eprintclass'] = entry['arxiv_primary_category']['term'] + if 'arxiv_doi' in entry: + db.entries[0]['arxiv_doi'] = arxiv_doi + + bibtex = bibtexparser.dumps(db) return bibtex + +if __name__ == '__main__': + print(arxiv2bibtex("0704.0010")) + print(arxiv2bibtex("0704.010*")) +# print(arxiv2bibtex("quant-ph/0703266")) diff --git a/setup.py b/setup.py index 9e99694..e1fd8a9 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ setup( }, install_requires=['pyyaml', 'bibtexparser>=1.0', 'python-dateutil', - 'requests', 'configobj', 'beautifulsoup4'], + 'requests', 'configobj', 'beautifulsoup4', 'feedparser'], tests_require=['pyfakefs>=2.7', 'mock'], extras_require={'autocompletion': ['argcomplete'], }, diff --git a/tests/test_apis.py b/tests/test_apis.py index c2893cc..2df5289 100644 --- a/tests/test_apis.py +++ b/tests/test_apis.py @@ -7,7 +7,8 @@ import dotdot from pubs.p3 import ustr from pubs.endecoder import EnDecoder -from pubs.apis import arxiv2bibtex, doi2bibtex, isbn2bibtex +from pubs.apis import arxiv2bibtex, doi2bibtex, isbn2bibtex, _is_arxiv_oldstyle, _extract_arxiv_id + class TestDOI2Bibtex(unittest.TestCase): @@ -84,6 +85,23 @@ class TestArxiv2Bibtex(unittest.TestCase): entry['title'], 'The entropy formula for the Ricci flow and its geometric applications') - -# Note: apparently ottobib.com uses caracter modifiers for accents instead -# of the correct unicode characters. TODO: Should we convert them? + def test_oldstyle_pattern(self): + """Test that we can accurately differentiate between old and new style arXiv ids.""" + # old-style arXiv ids + for arxiv_id in ['cs/9301113', 'math/9201277v3', 'astro-ph/9812133', + 'cond-mat/0604612', 'hep-ph/0702007v10', 'arXiv:physics/9403001' + ]: + self.assertTrue(_is_arxiv_oldstyle(arxiv_id)) + # new-style arXiv ids + for arxiv_id in ['1808.00954', 'arXiv:1808.00953', '1808.0953', + '1808.00954v1', 'arXiv:1808.00953v2', '1808.0953v42']: + self.assertFalse(_is_arxiv_oldstyle(arxiv_id)) + + def test_extract_id(self): + """Test that ids are correctly extracted""" + self.assertEqual(_extract_arxiv_id({'id': "http://arxiv.org/abs/0704.0010v1"}), "0704.0010v1") + self.assertEqual(_extract_arxiv_id({'id': "https://arxiv.org/abs/0704.0010v1"}), "0704.0010v1") + self.assertEqual(_extract_arxiv_id({'id': "https://arxiv.org/abs/astro-ph/9812133v2"}), "astro-ph/9812133v2") + +if __name__ == '__main__': + unittest.main(verbosity=2) From 647fea8ddb75a6871991d779e7775d7566d388d1 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Sun, 5 Aug 2018 22:16:01 +0900 Subject: [PATCH 08/20] update doi fail test, fix isbn test --- tests/test_apis.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_apis.py b/tests/test_apis.py index 2df5289..2922016 100644 --- a/tests/test_apis.py +++ b/tests/test_apis.py @@ -7,8 +7,9 @@ import dotdot from pubs.p3 import ustr from pubs.endecoder import EnDecoder -from pubs.apis import arxiv2bibtex, doi2bibtex, isbn2bibtex, _is_arxiv_oldstyle, _extract_arxiv_id +from pubs.apis import ReferenceNotFoundError, arxiv2bibtex, doi2bibtex, isbn2bibtex, _is_arxiv_oldstyle, _extract_arxiv_id +from pubs import apis class TestDOI2Bibtex(unittest.TestCase): @@ -31,10 +32,9 @@ class TestDOI2Bibtex(unittest.TestCase): 'Über formal unentscheidbare Sätze der Principia ' 'Mathematica und verwandter Systeme I') - def test_parse_fails_on_incorrect_DOI(self): - bib = doi2bibtex('999999') - with self.assertRaises(EnDecoder.BibDecodingError): - self.endecoder.decode_bibdata(bib) + def test_retrieve_fails_on_incorrect_DOI(self): + with self.assertRaises(apis.ReferenceNotFoundError): + doi2bibtex('999999') class TestISBN2Bibtex(unittest.TestCase): @@ -55,8 +55,8 @@ class TestISBN2Bibtex(unittest.TestCase): self.assertEqual(entry['author'][0], 'Poincaré, Henri') self.assertEqual(entry['title'], 'La science et l\'hypothèse') - def test_parse_fails_on_incorrect_ISBN(self): - bib = doi2bibtex('9' * 13) + def test_retrieve_fails_on_incorrect_ISBN(self): + bib = isbn2bibtex('9' * 13) with self.assertRaises(EnDecoder.BibDecodingError): self.endecoder.decode_bibdata(bib) From 814ce1bde2e57b403a33f3ed5821e265a5e4c0ce Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Sun, 5 Aug 2018 22:19:56 +0900 Subject: [PATCH 09/20] remove timespec argument from isoformat (introduced in 3.6) --- pubs/apis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubs/apis.py b/pubs/apis.py index 5c30bf6..3d57ec9 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -190,7 +190,7 @@ def arxiv2bibtex(arxiv_id, try_doi=True, ui=None): 'date': entry['published'], # not really standard, but a resolution more # granular than months is increasinlgy relevant. 'url': entry['link'], - 'urldate': datetime.datetime.utcnow().isoformat(timespec='seconds') + 'Z' # can't hurt. + 'urldate': datetime.datetime.utcnow().isoformat() + 'Z' # can't hurt. }] # we don't add eprintclass for old-style ids, as it is in the id already. if not _is_arxiv_oldstyle(entry_id): From 938a53b8f59d8fd0222f327183d683bdce2fb85b Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Mon, 6 Aug 2018 11:20:39 +0900 Subject: [PATCH 10/20] python setup.py test + no connection case - Make `python setup.py test work`. remove test/requirements.txt. fix #154 - Detect if no connection is present, and skip tests if not. stop-gap measure for issue #147 --- .travis.yml | 4 +--- pubs/apis.py | 9 ++++++--- requirements.txt | 8 ++++++++ setup.py | 12 ++++++++++-- tests/requirements.txt | 5 ----- tests/test_apis.py | 33 ++++++++++++++++++++++++--------- 6 files changed, 49 insertions(+), 22 deletions(-) delete mode 100644 tests/requirements.txt diff --git a/.travis.yml b/.travis.yml index 8173790..132be5d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,8 +36,6 @@ matrix: # command to install dependencies install: - python --version - - pip install -r tests/requirements.txt - - python setup.py install # command to run tests -script: python -m unittest discover +script: python setup.py test diff --git a/pubs/apis.py b/pubs/apis.py index 3d57ec9..b816abd 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -13,7 +13,7 @@ class ReferenceNotFoundError(Exception): pass -def get_bibentry_from_api(id_str, id_type, rp): +def get_bibentry_from_api(id_str, id_type, rp, ui=None): """Return a bibtex string from various ID methods. This is a wrapper around functions that will return a bibtex string given @@ -27,12 +27,14 @@ def get_bibentry_from_api(id_str, id_type, rp): 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. + ui: A UI object. Returns: A bibtex string. Raises: ValueError: if `id_type` is not one of `doi`, `isbn`, or `arxiv`. + apis.ReferenceNotFoundException: if no valid reference could be found. """ id_fns = { @@ -69,7 +71,7 @@ def _get_request(url, headers=None): ## DOI support -def doi2bibtex(doi): +def doi2bibtex(doi, **kwargs): """Return a bibtex string of metadata from a DOI""" url = 'http://dx.doi.org/{}'.format(doi) @@ -83,7 +85,8 @@ def doi2bibtex(doi): ## ISBN support -def isbn2bibtex(isbn): + +def isbn2bibtex(isbn, **kwargs): """Return a bibtex string of metadata from an ISBN""" url = 'http://www.ottobib.com/isbn/{}/bibtex'.format(isbn) diff --git a/requirements.txt b/requirements.txt index da1abec..d757303 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +-e . pyyaml bibtexparser>=1.0 python-dateutil @@ -5,3 +6,10 @@ requests configobj beautifulsoup4 feedparser +six + +# those are the additional packages required to run the tests +pyfakefs +ddt +mock +pytest # optional (python setup.py test works without it), but possible nonetheless diff --git a/setup.py b/setup.py index e1fd8a9..50058b5 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,16 @@ #!/usr/bin/env python +import unittest from setuptools import setup with open('pubs/version.py') as f: exec(f.read()) # defines __version__ +def pubs_test_suite(): + test_loader = unittest.TestLoader() + test_suite = test_loader.discover('tests', pattern='test_*.py') + return test_suite + setup( name='pubs', version=__version__, @@ -26,9 +32,8 @@ setup( ], }, - install_requires=['pyyaml', 'bibtexparser>=1.0', 'python-dateutil', + install_requires=['pyyaml', 'bibtexparser>=1.0', 'python-dateutil', 'six', 'requests', 'configobj', 'beautifulsoup4', 'feedparser'], - tests_require=['pyfakefs>=2.7', 'mock'], extras_require={'autocompletion': ['argcomplete'], }, @@ -41,6 +46,9 @@ setup( 'Intended Audience :: Science/Research', ], + test_suite= 'tests', + tests_require=['pyfakefs>=3.4', 'mock', 'ddt'], + # in order to avoid 'zipimport.ZipImportError: bad local file header' zip_safe=False, diff --git a/tests/requirements.txt b/tests/requirements.txt deleted file mode 100644 index f3726e3..0000000 --- a/tests/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -# those are the additional packages required to run the tests -six -pyfakefs -ddt -mock diff --git a/tests/test_apis.py b/tests/test_apis.py index 2922016..6886aa1 100644 --- a/tests/test_apis.py +++ b/tests/test_apis.py @@ -12,11 +12,29 @@ from pubs.apis import ReferenceNotFoundError, arxiv2bibtex, doi2bibtex, isbn2bib from pubs import apis -class TestDOI2Bibtex(unittest.TestCase): +def _is_connected(): + """Return False if no internet connection is detected. + + May not work if the local network redirects the connection. + """ + try: + host = socket.gethostbyname('www.google.com') + s = socket.create_connection((host, 80), 2) + return True + except: + return False + +class APITests(unittest.TestCase): def setUp(self): + if not _is_connected(): + self.skipTest('no connection detected, skiping test') self.endecoder = EnDecoder() + + +class TestDOI2Bibtex(APITests): + def test_unicode(self): bib = doi2bibtex('10.1007/BF01700692') self.assertIsInstance(bib, ustr) @@ -37,10 +55,7 @@ class TestDOI2Bibtex(unittest.TestCase): doi2bibtex('999999') -class TestISBN2Bibtex(unittest.TestCase): - - def setUp(self): - self.endecoder = EnDecoder() +class TestISBN2Bibtex(APITests): def test_unicode(self): bib = isbn2bibtex('9782081336742') @@ -61,10 +76,7 @@ class TestISBN2Bibtex(unittest.TestCase): self.endecoder.decode_bibdata(bib) -class TestArxiv2Bibtex(unittest.TestCase): - - def setUp(self): - self.endecoder = EnDecoder() +class TestArxiv2Bibtex(APITests): def test_parses_to_bibtex_with_doi(self): bib = arxiv2bibtex('astro-ph/9812133') @@ -85,6 +97,9 @@ class TestArxiv2Bibtex(unittest.TestCase): entry['title'], 'The entropy formula for the Ricci flow and its geometric applications') +class TestArxiv2BibtexLocal(unittest.TestCase): + """Test arXiv 2 Bibtex connection; those tests don't require a connection""" + def test_oldstyle_pattern(self): """Test that we can accurately differentiate between old and new style arXiv ids.""" # old-style arXiv ids From 69f760cac6f20152110bbdbf279410195c0721c9 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Mon, 6 Aug 2018 11:28:14 +0900 Subject: [PATCH 11/20] dev_requirements.txt + explanation --- dev_requirements.txt | 23 +++++++++++++++++++++++ requirements.txt | 15 --------------- 2 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 dev_requirements.txt delete mode 100644 requirements.txt diff --git a/dev_requirements.txt b/dev_requirements.txt new file mode 100644 index 0000000..30e3cf6 --- /dev/null +++ b/dev_requirements.txt @@ -0,0 +1,23 @@ +# if you want to setup your environment for development of the pytest code, +# doing `pip install -r dev_requirements.txt` is the single thing you have to do. +# Alternatively, and perhaps more conveniently, running `python setup.py test` +# will do the same *and* run the tests. +# Note that if you introduce a new dependency, you need to add it here and, more +# importantly, to the setup.py script so that it is taken into account when +# installing from PyPi. + +-e . +pyyaml +bibtexparser>=1.0 +python-dateutil +requests +configobj +beautifulsoup4 +feedparser +six + +# those are the additional packages required to run the tests +pyfakefs +ddt +mock +pytest # optional (python setup.py test works without it), but possible nonetheless diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index d757303..0000000 --- a/requirements.txt +++ /dev/null @@ -1,15 +0,0 @@ --e . -pyyaml -bibtexparser>=1.0 -python-dateutil -requests -configobj -beautifulsoup4 -feedparser -six - -# those are the additional packages required to run the tests -pyfakefs -ddt -mock -pytest # optional (python setup.py test works without it), but possible nonetheless From be80e75cbb7fb531ae8c9d67d97ca08299d04e95 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Mon, 6 Aug 2018 17:45:30 +0900 Subject: [PATCH 12/20] better error message when parsing of bibtex fails Plus, slight refactoring: remove `databroker.verify()` method --- changelog.md | 5 +++++ pubs/apis.py | 6 +++--- pubs/commands/add_cmd.py | 26 +++++++++++++---------- pubs/databroker.py | 10 --------- pubs/datacache.py | 3 --- pubs/endecoder.py | 45 +++++++++++++++++++++++++++++----------- tests/test_apis.py | 15 ++++++++++++-- tests/test_endecoder.py | 17 +++++++++++++++ 8 files changed, 86 insertions(+), 41 deletions(-) diff --git a/changelog.md b/changelog.md index 314ccbd..5e07c14 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,10 @@ ### Implemented enhancements +- Support for downloading arXiv reference from their ID ([#146](https://github.com/pubs/pubs/issues/146) by [joe-antognini](https://github.com/joe-antognini)) + +- Better feedback when an error is encountered while adding a reference from a DOI, ISBN or arXiv ID [#155](https://github.com/pubs/pubs/issues/155) + - Better dialog after editing paper [(#142)](https://github.com/pubs/pubs/issues/142) - Add a command to open urls ([#139](https://github.com/pubs/pubs/issues/139) by [ksunden](https://github.com/ksunden)) @@ -26,6 +30,7 @@ - Support year ranges in query [(#102)](https://github.com/pubs/pubs/issues/102) +- Tests can now be run with `python setup.py test` [#155](https://github.com/pubs/pubs/issues/155) ### Fixed bugs diff --git a/pubs/apis.py b/pubs/apis.py index b816abd..f6d84a8 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -13,7 +13,7 @@ class ReferenceNotFoundError(Exception): pass -def get_bibentry_from_api(id_str, id_type, rp, ui=None): +def get_bibentry_from_api(id_str, id_type, try_doi=True, ui=None): """Return a bibtex string from various ID methods. This is a wrapper around functions that will return a bibtex string given @@ -46,8 +46,8 @@ def get_bibentry_from_api(id_str, id_type, rp, ui=None): 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) + bibentry_raw = id_fns[id_type](id_str, try_doi=try_doi, ui=ui) + endecoder.EnDecoder().decode_bibdata(bibentry_raw) if bibentry is None: raise ReferenceNotFoundException( 'invalid {} {} or unable to retrieve bibfile from it.'.format(id_type, id_str)) diff --git a/pubs/commands/add_cmd.py b/pubs/commands/add_cmd.py index 3ae8f70..dead1a7 100644 --- a/pubs/commands/add_cmd.py +++ b/pubs/commands/add_cmd.py @@ -43,22 +43,25 @@ def parser(subparsers, conf): return parser -def bibentry_from_editor(conf, ui, rp): +def bibentry_from_editor(conf, ui): + again = True - bibstr = templates.add_bib + bibentry_raw = templates.add_bib + decoder = endecoder.EnDecoder() + while again: try: - bibstr = ui.editor_input(initial=bibstr, suffix='.bib') - if bibstr == templates.add_bib: + bibentry_raw = ui.editor_input(initial=bibentry_raw, suffix='.bib') + if bibentry_raw == templates.add_bib: again = ui.input_yn( question='Bibfile not edited. Edit again ?', default='y') if not again: ui.exit(0) else: - bibentry = rp.databroker.verify(bibstr) + bibentry = decoder.decode_bibdata(bibentry_raw) bibstruct.verify_bibdata(bibentry) - # REFACTOR Generate citykey + # REFACTOR Generate citekey again = False except endecoder.EnDecoder.BibDecodingError: @@ -84,28 +87,29 @@ def command(conf, args): citekey = args.citekey rp = repo.Repository(conf) + decoder = endecoder.EnDecoder() # get bibtex entry if bibfile is None: if args.doi is None and args.isbn is None and args.arxiv is None: - bibentry = bibentry_from_editor(conf, ui, rp) + bibentry = bibentry_from_editor(conf, ui) else: bibentry = None try: if args.doi is not None: - bibentry = apis.get_bibentry_from_api(args.doi, 'doi', rp) + bibentry = apis.get_bibentry_from_api(args.doi, 'doi', ui=ui) elif args.isbn is not None: - bibentry = apis.get_bibentry_from_api(args.isbn, 'isbn', rp) + bibentry = apis.get_bibentry_from_api(args.isbn, 'isbn', ui=ui) # 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 = apis.get_bibentry_from_api(args.arxiv, 'arxiv', rp) + bibentry = apis.get_bibentry_from_api(args.arxiv, 'arxiv', ui=ui) except apis.ReferenceNotFoundException as e: ui.error(e.message) ui.exit(1) else: bibentry_raw = content.get_content(bibfile, ui=ui) - bibentry = rp.databroker.verify(bibentry_raw) + bibentry = decoder.decode_bibdata(bibentry_raw) if bibentry is None: ui.error('invalid bibfile {}.'.format(bibfile)) diff --git a/pubs/databroker.py b/pubs/databroker.py index 97c1398..23e8b91 100644 --- a/pubs/databroker.py +++ b/pubs/databroker.py @@ -79,16 +79,6 @@ class DataBroker(object): def listing(self, filestats=True): return self.filebroker.listing(filestats=filestats) - def verify(self, bibdata_raw): - """Will return None if bibdata_raw can't be decoded""" - try: - if bibdata_raw.startswith('\ufeff'): - # remove BOM, because bibtexparser does not support it. - bibdata_raw = bibdata_raw[1:] - return self.endecoder.decode_bibdata(bibdata_raw) - except ValueError as e: - return None - # docbroker def in_docsdir(self, docpath): diff --git a/pubs/datacache.py b/pubs/datacache.py index 2da4fe0..a02a05b 100644 --- a/pubs/datacache.py +++ b/pubs/datacache.py @@ -163,9 +163,6 @@ class DataCache(object): def listing(self, filestats=True): return self.databroker.listing(filestats=filestats) - def verify(self, bibdata_raw): - return self.databroker.verify(bibdata_raw) - # docbroker def in_docsdir(self, docpath): diff --git a/pubs/endecoder.py b/pubs/endecoder.py index 259b8d9..f265f54 100644 --- a/pubs/endecoder.py +++ b/pubs/endecoder.py @@ -1,9 +1,16 @@ from __future__ import absolute_import, unicode_literals import copy +import logging + +# both needed to intercept exceptions. +import pyparsing +import bibtexparser try: import bibtexparser as bp + # don't let bibtexparser display stuff +# bp.bparser.logger.setLevel(level=logging.CRITICAL) except ImportError: print("error: you need to install bibterxparser; try running 'pip install " "bibtexparser'.") @@ -68,14 +75,16 @@ class EnDecoder(object): class BibDecodingError(Exception): - message = "Could not parse provided bibdata:\n---\n{}\n---" +# message = "Could not parse provided bibdata:\n---\n{}\n---" - def __init__(self, bibdata): + def __init__(self, error_msg, bibdata): + """ + :param error_msg: specific message about what went wrong + :param bibdata: the data that was unsuccessfully decoded. + """ + super(Exception, self).__init__(error_msg) # make `str(self)` work. self.data = bibdata - def __str__(self): - return self.message.format(self.data) - bwriter = bp.bwriter.BibTexWriter() bwriter.display_order = BIBFIELD_ORDER @@ -117,10 +126,12 @@ class EnDecoder(object): If the decoding fails, returns a BibParseError. """ + if len(bibdata) == 0: + error_msg = 'parsing error: the provided string has length zero.' + raise self.BibDecodingError(error_msg, bibdata) try: entries = bp.bparser.BibTexParser( - bibdata, common_strings=True, - customization=customizations, + bibdata, common_strings=True, customization=customizations, homogenize_fields=True).get_entry_dict() # Remove id from bibtexparser attribute which is stored as citekey @@ -131,8 +142,18 @@ class EnDecoder(object): entries[e][TYPE_KEY] = t if len(entries) > 0: return entries - except Exception: - import traceback - traceback.print_exc() - raise self.BibDecodingError(bibdata) - # TODO: filter exceptions from pyparsing and pass reason upstream + except (pyparsing.ParseException, pyparsing.ParseSyntaxException) as e: + error_msg = self._format_parsing_error(e) + raise self.BibDecodingError(error_msg, bibdata) + except bibtexparser.bibdatabase.UndefinedString as e: + error_msg = 'parsing error: undefined string in provided data: {}'.format(e) + raise self.BibDecodingError(error_msg, bibdata) + + + @classmethod + def _format_parsing_error(cls, e): + """Transform a pyparsing exception into an error message + + Does a best effort to be useful, but might need to be improved. + """ + return '{}\n{}^\n{}'.format(e.line, (e.column - 1) * ' ', e) diff --git a/tests/test_apis.py b/tests/test_apis.py index 6886aa1..d42e110 100644 --- a/tests/test_apis.py +++ b/tests/test_apis.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import unittest +import socket import dotdot @@ -20,9 +21,11 @@ def _is_connected(): try: host = socket.gethostbyname('www.google.com') s = socket.create_connection((host, 80), 2) + s.close() return True - except: - return False + except socket.error: + pass + return False class APITests(unittest.TestCase): @@ -78,6 +81,14 @@ class TestISBN2Bibtex(APITests): class TestArxiv2Bibtex(APITests): + def test_new_style(self): + bib = arxiv2bibtex('astro-ph/9812133') + b = self.endecoder.decode_bibdata(bib) + self.assertEqual(len(b), 1) + entry = b[list(b)[0]] + self.assertEqual(entry['author'][0], 'Perlmutter, S.') + self.assertEqual(entry['year'], '1999') + def test_parses_to_bibtex_with_doi(self): bib = arxiv2bibtex('astro-ph/9812133') b = self.endecoder.decode_bibdata(bib) diff --git a/tests/test_endecoder.py b/tests/test_endecoder.py index a6e3043..11d5306 100644 --- a/tests/test_endecoder.py +++ b/tests/test_endecoder.py @@ -23,6 +23,11 @@ def compare_yaml_str(s1, s2): class TestEnDecode(unittest.TestCase): + def test_decode_emptystring(self): + decoder = endecoder.EnDecoder() + with self.assertRaises(decoder.BibDecodingError): + entry = decoder.decode_bibdata('') + def test_encode_bibtex_is_unicode(self): decoder = endecoder.EnDecoder() entry = decoder.decode_bibdata(bibtex_raw0) @@ -52,6 +57,18 @@ class TestEnDecode(unittest.TestCase): self.assertEqual(bibraw1, bibraw2) + def test_endecode_bibtex_BOM(self): + """Test that bibtexparser if fine with BOM-prefixed data""" + decoder = endecoder.EnDecoder() + bom_str = '\ufeff' + + entry_1 = decoder.decode_bibdata(bibtex_raw0) + bibraw_1 = decoder.encode_bibdata(entry_1) + entry_2 = decoder.decode_bibdata(bom_str + bibraw_1) + bibraw_2 = decoder.encode_bibdata(entry_2) + + self.assertEqual(bibraw_1, bibraw_2) + def test_endecode_bibtex_converts_month_string(self): """Test if `month=dec` is correctly recognized and transformed into `month={December}`""" From bf1b4cd9d755a729643a57a90d07cae2332cd558 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Tue, 7 Aug 2018 11:22:36 +0900 Subject: [PATCH 13/20] mock mode for test_apis The mock system relies on the PUBS_TESTS_MODE environmental variable. See the `tests/mock_requests.py` code for details. By defaults, fast mock tests are used with data pre-fetched from real calls. --- dev_requirements.txt | 3 +- pubs/apis.py | 12 -------- pubs/endecoder.py | 4 +-- test_apis_data.pickle | Bin 0 -> 43888 bytes tests/mock_requests.py | 61 +++++++++++++++++++++++++++++++++++++++++ tests/test_apis.py | 40 +++++++++++++++++++-------- 6 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 test_apis_data.pickle create mode 100644 tests/mock_requests.py diff --git a/dev_requirements.txt b/dev_requirements.txt index 30e3cf6..0d91a9e 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,7 +1,8 @@ # if you want to setup your environment for development of the pytest code, # doing `pip install -r dev_requirements.txt` is the single thing you have to do. # Alternatively, and perhaps more conveniently, running `python setup.py test` -# will do the same *and* run the tests. +# will do the same *and* run the tests, but without installing the packages on +# the system. # Note that if you introduce a new dependency, you need to add it here and, more # importantly, to the setup.py script so that it is taken into account when # installing from PyPi. diff --git a/pubs/apis.py b/pubs/apis.py index f6d84a8..6f487ca 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -146,7 +146,6 @@ def arxiv2bibtex(arxiv_id, try_doi=True, ui=None): "'{}': {}".format(arxiv_id, e)) raise ReferenceNotFoundError(msg) - # print("TEXT = '{}'".format(r.text)) feed = feedparser.parse(r.text) if len(feed.entries) == 0: # no results. msg = "no results for arXiv id {}".format(arxiv_id) @@ -161,12 +160,6 @@ def arxiv2bibtex(arxiv_id, try_doi=True, ui=None): raise ReferenceNotFoundError(msg) entry = feed.entries[0] - if 'arxiv.org/api/errors' in entry['id']: # server is returning an error message. - msg = 'the arXiv server returned an error message: {}'.format(entry['summary']) - raise ReferenceNotFoundError(msg) - # import pprint - # pprint.pprint(entry) - ## try to return a doi instead of the arXiv reference if try_doi and 'arxiv_doi' in entry: @@ -203,8 +196,3 @@ def arxiv2bibtex(arxiv_id, try_doi=True, ui=None): bibtex = bibtexparser.dumps(db) return bibtex - -if __name__ == '__main__': - print(arxiv2bibtex("0704.0010")) - print(arxiv2bibtex("0704.010*")) -# print(arxiv2bibtex("quant-ph/0703266")) diff --git a/pubs/endecoder.py b/pubs/endecoder.py index f265f54..c280460 100644 --- a/pubs/endecoder.py +++ b/pubs/endecoder.py @@ -10,7 +10,7 @@ import bibtexparser try: import bibtexparser as bp # don't let bibtexparser display stuff -# bp.bparser.logger.setLevel(level=logging.CRITICAL) + bp.bparser.logger.setLevel(level=logging.CRITICAL) except ImportError: print("error: you need to install bibterxparser; try running 'pip install " "bibtexparser'.") @@ -75,8 +75,6 @@ class EnDecoder(object): class BibDecodingError(Exception): -# message = "Could not parse provided bibdata:\n---\n{}\n---" - def __init__(self, error_msg, bibdata): """ :param error_msg: specific message about what went wrong diff --git a/test_apis_data.pickle b/test_apis_data.pickle new file mode 100644 index 0000000000000000000000000000000000000000..a18f46a1779088764856cae2dfc0e3587e196c31 GIT binary patch literal 43888 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 Date: Tue, 7 Aug 2018 11:48:28 +0900 Subject: [PATCH 14/20] Add explanation for how mock work. Fix pickle protocol error for Python 2.7. --- .travis.yml | 1 + tests/mock_requests.py | 40 +++++++++++++++--- .../test_apis_data.pickle | Bin 43888 -> 43888 bytes 3 files changed, 35 insertions(+), 6 deletions(-) rename test_apis_data.pickle => tests/test_apis_data.pickle (99%) diff --git a/.travis.yml b/.travis.yml index 132be5d..f10b731 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ matrix: # command to install dependencies install: - python --version + - export PUBS_TESTS_MODE=ONLINE # command to run tests script: python setup.py test diff --git a/tests/mock_requests.py b/tests/mock_requests.py index 31e4ec3..a9ff9ab 100644 --- a/tests/mock_requests.py +++ b/tests/mock_requests.py @@ -1,3 +1,26 @@ +""" +Mock the `requests.get` function, and handle collecting data to do so. + +Three modes are available, and controlled via the `PUBS_TESTS_MODE` environment +variable. To modify the variable, under linux or macos, do one of: +$ export PUBS_TESTS_MODE=MOCK +$ export PUBS_TESTS_MODE=COLLECT +$ export PUBS_TESTS_MODE=ONLINE + +The MOCK mode is the default one, active even if PUBS_TESTS_MODE has not been +set. It use prefetched data to run pubs units tests relying on the `requests.get` +function without the need of an internet connection (it is also much faster). +The prefected data is save in the `test_apis_data.pickle` file. + +The COLLECT mode does real GET requests, and update the `test_apis_data.pickle` +file. It is needed if you add or modify the test relying on `requests.get`. + +The ONLINE mode bypasses all this and use the original `requests.get` without +accessing or updating the `test_apis_data.pickle` data. It might be useful when +running tests on Travis for instance. +""" + + import os try: import cPickle as pickle @@ -6,9 +29,10 @@ except ImportError: import requests -_orgininal_requests_get = requests.get +_orgininal_requests_get = requests.get _collected_responses = [] +_data_filepath = os.path.join(os.path.dirname(__file__), 'test_apis_data.pickle') class MockingResponse: def __init__(self, text, status_code=200, error_msg=None): @@ -26,14 +50,16 @@ mode = os.environ.get('PUBS_TESTS_MODE', 'MOCK') if mode == 'MOCK': - with open('test_apis_data.pickle', 'rb') as fd: + with open(os.path.join(_data_filepath), 'rb') as fd: _collected_responses.extend(pickle.load(fd)) def mock_requests_get(*args, **kwargs): for args2, kwargs2, text, status_code, error_msg in _collected_responses: if args == args2 and kwargs == kwargs2: return MockingResponse(text, status_code, error_msg) - raise KeyError('No stub data found for requests.get({}, {})'.format(args, kwargs)) + raise KeyError(('No stub data found for requests.get({}, {}).\n You may' + ' need to update the mock data. Look at the ' + 'tests/mock_requests.py file for explanation').format(args, kwargs)) elif mode == 'COLLECT': @@ -48,13 +74,15 @@ elif mode == 'COLLECT': key = (sorted(args), sorted((k, v) for k, v in kwargs.items())) _collected_responses.append((args, kwargs, text, status_code, error_msg)) - _save_collected_responses() + _save_collected_responses() # yes, we save everytime, because it's not + # clear how to run once after all the tests + # have run. If you figure it out... return MockingResponse(text, status_code, error_msg) def _save_collected_responses(): - with open('test_apis_data.pickle', 'wb') as fd: - pickle.dump(_collected_responses, fd, protocol=3) + with open(os.path.join(_data_filepath), 'wb') as fd: + pickle.dump(_collected_responses, fd, protocol=2) elif mode == 'ONLINE': def mock_requests_get(*args, **kwargs): diff --git a/test_apis_data.pickle b/tests/test_apis_data.pickle similarity index 99% rename from test_apis_data.pickle rename to tests/test_apis_data.pickle index a18f46a1779088764856cae2dfc0e3587e196c31..1d7a91495e82100eedec4a502ddacb63047dc61a 100644 GIT binary patch delta 233 zcmexxjp@TRCe8+?*g^&kjR@<>@*#SYqqGD!dhDpu4hzT&Pbw%jPV@Cnbqmr?*3U0; zGs-hAHO|dTwA6R?@yRmFDM*fT@efVk9Jok~bF*X13l?o3b8mn5^7Js1km3|m3uEKl z;K*XX-0&n5!{qS7tb#I&?6eZgG_&xu5?`RMJ4~AmdQLEtq)T}Mvyhgtv59B7ds1Mb qhmVV8K#^04etML9ae9=qlYx0rWVxw+c0i=5w!c9@@aBL;3Y-7~yH830 delta 233 zcmexxjp@TRCe8-t*g^&kjR@<>@*#SYqqGD!dhDpub}2${Nva6l9Jok~bF*X13l{C<%&MZi&=6D86xUMAGGCW~ ztjfaTS#fQa%8*UB_!%Y2}&J4~AmdQLEtq)T}MvyfIQ3YL1uPpK}c|F{^o#13Y-940#Skh From c62d1c3c5030ffc2c79b1f9e2625be3f08cd6f09 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Thu, 9 Aug 2018 19:51:40 +0900 Subject: [PATCH 15/20] move test data from pickle to json --- .travis.yml | 6 +++++- readme.md | 4 ++++ tests/mock_requests.py | 22 +++++++++------------- tests/test_apis.py | 18 ------------------ tests/test_apis_data.json | 1 + tests/test_apis_data.pickle | Bin 43888 -> 0 bytes 6 files changed, 19 insertions(+), 32 deletions(-) create mode 100644 tests/test_apis_data.json delete mode 100644 tests/test_apis_data.pickle diff --git a/.travis.yml b/.travis.yml index f10b731..16e69a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,4 +39,8 @@ install: - export PUBS_TESTS_MODE=ONLINE # command to run tests -script: python setup.py test +script: + - export PUBS_TESTS_MODE=ONLINE + - python setup.py test + - export PUBS_TESTS_MODE=MOCK + - python setup.py test diff --git a/readme.md b/readme.md index 4b03dcd..5b43e56 100644 --- a/readme.md +++ b/readme.md @@ -56,6 +56,10 @@ or an ISBN (dashes are ignored): pubs add -I 978-0822324669 -d article.pdf +or an arXiv id (automatically downloading arXiv article is in the works): + + pubs add -X math/9501234 -d article.pdf + ## References always up-to-date diff --git a/tests/mock_requests.py b/tests/mock_requests.py index a9ff9ab..3eb72ca 100644 --- a/tests/mock_requests.py +++ b/tests/mock_requests.py @@ -8,11 +8,11 @@ $ export PUBS_TESTS_MODE=COLLECT $ export PUBS_TESTS_MODE=ONLINE The MOCK mode is the default one, active even if PUBS_TESTS_MODE has not been -set. It use prefetched data to run pubs units tests relying on the `requests.get` +set. It uses saved data to run pubs units tests relying on the `requests.get` function without the need of an internet connection (it is also much faster). The prefected data is save in the `test_apis_data.pickle` file. -The COLLECT mode does real GET requests, and update the `test_apis_data.pickle` +The COLLECT mode does real GET requests, and updates the `test_apis_data.pickle` file. It is needed if you add or modify the test relying on `requests.get`. The ONLINE mode bypasses all this and use the original `requests.get` without @@ -22,17 +22,14 @@ running tests on Travis for instance. import os -try: - import cPickle as pickle -except ImportError: - import pickle +import json import requests _orgininal_requests_get = requests.get _collected_responses = [] -_data_filepath = os.path.join(os.path.dirname(__file__), 'test_apis_data.pickle') +_data_filepath = os.path.join(os.path.dirname(__file__), 'test_apis_data.json') class MockingResponse: def __init__(self, text, status_code=200, error_msg=None): @@ -50,12 +47,12 @@ mode = os.environ.get('PUBS_TESTS_MODE', 'MOCK') if mode == 'MOCK': - with open(os.path.join(_data_filepath), 'rb') as fd: - _collected_responses.extend(pickle.load(fd)) + with open(os.path.join(_data_filepath), 'r') as fd: + _collected_responses = json.load(fd) def mock_requests_get(*args, **kwargs): for args2, kwargs2, text, status_code, error_msg in _collected_responses: - if args == args2 and kwargs == kwargs2: + if list(args) == list(args2) and kwargs == kwargs2: return MockingResponse(text, status_code, error_msg) raise KeyError(('No stub data found for requests.get({}, {}).\n You may' ' need to update the mock data. Look at the ' @@ -71,7 +68,6 @@ elif mode == 'COLLECT': r.raise_for_status() except requests.exceptions.RequestException as e: error_msg = str(e) - key = (sorted(args), sorted((k, v) for k, v in kwargs.items())) _collected_responses.append((args, kwargs, text, status_code, error_msg)) _save_collected_responses() # yes, we save everytime, because it's not @@ -81,8 +77,8 @@ elif mode == 'COLLECT': return MockingResponse(text, status_code, error_msg) def _save_collected_responses(): - with open(os.path.join(_data_filepath), 'wb') as fd: - pickle.dump(_collected_responses, fd, protocol=2) + with open(os.path.join(_data_filepath), 'w') as fd: + json.dump(_collected_responses, fd) elif mode == 'ONLINE': def mock_requests_get(*args, **kwargs): diff --git a/tests/test_apis.py b/tests/test_apis.py index e3651e4..67a76b5 100644 --- a/tests/test_apis.py +++ b/tests/test_apis.py @@ -2,7 +2,6 @@ from __future__ import unicode_literals import unittest -import socket import mock @@ -18,26 +17,9 @@ from pubs import apis import mock_requests -def _is_connected(): - """Return False if no internet connection is detected. - - May not work if the local network redirects the connection. - """ - try: - host = socket.gethostbyname('www.google.com') - s = socket.create_connection((host, 80), 2) - s.close() - return True - except socket.error: - pass - return False - - class APITests(unittest.TestCase): def setUp(self): - # if not _is_connected(): - # self.skipTest('no connection detected, skiping test') self.endecoder = EnDecoder() diff --git a/tests/test_apis_data.json b/tests/test_apis_data.json new file mode 100644 index 0000000..42daa8c --- /dev/null +++ b/tests/test_apis_data.json @@ -0,0 +1 @@ +[[["https://export.arxiv.org/api/query?id_list=astro-ph/9812133"], {}, "\n\n \n ArXiv Query: search_query=&id_list=astro-ph/9812133&start=0&max_results=10\n http://arxiv.org/api/SfKekabpSjI/htnxCLpK3q9AsUs\n 2018-08-09T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/astro-ph/9812133v1\n 1998-12-08T03:27:34Z\n 1998-12-08T03:27:34Z\n Measurements of Omega and Lambda from 42 High-Redshift Supernovae\n We report measurements of the mass density, Omega_M, and\ncosmological-constant energy density, Omega_Lambda, of the universe based on\nthe analysis of 42 Type Ia supernovae discovered by the Supernova Cosmology\nProject. The magnitude-redshift data for these SNe, at redshifts between 0.18\nand 0.83, are fit jointly with a set of SNe from the Calan/Tololo Supernova\nSurvey, at redshifts below 0.1, to yield values for the cosmological\nparameters. All SN peak magnitudes are standardized using a SN Ia lightcurve\nwidth-luminosity relation. The measurement yields a joint probability\ndistribution of the cosmological parameters that is approximated by the\nrelation 0.8 Omega_M - 0.6 Omega_Lambda ~= -0.2 +/- 0.1 in the region of\ninterest (Omega_M <~ 1.5). For a flat (Omega_M + Omega_Lambda = 1) cosmology we\nfind Omega_M = 0.28{+0.09,-0.08} (1 sigma statistical) {+0.05,-0.04}\n(identified systematics). The data are strongly inconsistent with a Lambda = 0\nflat cosmology, the simplest inflationary universe model. An open, Lambda = 0\ncosmology also does not fit the data well: the data indicate that the\ncosmological constant is non-zero and positive, with a confidence of P(Lambda >\n0) = 99%, including the identified systematic uncertainties. The best-fit age\nof the universe relative to the Hubble time is t_0 = 14.9{+1.4,-1.1} (0.63/h)\nGyr for a flat cosmology. The size of our sample allows us to perform a variety\nof statistical tests to check for possible systematic errors and biases. We\nfind no significant differences in either the host reddening distribution or\nMalmquist bias between the low-redshift Calan/Tololo sample and our\nhigh-redshift sample. The conclusions are robust whether or not a\nwidth-luminosity relation is used to standardize the SN peak magnitudes.\n\n \n S. Perlmutter\n The Supernova Cosmology Project\n \n \n G. Aldering\n The Supernova Cosmology Project\n \n \n G. Goldhaber\n The Supernova Cosmology Project\n \n \n R. A. Knop\n The Supernova Cosmology Project\n \n \n P. Nugent\n The Supernova Cosmology Project\n \n \n P. G. Castro\n The Supernova Cosmology Project\n \n \n S. Deustua\n The Supernova Cosmology Project\n \n \n S. Fabbro\n The Supernova Cosmology Project\n \n \n A. Goobar\n The Supernova Cosmology Project\n \n \n D. E. Groom\n The Supernova Cosmology Project\n \n \n I. M. Hook\n The Supernova Cosmology Project\n \n \n A. G. Kim\n The Supernova Cosmology Project\n \n \n M. Y. Kim\n The Supernova Cosmology Project\n \n \n J. C. Lee\n The Supernova Cosmology Project\n \n \n N. J. Nunes\n The Supernova Cosmology Project\n \n \n R. Pain\n The Supernova Cosmology Project\n \n \n C. R. Pennypacker\n The Supernova Cosmology Project\n \n \n R. Quimby\n The Supernova Cosmology Project\n \n \n C. Lidman\n The Supernova Cosmology Project\n \n \n R. S. Ellis\n The Supernova Cosmology Project\n \n \n M. Irwin\n The Supernova Cosmology Project\n \n \n R. G. McMahon\n The Supernova Cosmology Project\n \n \n P. Ruiz-Lapuente\n The Supernova Cosmology Project\n \n \n N. Walton\n The Supernova Cosmology Project\n \n \n B. Schaefer\n The Supernova Cosmology Project\n \n \n B. J. Boyle\n The Supernova Cosmology Project\n \n \n A. V. Filippenko\n The Supernova Cosmology Project\n \n \n T. Matheson\n The Supernova Cosmology Project\n \n \n A. S. Fruchter\n The Supernova Cosmology Project\n \n \n N. Panagia\n The Supernova Cosmology Project\n \n \n H. J. M. Newberg\n The Supernova Cosmology Project\n \n \n W. J. Couch\n The Supernova Cosmology Project\n \n 10.1086/307221\n \n 21 pages and 10 figures. Accepted for publication in the\n Astrophysical Journal. Individual color figures, supplementary tables, and\n preprint also available at http://www-supernova.lbl.gov/\n Astrophys.J.517:565-586,1999\n \n \n \n \n \n \n \n\n", 200, null], [["http://dx.doi.org/10.1086/307221"], {"headers": {"accept": "application/x-bibtex"}}, "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", 200, null], [["https://export.arxiv.org/api/query?id_list=astro-ph/9812133"], {}, "\n\n \n ArXiv Query: search_query=&id_list=astro-ph/9812133&start=0&max_results=10\n http://arxiv.org/api/SfKekabpSjI/htnxCLpK3q9AsUs\n 2018-08-09T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/astro-ph/9812133v1\n 1998-12-08T03:27:34Z\n 1998-12-08T03:27:34Z\n Measurements of Omega and Lambda from 42 High-Redshift Supernovae\n We report measurements of the mass density, Omega_M, and\ncosmological-constant energy density, Omega_Lambda, of the universe based on\nthe analysis of 42 Type Ia supernovae discovered by the Supernova Cosmology\nProject. The magnitude-redshift data for these SNe, at redshifts between 0.18\nand 0.83, are fit jointly with a set of SNe from the Calan/Tololo Supernova\nSurvey, at redshifts below 0.1, to yield values for the cosmological\nparameters. All SN peak magnitudes are standardized using a SN Ia lightcurve\nwidth-luminosity relation. The measurement yields a joint probability\ndistribution of the cosmological parameters that is approximated by the\nrelation 0.8 Omega_M - 0.6 Omega_Lambda ~= -0.2 +/- 0.1 in the region of\ninterest (Omega_M <~ 1.5). For a flat (Omega_M + Omega_Lambda = 1) cosmology we\nfind Omega_M = 0.28{+0.09,-0.08} (1 sigma statistical) {+0.05,-0.04}\n(identified systematics). The data are strongly inconsistent with a Lambda = 0\nflat cosmology, the simplest inflationary universe model. An open, Lambda = 0\ncosmology also does not fit the data well: the data indicate that the\ncosmological constant is non-zero and positive, with a confidence of P(Lambda >\n0) = 99%, including the identified systematic uncertainties. The best-fit age\nof the universe relative to the Hubble time is t_0 = 14.9{+1.4,-1.1} (0.63/h)\nGyr for a flat cosmology. The size of our sample allows us to perform a variety\nof statistical tests to check for possible systematic errors and biases. We\nfind no significant differences in either the host reddening distribution or\nMalmquist bias between the low-redshift Calan/Tololo sample and our\nhigh-redshift sample. The conclusions are robust whether or not a\nwidth-luminosity relation is used to standardize the SN peak magnitudes.\n\n \n S. Perlmutter\n The Supernova Cosmology Project\n \n \n G. Aldering\n The Supernova Cosmology Project\n \n \n G. Goldhaber\n The Supernova Cosmology Project\n \n \n R. A. Knop\n The Supernova Cosmology Project\n \n \n P. Nugent\n The Supernova Cosmology Project\n \n \n P. G. Castro\n The Supernova Cosmology Project\n \n \n S. Deustua\n The Supernova Cosmology Project\n \n \n S. Fabbro\n The Supernova Cosmology Project\n \n \n A. Goobar\n The Supernova Cosmology Project\n \n \n D. E. Groom\n The Supernova Cosmology Project\n \n \n I. M. Hook\n The Supernova Cosmology Project\n \n \n A. G. Kim\n The Supernova Cosmology Project\n \n \n M. Y. Kim\n The Supernova Cosmology Project\n \n \n J. C. Lee\n The Supernova Cosmology Project\n \n \n N. J. Nunes\n The Supernova Cosmology Project\n \n \n R. Pain\n The Supernova Cosmology Project\n \n \n C. R. Pennypacker\n The Supernova Cosmology Project\n \n \n R. Quimby\n The Supernova Cosmology Project\n \n \n C. Lidman\n The Supernova Cosmology Project\n \n \n R. S. Ellis\n The Supernova Cosmology Project\n \n \n M. Irwin\n The Supernova Cosmology Project\n \n \n R. G. McMahon\n The Supernova Cosmology Project\n \n \n P. Ruiz-Lapuente\n The Supernova Cosmology Project\n \n \n N. Walton\n The Supernova Cosmology Project\n \n \n B. Schaefer\n The Supernova Cosmology Project\n \n \n B. J. Boyle\n The Supernova Cosmology Project\n \n \n A. V. Filippenko\n The Supernova Cosmology Project\n \n \n T. Matheson\n The Supernova Cosmology Project\n \n \n A. S. Fruchter\n The Supernova Cosmology Project\n \n \n N. Panagia\n The Supernova Cosmology Project\n \n \n H. J. M. Newberg\n The Supernova Cosmology Project\n \n \n W. J. Couch\n The Supernova Cosmology Project\n \n 10.1086/307221\n \n 21 pages and 10 figures. Accepted for publication in the\n Astrophysical Journal. Individual color figures, supplementary tables, and\n preprint also available at http://www-supernova.lbl.gov/\n Astrophys.J.517:565-586,1999\n \n \n \n \n \n \n \n\n", 200, null], [["http://dx.doi.org/10.1086/307221"], {"headers": {"accept": "application/x-bibtex"}}, "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", 200, null], [["https://export.arxiv.org/api/query?id_list=math/0211159"], {}, "\n\n \n ArXiv Query: search_query=&id_list=math/0211159&start=0&max_results=10\n http://arxiv.org/api/4nVRTcAL5Np4oaGFQnqVPG0+c5k\n 2018-08-09T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/math/0211159v1\n 2002-11-11T16:11:49Z\n 2002-11-11T16:11:49Z\n The entropy formula for the Ricci flow and its geometric applications\n We present a monotonic expression for the Ricci flow, valid in all dimensions\nand without curvature assumptions. It is interpreted as an entropy for a\ncertain canonical ensemble. Several geometric applications are given. In\nparticular, (1) Ricci flow, considered on the space of riemannian metrics\nmodulo diffeomorphism and scaling, has no nontrivial periodic orbits (that is,\nother than fixed points); (2) In a region, where singularity is forming in\nfinite time, the injectivity radius is controlled by the curvature; (3) Ricci\nflow can not quickly turn an almost euclidean region into a very curved one, no\nmatter what happens far away. We also verify several assertions related to\nRichard Hamilton's program for the proof of Thurston geometrization conjecture\nfor closed three-manifolds, and give a sketch of an eclectic proof of this\nconjecture, making use of earlier results on collapsing with local lower\ncurvature bound.\n\n \n Grisha Perelman\n \n 39 pages\n \n \n \n \n \n \n\n", 200, null], [["http://dx.doi.org/10.1007/BF01700692"], {"headers": {"accept": "application/x-bibtex"}}, "@article{G_del_1931,\n\tdoi = {10.1007/bf01700692},\n\turl = {https://doi.org/10.1007%2Fbf01700692},\n\tyear = 1931,\n\tmonth = {dec},\n\tpublisher = {Springer Nature},\n\tvolume = {38-38},\n\tnumber = {1},\n\tpages = {173--198},\n\tauthor = {Kurt G\u00f6del},\n\ttitle = {\u00dcber formal unentscheidbare S\u00e4tze der Principia Mathematica und verwandter Systeme I},\n\tjournal = {Monatshefte f\u00fcr Mathematik und Physik}\n}", 200, null], [["http://dx.doi.org/999999"], {"headers": {"accept": "application/x-bibtex"}}, "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10/999999

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", 404, "404 Client Error: for url: http://dx.doi.org/999999"], [["http://dx.doi.org/10.1007/BF01700692"], {"headers": {"accept": "application/x-bibtex"}}, "@article{G_del_1931,\n\tdoi = {10.1007/bf01700692},\n\turl = {https://doi.org/10.1007%2Fbf01700692},\n\tyear = 1931,\n\tmonth = {dec},\n\tpublisher = {Springer Nature},\n\tvolume = {38-38},\n\tnumber = {1},\n\tpages = {173--198},\n\tauthor = {Kurt G\u00f6del},\n\ttitle = {\u00dcber formal unentscheidbare S\u00e4tze der Principia Mathematica und verwandter Systeme I},\n\tjournal = {Monatshefte f\u00fcr Mathematik und Physik}\n}", 200, null], [["http://www.ottobib.com/isbn/9782081336742/bibtex"], {"headers": null}, "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", 200, null], [["http://www.ottobib.com/isbn/9999999999999/bibtex"], {"headers": null}, "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n\t

OttoBib

\n\t

Make a bibliography or works cited with just an ISBN. It's free, easy and FAST

\n\t

\n\t about ottobib and history\n\t \n\t

\n\t \n

\n\t
\n
\n\n
\n
\n\n
No Results for 9999999999999
\n
\n

\n Enter ISBN of book(s) - separate with commas (,)\n

\n \n read more about ISBN on Wikipedia\n \n
\n \n \n \n \n \n\n
\n \n
\n
\n\n
\n
\n\n

Did OttoBib help you? Then help us and Like us on Facebook!

\n
\n
\n\n\n
\n\n\n\n\n
\n \n\n \n", 200, null], [["http://www.ottobib.com/isbn/9782081336742/bibtex"], {"headers": null}, "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", 200, null]] \ No newline at end of file diff --git a/tests/test_apis_data.pickle b/tests/test_apis_data.pickle deleted file mode 100644 index 1d7a91495e82100eedec4a502ddacb63047dc61a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43888 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 y Date: Thu, 9 Aug 2018 20:54:44 +0200 Subject: [PATCH 16/20] Adds the statistics command. (Fixes #8) --- pubs/commands/__init__.py | 6 +++--- pubs/commands/statistics_cmd.py | 33 +++++++++++++++++++++++++++++++++ pubs/pubs_cmd.py | 5 +++-- tests/test_usecase.py | 15 +++++++++++++++ 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 pubs/commands/statistics_cmd.py diff --git a/pubs/commands/__init__.py b/pubs/commands/__init__.py index cd17fa3..ed5defa 100644 --- a/pubs/commands/__init__.py +++ b/pubs/commands/__init__.py @@ -6,9 +6,11 @@ from . import add_cmd from . import rename_cmd from . import remove_cmd from . import list_cmd +from . import edit_cmd +from . import tag_cmd +from . import statistics_cmd # doc from . import doc_cmd -from . import tag_cmd from . import note_cmd # bulk from . import export_cmd @@ -16,5 +18,3 @@ from . import import_cmd # bonus from . import websearch_cmd from . import url_cmd - -from . import edit_cmd diff --git a/pubs/commands/statistics_cmd.py b/pubs/commands/statistics_cmd.py new file mode 100644 index 0000000..5132010 --- /dev/null +++ b/pubs/commands/statistics_cmd.py @@ -0,0 +1,33 @@ +from ..repo import Repository +from ..uis import get_ui +from .. import color + + +def parser(subparsers, conf): + parser = subparsers.add_parser( + 'statistics', + help="show statistics on the repository.") + return parser + + +def command(conf, args): + ui = get_ui() + rp = Repository(conf) + papers = list(rp.all_papers()) + + paper_count = len(papers) + doc_count = sum([0 if p.docpath is None else 1 for p in papers]) + tag_count = len(list(rp.get_tags())) + papers_with_tags = sum([0 if p.tags else 1 for p in papers]) + + ui.message(color.dye_out('Repository statistics:', 'bold')) + ui.message('Total papers: {}, {} ({}) have a document attached'.format( + color.dye_out('{:d}'.format(paper_count), 'bgreen'), + color.dye_out('{:d}'.format(doc_count), 'bold'), + '{:.0f}%'.format(100. * doc_count / paper_count), + )) + ui.message('Total tags: {}, {} ({}) of papers have at least one tag'.format( + color.dye_out('{:d}'.format(tag_count), 'bgreen'), + color.dye_out('{:d}'.format(papers_with_tags), 'bold'), + '{:.0f}%'.format(100. * papers_with_tags / paper_count), + )) diff --git a/pubs/pubs_cmd.py b/pubs/pubs_cmd.py index 949fd4a..258cb85 100644 --- a/pubs/pubs_cmd.py +++ b/pubs/pubs_cmd.py @@ -20,9 +20,11 @@ CORE_CMDS = collections.OrderedDict([ ('rename', commands.rename_cmd), ('remove', commands.remove_cmd), ('list', commands.list_cmd), + ('edit', commands.edit_cmd), + ('tag', commands.tag_cmd), + ('statistics', commands.statistics_cmd), ('doc', commands.doc_cmd), - ('tag', commands.tag_cmd), ('note', commands.note_cmd), ('export', commands.export_cmd), @@ -30,7 +32,6 @@ CORE_CMDS = collections.OrderedDict([ ('websearch', commands.websearch_cmd), ('url', commands.url_cmd), - ('edit', commands.edit_cmd), ]) diff --git a/tests/test_usecase.py b/tests/test_usecase.py index 43cbf2c..11cce7a 100644 --- a/tests/test_usecase.py +++ b/tests/test_usecase.py @@ -925,6 +925,21 @@ class TestUsecase(DataCommandTestCase): self.assertFalse(os.path.isfile(self.default_conf_path)) self.assertTrue(os.path.isfile(alt_conf)) + def test_statistics(self): + cmds = ['pubs init', + 'pubs add data/pagerank.bib', + 'pubs add -d data/turing-mind-1950.pdf data/turing1950.bib', + 'pubs add data/martius.bib', + 'pubs add data/10.1371%2Fjournal.pone.0038236.bib', + 'pubs tag Page99 A+B', + 'pubs tag turing1950computing C', + 'pubs statistics', + ] + out = self.execute_cmds(cmds) + lines = out[-1].splitlines() + self.assertEqual(lines[0], 'Repository statistics:') + self.assertEqual(lines[1], 'Total papers: 4, 1 (25%) have a document attached') + self.assertEqual(lines[2], 'Total tags: 3, 2 (50%) of papers have at least one tag') @ddt.ddt From 30a7094eaf341a57b575ef1328c944f3f27c4c76 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Tue, 14 Aug 2018 17:05:11 +0900 Subject: [PATCH 17/20] add arXiv tests --- .travis.yml | 6 +- pubs/apis.py | 2 +- tests/mock_requests.py | 27 +++++- tests/test_apis.py | 30 ++++++ tests/test_apis_data.json | 190 +++++++++++++++++++++++++++++++++++++- 5 files changed, 246 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 16e69a7..f2be365 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,5 @@ install: # command to run tests script: - - export PUBS_TESTS_MODE=ONLINE - - python setup.py test - - export PUBS_TESTS_MODE=MOCK - - python setup.py test + - PUBS_TESTS_MODE=MOCK python setup.py test + - PUBS_TESTS_MODE=COLLECT python setup.py test diff --git a/pubs/apis.py b/pubs/apis.py index 6f487ca..78f9190 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -192,7 +192,7 @@ def arxiv2bibtex(arxiv_id, try_doi=True, ui=None): if not _is_arxiv_oldstyle(entry_id): db.entries[0]['eprintclass'] = entry['arxiv_primary_category']['term'] if 'arxiv_doi' in entry: - db.entries[0]['arxiv_doi'] = arxiv_doi + db.entries[0]['arxiv_doi'] = entry['arxiv_doi'] bibtex = bibtexparser.dumps(db) return bibtex diff --git a/tests/mock_requests.py b/tests/mock_requests.py index 3eb72ca..9fc765f 100644 --- a/tests/mock_requests.py +++ b/tests/mock_requests.py @@ -23,6 +23,7 @@ running tests on Travis for instance. import os import json +import mock import requests @@ -31,6 +32,7 @@ _orgininal_requests_get = requests.get _collected_responses = [] _data_filepath = os.path.join(os.path.dirname(__file__), 'test_apis_data.json') + class MockingResponse: def __init__(self, text, status_code=200, error_msg=None): self.text = text @@ -43,6 +45,19 @@ class MockingResponse: raise requests.exceptions.RequestException(self.error_msg) +def intercept_text(text): + try: + if '10.1103/PhysRevD.89.084044' in text: + # replace with wrong DOI + text = text.replace('PhysRevD', 'INVALIDDOI') + except TypeError: + if b'10.1103/PhysRevD.89.084044' in text: + # replace with wrong DOI + text = text.replace(b'PhysRevD', b'INVALIDDOI') + + return text + + mode = os.environ.get('PUBS_TESTS_MODE', 'MOCK') if mode == 'MOCK': @@ -56,7 +71,7 @@ if mode == 'MOCK': return MockingResponse(text, status_code, error_msg) raise KeyError(('No stub data found for requests.get({}, {}).\n You may' ' need to update the mock data. Look at the ' - 'tests/mock_requests.py file for explanation').format(args, kwargs)) + 'tests/mock_requests.py file for an explanation').format(args, kwargs)) elif mode == 'COLLECT': @@ -74,12 +89,18 @@ elif mode == 'COLLECT': # clear how to run once after all the tests # have run. If you figure it out... + text = intercept_text(text) return MockingResponse(text, status_code, error_msg) def _save_collected_responses(): with open(os.path.join(_data_filepath), 'w') as fd: - json.dump(_collected_responses, fd) + json.dump(_collected_responses, fd, indent=2) elif mode == 'ONLINE': def mock_requests_get(*args, **kwargs): - return _orgininal_requests_get(*args, **kwargs) + # with mock.patch('requests.Response.text', new_callable=mock.PropertyMock) as mock_text: + r = _orgininal_requests_get(*args, **kwargs) + r._content = intercept_text(r.content) + # print(r.content.__class__) + # mock_text.return_value = intercept_text(r.text) + return r diff --git a/tests/test_apis.py b/tests/test_apis.py index 67a76b5..b870f63 100644 --- a/tests/test_apis.py +++ b/tests/test_apis.py @@ -104,6 +104,36 @@ class TestArxiv2Bibtex(APITests): entry['title'], 'The entropy formula for the Ricci flow and its geometric applications') + @mock.patch('pubs.apis.requests.get', side_effect=mock_requests.mock_requests_get) + def test_arxiv_wrong_id(self, reqget): + with self.assertRaises(ReferenceNotFoundError): + bib = arxiv2bibtex('INVALIDID') + + @mock.patch('pubs.apis.requests.get', side_effect=mock_requests.mock_requests_get) + def test_arxiv_wrong_doi(self, reqget): + bib = arxiv2bibtex('1312.2021') + b = self.endecoder.decode_bibdata(bib) + entry = b[list(b)[0]] + self.assertEqual(entry['arxiv_doi'], '10.1103/INVALIDDOI.89.084044') + + @mock.patch('pubs.apis.requests.get', side_effect=mock_requests.mock_requests_get) + def test_arxiv_good_doi(self, reqget): + """Get the DOI bibtex instead of the arXiv one if possible""" + bib = arxiv2bibtex('1710.08557') + b = self.endecoder.decode_bibdata(bib) + entry = b[list(b)[0]] + self.assertTrue(not 'arxiv_doi' in entry) + self.assertEqual(entry['doi'], '10.1186/s12984-017-0305-3') + self.assertEqual(entry['title'].lower(), 'on neuromechanical approaches for the study of biological and robotic grasp and manipulation') + + @mock.patch('pubs.apis.requests.get', side_effect=mock_requests.mock_requests_get) + def test_arxiv_good_doi_force_arxiv(self, reqget): + bib = arxiv2bibtex('1710.08557', try_doi=False) + b = self.endecoder.decode_bibdata(bib) + entry = b[list(b)[0]] + self.assertEqual(entry['arxiv_doi'], '10.1186/s12984-017-0305-3') + self.assertEqual(entry['title'].lower(), 'on neuromechanical approaches for the study of biological grasp and\nmanipulation') + class TestArxiv2BibtexLocal(unittest.TestCase): """Test arXiv 2 Bibtex connection; those tests don't require a connection""" diff --git a/tests/test_apis_data.json b/tests/test_apis_data.json index 42daa8c..6ce46ae 100644 --- a/tests/test_apis_data.json +++ b/tests/test_apis_data.json @@ -1 +1,189 @@ -[[["https://export.arxiv.org/api/query?id_list=astro-ph/9812133"], {}, "\n\n \n ArXiv Query: search_query=&id_list=astro-ph/9812133&start=0&max_results=10\n http://arxiv.org/api/SfKekabpSjI/htnxCLpK3q9AsUs\n 2018-08-09T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/astro-ph/9812133v1\n 1998-12-08T03:27:34Z\n 1998-12-08T03:27:34Z\n Measurements of Omega and Lambda from 42 High-Redshift Supernovae\n We report measurements of the mass density, Omega_M, and\ncosmological-constant energy density, Omega_Lambda, of the universe based on\nthe analysis of 42 Type Ia supernovae discovered by the Supernova Cosmology\nProject. The magnitude-redshift data for these SNe, at redshifts between 0.18\nand 0.83, are fit jointly with a set of SNe from the Calan/Tololo Supernova\nSurvey, at redshifts below 0.1, to yield values for the cosmological\nparameters. All SN peak magnitudes are standardized using a SN Ia lightcurve\nwidth-luminosity relation. The measurement yields a joint probability\ndistribution of the cosmological parameters that is approximated by the\nrelation 0.8 Omega_M - 0.6 Omega_Lambda ~= -0.2 +/- 0.1 in the region of\ninterest (Omega_M <~ 1.5). For a flat (Omega_M + Omega_Lambda = 1) cosmology we\nfind Omega_M = 0.28{+0.09,-0.08} (1 sigma statistical) {+0.05,-0.04}\n(identified systematics). The data are strongly inconsistent with a Lambda = 0\nflat cosmology, the simplest inflationary universe model. An open, Lambda = 0\ncosmology also does not fit the data well: the data indicate that the\ncosmological constant is non-zero and positive, with a confidence of P(Lambda >\n0) = 99%, including the identified systematic uncertainties. The best-fit age\nof the universe relative to the Hubble time is t_0 = 14.9{+1.4,-1.1} (0.63/h)\nGyr for a flat cosmology. The size of our sample allows us to perform a variety\nof statistical tests to check for possible systematic errors and biases. We\nfind no significant differences in either the host reddening distribution or\nMalmquist bias between the low-redshift Calan/Tololo sample and our\nhigh-redshift sample. The conclusions are robust whether or not a\nwidth-luminosity relation is used to standardize the SN peak magnitudes.\n\n \n S. Perlmutter\n The Supernova Cosmology Project\n \n \n G. Aldering\n The Supernova Cosmology Project\n \n \n G. Goldhaber\n The Supernova Cosmology Project\n \n \n R. A. Knop\n The Supernova Cosmology Project\n \n \n P. Nugent\n The Supernova Cosmology Project\n \n \n P. G. Castro\n The Supernova Cosmology Project\n \n \n S. Deustua\n The Supernova Cosmology Project\n \n \n S. Fabbro\n The Supernova Cosmology Project\n \n \n A. Goobar\n The Supernova Cosmology Project\n \n \n D. E. Groom\n The Supernova Cosmology Project\n \n \n I. M. Hook\n The Supernova Cosmology Project\n \n \n A. G. Kim\n The Supernova Cosmology Project\n \n \n M. Y. Kim\n The Supernova Cosmology Project\n \n \n J. C. Lee\n The Supernova Cosmology Project\n \n \n N. J. Nunes\n The Supernova Cosmology Project\n \n \n R. Pain\n The Supernova Cosmology Project\n \n \n C. R. Pennypacker\n The Supernova Cosmology Project\n \n \n R. Quimby\n The Supernova Cosmology Project\n \n \n C. Lidman\n The Supernova Cosmology Project\n \n \n R. S. Ellis\n The Supernova Cosmology Project\n \n \n M. Irwin\n The Supernova Cosmology Project\n \n \n R. G. McMahon\n The Supernova Cosmology Project\n \n \n P. Ruiz-Lapuente\n The Supernova Cosmology Project\n \n \n N. Walton\n The Supernova Cosmology Project\n \n \n B. Schaefer\n The Supernova Cosmology Project\n \n \n B. J. Boyle\n The Supernova Cosmology Project\n \n \n A. V. Filippenko\n The Supernova Cosmology Project\n \n \n T. Matheson\n The Supernova Cosmology Project\n \n \n A. S. Fruchter\n The Supernova Cosmology Project\n \n \n N. Panagia\n The Supernova Cosmology Project\n \n \n H. J. M. Newberg\n The Supernova Cosmology Project\n \n \n W. J. Couch\n The Supernova Cosmology Project\n \n 10.1086/307221\n \n 21 pages and 10 figures. Accepted for publication in the\n Astrophysical Journal. Individual color figures, supplementary tables, and\n preprint also available at http://www-supernova.lbl.gov/\n Astrophys.J.517:565-586,1999\n \n \n \n \n \n \n \n\n", 200, null], [["http://dx.doi.org/10.1086/307221"], {"headers": {"accept": "application/x-bibtex"}}, "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", 200, null], [["https://export.arxiv.org/api/query?id_list=astro-ph/9812133"], {}, "\n\n \n ArXiv Query: search_query=&id_list=astro-ph/9812133&start=0&max_results=10\n http://arxiv.org/api/SfKekabpSjI/htnxCLpK3q9AsUs\n 2018-08-09T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/astro-ph/9812133v1\n 1998-12-08T03:27:34Z\n 1998-12-08T03:27:34Z\n Measurements of Omega and Lambda from 42 High-Redshift Supernovae\n We report measurements of the mass density, Omega_M, and\ncosmological-constant energy density, Omega_Lambda, of the universe based on\nthe analysis of 42 Type Ia supernovae discovered by the Supernova Cosmology\nProject. The magnitude-redshift data for these SNe, at redshifts between 0.18\nand 0.83, are fit jointly with a set of SNe from the Calan/Tololo Supernova\nSurvey, at redshifts below 0.1, to yield values for the cosmological\nparameters. All SN peak magnitudes are standardized using a SN Ia lightcurve\nwidth-luminosity relation. The measurement yields a joint probability\ndistribution of the cosmological parameters that is approximated by the\nrelation 0.8 Omega_M - 0.6 Omega_Lambda ~= -0.2 +/- 0.1 in the region of\ninterest (Omega_M <~ 1.5). For a flat (Omega_M + Omega_Lambda = 1) cosmology we\nfind Omega_M = 0.28{+0.09,-0.08} (1 sigma statistical) {+0.05,-0.04}\n(identified systematics). The data are strongly inconsistent with a Lambda = 0\nflat cosmology, the simplest inflationary universe model. An open, Lambda = 0\ncosmology also does not fit the data well: the data indicate that the\ncosmological constant is non-zero and positive, with a confidence of P(Lambda >\n0) = 99%, including the identified systematic uncertainties. The best-fit age\nof the universe relative to the Hubble time is t_0 = 14.9{+1.4,-1.1} (0.63/h)\nGyr for a flat cosmology. The size of our sample allows us to perform a variety\nof statistical tests to check for possible systematic errors and biases. We\nfind no significant differences in either the host reddening distribution or\nMalmquist bias between the low-redshift Calan/Tololo sample and our\nhigh-redshift sample. The conclusions are robust whether or not a\nwidth-luminosity relation is used to standardize the SN peak magnitudes.\n\n \n S. Perlmutter\n The Supernova Cosmology Project\n \n \n G. Aldering\n The Supernova Cosmology Project\n \n \n G. Goldhaber\n The Supernova Cosmology Project\n \n \n R. A. Knop\n The Supernova Cosmology Project\n \n \n P. Nugent\n The Supernova Cosmology Project\n \n \n P. G. Castro\n The Supernova Cosmology Project\n \n \n S. Deustua\n The Supernova Cosmology Project\n \n \n S. Fabbro\n The Supernova Cosmology Project\n \n \n A. Goobar\n The Supernova Cosmology Project\n \n \n D. E. Groom\n The Supernova Cosmology Project\n \n \n I. M. Hook\n The Supernova Cosmology Project\n \n \n A. G. Kim\n The Supernova Cosmology Project\n \n \n M. Y. Kim\n The Supernova Cosmology Project\n \n \n J. C. Lee\n The Supernova Cosmology Project\n \n \n N. J. Nunes\n The Supernova Cosmology Project\n \n \n R. Pain\n The Supernova Cosmology Project\n \n \n C. R. Pennypacker\n The Supernova Cosmology Project\n \n \n R. Quimby\n The Supernova Cosmology Project\n \n \n C. Lidman\n The Supernova Cosmology Project\n \n \n R. S. Ellis\n The Supernova Cosmology Project\n \n \n M. Irwin\n The Supernova Cosmology Project\n \n \n R. G. McMahon\n The Supernova Cosmology Project\n \n \n P. Ruiz-Lapuente\n The Supernova Cosmology Project\n \n \n N. Walton\n The Supernova Cosmology Project\n \n \n B. Schaefer\n The Supernova Cosmology Project\n \n \n B. J. Boyle\n The Supernova Cosmology Project\n \n \n A. V. Filippenko\n The Supernova Cosmology Project\n \n \n T. Matheson\n The Supernova Cosmology Project\n \n \n A. S. Fruchter\n The Supernova Cosmology Project\n \n \n N. Panagia\n The Supernova Cosmology Project\n \n \n H. J. M. Newberg\n The Supernova Cosmology Project\n \n \n W. J. Couch\n The Supernova Cosmology Project\n \n 10.1086/307221\n \n 21 pages and 10 figures. Accepted for publication in the\n Astrophysical Journal. Individual color figures, supplementary tables, and\n preprint also available at http://www-supernova.lbl.gov/\n Astrophys.J.517:565-586,1999\n \n \n \n \n \n \n \n\n", 200, null], [["http://dx.doi.org/10.1086/307221"], {"headers": {"accept": "application/x-bibtex"}}, "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", 200, null], [["https://export.arxiv.org/api/query?id_list=math/0211159"], {}, "\n\n \n ArXiv Query: search_query=&id_list=math/0211159&start=0&max_results=10\n http://arxiv.org/api/4nVRTcAL5Np4oaGFQnqVPG0+c5k\n 2018-08-09T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/math/0211159v1\n 2002-11-11T16:11:49Z\n 2002-11-11T16:11:49Z\n The entropy formula for the Ricci flow and its geometric applications\n We present a monotonic expression for the Ricci flow, valid in all dimensions\nand without curvature assumptions. It is interpreted as an entropy for a\ncertain canonical ensemble. Several geometric applications are given. In\nparticular, (1) Ricci flow, considered on the space of riemannian metrics\nmodulo diffeomorphism and scaling, has no nontrivial periodic orbits (that is,\nother than fixed points); (2) In a region, where singularity is forming in\nfinite time, the injectivity radius is controlled by the curvature; (3) Ricci\nflow can not quickly turn an almost euclidean region into a very curved one, no\nmatter what happens far away. We also verify several assertions related to\nRichard Hamilton's program for the proof of Thurston geometrization conjecture\nfor closed three-manifolds, and give a sketch of an eclectic proof of this\nconjecture, making use of earlier results on collapsing with local lower\ncurvature bound.\n\n \n Grisha Perelman\n \n 39 pages\n \n \n \n \n \n \n\n", 200, null], [["http://dx.doi.org/10.1007/BF01700692"], {"headers": {"accept": "application/x-bibtex"}}, "@article{G_del_1931,\n\tdoi = {10.1007/bf01700692},\n\turl = {https://doi.org/10.1007%2Fbf01700692},\n\tyear = 1931,\n\tmonth = {dec},\n\tpublisher = {Springer Nature},\n\tvolume = {38-38},\n\tnumber = {1},\n\tpages = {173--198},\n\tauthor = {Kurt G\u00f6del},\n\ttitle = {\u00dcber formal unentscheidbare S\u00e4tze der Principia Mathematica und verwandter Systeme I},\n\tjournal = {Monatshefte f\u00fcr Mathematik und Physik}\n}", 200, null], [["http://dx.doi.org/999999"], {"headers": {"accept": "application/x-bibtex"}}, "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10/999999

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", 404, "404 Client Error: for url: http://dx.doi.org/999999"], [["http://dx.doi.org/10.1007/BF01700692"], {"headers": {"accept": "application/x-bibtex"}}, "@article{G_del_1931,\n\tdoi = {10.1007/bf01700692},\n\turl = {https://doi.org/10.1007%2Fbf01700692},\n\tyear = 1931,\n\tmonth = {dec},\n\tpublisher = {Springer Nature},\n\tvolume = {38-38},\n\tnumber = {1},\n\tpages = {173--198},\n\tauthor = {Kurt G\u00f6del},\n\ttitle = {\u00dcber formal unentscheidbare S\u00e4tze der Principia Mathematica und verwandter Systeme I},\n\tjournal = {Monatshefte f\u00fcr Mathematik und Physik}\n}", 200, null], [["http://www.ottobib.com/isbn/9782081336742/bibtex"], {"headers": null}, "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", 200, null], [["http://www.ottobib.com/isbn/9999999999999/bibtex"], {"headers": null}, "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n\t

OttoBib

\n\t

Make a bibliography or works cited with just an ISBN. It's free, easy and FAST

\n\t

\n\t about ottobib and history\n\t \n\t

\n\t \n

\n\t
\n
\n\n
\n
\n\n
No Results for 9999999999999
\n
\n

\n Enter ISBN of book(s) - separate with commas (,)\n

\n \n read more about ISBN on Wikipedia\n \n
\n \n \n \n \n \n\n
\n \n
\n
\n\n
\n
\n\n

Did OttoBib help you? Then help us and Like us on Facebook!

\n
\n
\n\n\n
\n\n\n\n\n
\n \n\n \n", 200, null], [["http://www.ottobib.com/isbn/9782081336742/bibtex"], {"headers": null}, "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", 200, null]] \ No newline at end of file +[ + [ + [ + "http://dx.doi.org/10.1007/BF01700692" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "@article{G_del_1931,\n\tdoi = {10.1007/bf01700692},\n\turl = {https://doi.org/10.1007%2Fbf01700692},\n\tyear = 1931,\n\tmonth = {dec},\n\tpublisher = {Springer Nature},\n\tvolume = {38-38},\n\tnumber = {1},\n\tpages = {173--198},\n\tauthor = {Kurt G\u00f6del},\n\ttitle = {\u00dcber formal unentscheidbare S\u00e4tze der Principia Mathematica und verwandter Systeme I},\n\tjournal = {Monatshefte f\u00fcr Mathematik und Physik}\n}", + 200, + null + ], + [ + [ + "http://dx.doi.org/999999" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10/999999

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", + 404, + "404 Client Error: for url: http://dx.doi.org/999999" + ], + [ + [ + "http://dx.doi.org/10.1007/BF01700692" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "@article{G_del_1931,\n\tdoi = {10.1007/bf01700692},\n\turl = {https://doi.org/10.1007%2Fbf01700692},\n\tyear = 1931,\n\tmonth = {dec},\n\tpublisher = {Springer Nature},\n\tvolume = {38-38},\n\tnumber = {1},\n\tpages = {173--198},\n\tauthor = {Kurt G\u00f6del},\n\ttitle = {\u00dcber formal unentscheidbare S\u00e4tze der Principia Mathematica und verwandter Systeme I},\n\tjournal = {Monatshefte f\u00fcr Mathematik und Physik}\n}", + 200, + null + ], + [ + [ + "http://www.ottobib.com/isbn/9782081336742/bibtex" + ], + { + "headers": null + }, + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", + 200, + null + ], + [ + [ + "http://www.ottobib.com/isbn/9999999999999/bibtex" + ], + { + "headers": null + }, + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n\t

OttoBib

\n\t

Make a bibliography or works cited with just an ISBN. It's free, easy and FAST

\n\t

\n\t about ottobib and history\n\t \n\t

\n\t \n

\n\t
\n
\n\n
\n
\n\n
No Results for 9999999999999
\n
\n

\n Enter ISBN of book(s) - separate with commas (,)\n

\n \n read more about ISBN on Wikipedia\n \n
\n \n \n \n \n \n\n
\n \n
\n
\n\n
\n
\n\n

Did OttoBib help you? Then help us and Like us on Facebook!

\n
\n
\n\n\n
\n\n\n\n\n
\n \n\n \n", + 200, + null + ], + [ + [ + "http://www.ottobib.com/isbn/9782081336742/bibtex" + ], + { + "headers": null + }, + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", + 200, + null + ], + [ + [ + "https://export.arxiv.org/api/query?id_list=1710.08557" + ], + {}, + "\n\n \n ArXiv Query: search_query=&id_list=1710.08557&start=0&max_results=10\n http://arxiv.org/api/bNB5RPNlUYbELau5YJ4IzaIq1x8\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1710.08557v1\n 2017-10-24T00:21:32Z\n 2017-10-24T00:21:32Z\n On Neuromechanical Approaches for the Study of Biological Grasp and\n Manipulation\n Biological and robotic grasp and manipulation are undeniably similar at the\nlevel of mechanical task performance. However, their underlying fundamental\nbiological vs. engineering mechanisms are, by definition, dramatically\ndifferent and can even be antithetical. Even our approach to each is\ndiametrically opposite: inductive science for the study of biological systems\nvs. engineering synthesis for the design and construction of robotic systems.\nThe past 20 years have seen several conceptual advances in both fields and the\nquest to unify them. Chief among them is the reluctant recognition that their\nunderlying fundamental mechanisms may actually share limited common ground,\nwhile exhibiting many fundamental differences. This recognition is particularly\nliberating because it allows us to resolve and move beyond multiple paradoxes\nand contradictions that arose from the initial reasonable assumption of a large\ncommon ground. Here, we begin by introducing the perspective of neuromechanics,\nwhich emphasizes that real-world behavior emerges from the intimate\ninteractions among the physical structure of the system, the mechanical\nrequirements of a task, the feasible neural control actions to produce it, and\nthe ability of the neuromuscular system to adapt through interactions with the\nenvironment. This allows us to articulate a succinct overview of a few salient\nconceptual paradoxes and contradictions regarding under-determined vs.\nover-determined mechanics, under- vs. over-actuated control, prescribed vs.\nemergent function, learning vs. implementation vs. adaptation, prescriptive vs.\ndescriptive synergies, and optimal vs. habitual performance. We conclude by\npresenting open questions and suggesting directions for future research. We\nhope this frank assessment of the state-of-the-art will encourage and guide\nthese communities to continue to interact and make progress in these important\nareas.\n\n \n Francisco J Valero-Cuevas\n \n \n Marco Santello\n \n 10.1186/s12984-017-0305-3\n \n Journal of NeuroEngineering and Rehabilitation, 2017\n \n \n \n \n \n\n", + 200, + null + ], + [ + [ + "http://dx.doi.org/10.1186/s12984-017-0305-3" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "@article{Valero_Cuevas_2017,\n\tdoi = {10.1186/s12984-017-0305-3},\n\turl = {https://doi.org/10.1186%2Fs12984-017-0305-3},\n\tyear = 2017,\n\tmonth = {oct},\n\tpublisher = {Springer Nature},\n\tvolume = {14},\n\tnumber = {1},\n\tauthor = {Francisco J. Valero-Cuevas and Marco Santello},\n\ttitle = {On neuromechanical approaches for the study of biological and robotic grasp and manipulation},\n\tjournal = {Journal of {NeuroEngineering} and Rehabilitation}\n}", + 200, + null + ], + [ + [ + "https://export.arxiv.org/api/query?id_list=1710.08557" + ], + {}, + "\n\n \n ArXiv Query: search_query=&id_list=1710.08557&start=0&max_results=10\n http://arxiv.org/api/bNB5RPNlUYbELau5YJ4IzaIq1x8\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1710.08557v1\n 2017-10-24T00:21:32Z\n 2017-10-24T00:21:32Z\n On Neuromechanical Approaches for the Study of Biological Grasp and\n Manipulation\n Biological and robotic grasp and manipulation are undeniably similar at the\nlevel of mechanical task performance. However, their underlying fundamental\nbiological vs. engineering mechanisms are, by definition, dramatically\ndifferent and can even be antithetical. Even our approach to each is\ndiametrically opposite: inductive science for the study of biological systems\nvs. engineering synthesis for the design and construction of robotic systems.\nThe past 20 years have seen several conceptual advances in both fields and the\nquest to unify them. Chief among them is the reluctant recognition that their\nunderlying fundamental mechanisms may actually share limited common ground,\nwhile exhibiting many fundamental differences. This recognition is particularly\nliberating because it allows us to resolve and move beyond multiple paradoxes\nand contradictions that arose from the initial reasonable assumption of a large\ncommon ground. Here, we begin by introducing the perspective of neuromechanics,\nwhich emphasizes that real-world behavior emerges from the intimate\ninteractions among the physical structure of the system, the mechanical\nrequirements of a task, the feasible neural control actions to produce it, and\nthe ability of the neuromuscular system to adapt through interactions with the\nenvironment. This allows us to articulate a succinct overview of a few salient\nconceptual paradoxes and contradictions regarding under-determined vs.\nover-determined mechanics, under- vs. over-actuated control, prescribed vs.\nemergent function, learning vs. implementation vs. adaptation, prescriptive vs.\ndescriptive synergies, and optimal vs. habitual performance. We conclude by\npresenting open questions and suggesting directions for future research. We\nhope this frank assessment of the state-of-the-art will encourage and guide\nthese communities to continue to interact and make progress in these important\nareas.\n\n \n Francisco J Valero-Cuevas\n \n \n Marco Santello\n \n 10.1186/s12984-017-0305-3\n \n Journal of NeuroEngineering and Rehabilitation, 2017\n \n \n \n \n \n\n", + 200, + null + ], + [ + [ + "https://export.arxiv.org/api/query?id_list=1312.2021" + ], + {}, + "\n\n \n ArXiv Query: search_query=&id_list=1312.2021&start=0&max_results=10\n http://arxiv.org/api/eXBvi61X4ShcFWF7lwJgRo7KSFk\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1312.2021v1\n 2013-12-06T21:33:40Z\n 2013-12-06T21:33:40Z\n Living with the Wrong Sign\n We describe a UV complete asymptotically fragile Lorentz-invariant theory\nexhibiting superluminal signal propagation. Its low energy effective action\ncontains \"wrong\" sign higher dimensional operators. Nevertheless, the theory\ngives rise to an S-matrix, which is defined at all energies. As expected for a\nnon-local theory, the corresponding scattering amplitudes are not exponentially\nbounded on the physical sheet, but otherwise are healthy. We study some of the\nphysical consequences of this S-matrix.\n\n \n Patrick Cooper\n \n \n Sergei Dubovsky\n \n \n Ali Mohsen\n \n 10.1103/PhysRevD.89.084044\n \n Phys. Rev. D 89, 084044 (2014)\n \n \n \n \n \n \n\n", + 200, + null + ], + [ + [ + "http://dx.doi.org/10.1103/INVALIDDOI.89.084044" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10.1103/INVALIDDOI.89.084044

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", + 404, + "404 Client Error: for url: http://dx.doi.org/10.1103/INVALIDDOI.89.084044" + ], + [ + [ + "https://export.arxiv.org/api/query?id_list=INVALIDID" + ], + {}, + "\n\n \n ArXiv Query: search_query=&id_list=INVALIDID\n http://arxiv.org/api//TMQrv7hMz9PNtlUyGrhFtefYFQ\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 1\n \n http://arxiv.org/api/errors#incorrect_id_format_for_INVALIDID\n Error\n incorrect id format for INVALIDID\n 2018-08-14T00:00:00-04:00\n \n \n arXiv api core\n \n \n\n", + 400, + "400 Client Error: Bad Request for url: https://export.arxiv.org/api/query?id_list=INVALIDID" + ], + [ + [ + "https://export.arxiv.org/api/query?id_list=astro-ph/9812133" + ], + {}, + "\n\n \n ArXiv Query: search_query=&id_list=astro-ph/9812133&start=0&max_results=10\n http://arxiv.org/api/SfKekabpSjI/htnxCLpK3q9AsUs\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/astro-ph/9812133v1\n 1998-12-08T03:27:34Z\n 1998-12-08T03:27:34Z\n Measurements of Omega and Lambda from 42 High-Redshift Supernovae\n We report measurements of the mass density, Omega_M, and\ncosmological-constant energy density, Omega_Lambda, of the universe based on\nthe analysis of 42 Type Ia supernovae discovered by the Supernova Cosmology\nProject. The magnitude-redshift data for these SNe, at redshifts between 0.18\nand 0.83, are fit jointly with a set of SNe from the Calan/Tololo Supernova\nSurvey, at redshifts below 0.1, to yield values for the cosmological\nparameters. All SN peak magnitudes are standardized using a SN Ia lightcurve\nwidth-luminosity relation. The measurement yields a joint probability\ndistribution of the cosmological parameters that is approximated by the\nrelation 0.8 Omega_M - 0.6 Omega_Lambda ~= -0.2 +/- 0.1 in the region of\ninterest (Omega_M <~ 1.5). For a flat (Omega_M + Omega_Lambda = 1) cosmology we\nfind Omega_M = 0.28{+0.09,-0.08} (1 sigma statistical) {+0.05,-0.04}\n(identified systematics). The data are strongly inconsistent with a Lambda = 0\nflat cosmology, the simplest inflationary universe model. An open, Lambda = 0\ncosmology also does not fit the data well: the data indicate that the\ncosmological constant is non-zero and positive, with a confidence of P(Lambda >\n0) = 99%, including the identified systematic uncertainties. The best-fit age\nof the universe relative to the Hubble time is t_0 = 14.9{+1.4,-1.1} (0.63/h)\nGyr for a flat cosmology. The size of our sample allows us to perform a variety\nof statistical tests to check for possible systematic errors and biases. We\nfind no significant differences in either the host reddening distribution or\nMalmquist bias between the low-redshift Calan/Tololo sample and our\nhigh-redshift sample. The conclusions are robust whether or not a\nwidth-luminosity relation is used to standardize the SN peak magnitudes.\n\n \n S. Perlmutter\n The Supernova Cosmology Project\n \n \n G. Aldering\n The Supernova Cosmology Project\n \n \n G. Goldhaber\n The Supernova Cosmology Project\n \n \n R. A. Knop\n The Supernova Cosmology Project\n \n \n P. Nugent\n The Supernova Cosmology Project\n \n \n P. G. Castro\n The Supernova Cosmology Project\n \n \n S. Deustua\n The Supernova Cosmology Project\n \n \n S. Fabbro\n The Supernova Cosmology Project\n \n \n A. Goobar\n The Supernova Cosmology Project\n \n \n D. E. Groom\n The Supernova Cosmology Project\n \n \n I. M. Hook\n The Supernova Cosmology Project\n \n \n A. G. Kim\n The Supernova Cosmology Project\n \n \n M. Y. Kim\n The Supernova Cosmology Project\n \n \n J. C. Lee\n The Supernova Cosmology Project\n \n \n N. J. Nunes\n The Supernova Cosmology Project\n \n \n R. Pain\n The Supernova Cosmology Project\n \n \n C. R. Pennypacker\n The Supernova Cosmology Project\n \n \n R. Quimby\n The Supernova Cosmology Project\n \n \n C. Lidman\n The Supernova Cosmology Project\n \n \n R. S. Ellis\n The Supernova Cosmology Project\n \n \n M. Irwin\n The Supernova Cosmology Project\n \n \n R. G. McMahon\n The Supernova Cosmology Project\n \n \n P. Ruiz-Lapuente\n The Supernova Cosmology Project\n \n \n N. Walton\n The Supernova Cosmology Project\n \n \n B. Schaefer\n The Supernova Cosmology Project\n \n \n B. J. Boyle\n The Supernova Cosmology Project\n \n \n A. V. Filippenko\n The Supernova Cosmology Project\n \n \n T. Matheson\n The Supernova Cosmology Project\n \n \n A. S. Fruchter\n The Supernova Cosmology Project\n \n \n N. Panagia\n The Supernova Cosmology Project\n \n \n H. J. M. Newberg\n The Supernova Cosmology Project\n \n \n W. J. Couch\n The Supernova Cosmology Project\n \n 10.1086/307221\n \n 21 pages and 10 figures. Accepted for publication in the\n Astrophysical Journal. Individual color figures, supplementary tables, and\n preprint also available at http://www-supernova.lbl.gov/\n Astrophys.J.517:565-586,1999\n \n \n \n \n \n \n \n\n", + 200, + null + ], + [ + [ + "http://dx.doi.org/10.1086/307221" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", + 200, + null + ], + [ + [ + "https://export.arxiv.org/api/query?id_list=astro-ph/9812133" + ], + {}, + "\n\n \n ArXiv Query: search_query=&id_list=astro-ph/9812133&start=0&max_results=10\n http://arxiv.org/api/SfKekabpSjI/htnxCLpK3q9AsUs\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/astro-ph/9812133v1\n 1998-12-08T03:27:34Z\n 1998-12-08T03:27:34Z\n Measurements of Omega and Lambda from 42 High-Redshift Supernovae\n We report measurements of the mass density, Omega_M, and\ncosmological-constant energy density, Omega_Lambda, of the universe based on\nthe analysis of 42 Type Ia supernovae discovered by the Supernova Cosmology\nProject. The magnitude-redshift data for these SNe, at redshifts between 0.18\nand 0.83, are fit jointly with a set of SNe from the Calan/Tololo Supernova\nSurvey, at redshifts below 0.1, to yield values for the cosmological\nparameters. All SN peak magnitudes are standardized using a SN Ia lightcurve\nwidth-luminosity relation. The measurement yields a joint probability\ndistribution of the cosmological parameters that is approximated by the\nrelation 0.8 Omega_M - 0.6 Omega_Lambda ~= -0.2 +/- 0.1 in the region of\ninterest (Omega_M <~ 1.5). For a flat (Omega_M + Omega_Lambda = 1) cosmology we\nfind Omega_M = 0.28{+0.09,-0.08} (1 sigma statistical) {+0.05,-0.04}\n(identified systematics). The data are strongly inconsistent with a Lambda = 0\nflat cosmology, the simplest inflationary universe model. An open, Lambda = 0\ncosmology also does not fit the data well: the data indicate that the\ncosmological constant is non-zero and positive, with a confidence of P(Lambda >\n0) = 99%, including the identified systematic uncertainties. The best-fit age\nof the universe relative to the Hubble time is t_0 = 14.9{+1.4,-1.1} (0.63/h)\nGyr for a flat cosmology. The size of our sample allows us to perform a variety\nof statistical tests to check for possible systematic errors and biases. We\nfind no significant differences in either the host reddening distribution or\nMalmquist bias between the low-redshift Calan/Tololo sample and our\nhigh-redshift sample. The conclusions are robust whether or not a\nwidth-luminosity relation is used to standardize the SN peak magnitudes.\n\n \n S. Perlmutter\n The Supernova Cosmology Project\n \n \n G. Aldering\n The Supernova Cosmology Project\n \n \n G. Goldhaber\n The Supernova Cosmology Project\n \n \n R. A. Knop\n The Supernova Cosmology Project\n \n \n P. Nugent\n The Supernova Cosmology Project\n \n \n P. G. Castro\n The Supernova Cosmology Project\n \n \n S. Deustua\n The Supernova Cosmology Project\n \n \n S. Fabbro\n The Supernova Cosmology Project\n \n \n A. Goobar\n The Supernova Cosmology Project\n \n \n D. E. Groom\n The Supernova Cosmology Project\n \n \n I. M. Hook\n The Supernova Cosmology Project\n \n \n A. G. Kim\n The Supernova Cosmology Project\n \n \n M. Y. Kim\n The Supernova Cosmology Project\n \n \n J. C. Lee\n The Supernova Cosmology Project\n \n \n N. J. Nunes\n The Supernova Cosmology Project\n \n \n R. Pain\n The Supernova Cosmology Project\n \n \n C. R. Pennypacker\n The Supernova Cosmology Project\n \n \n R. Quimby\n The Supernova Cosmology Project\n \n \n C. Lidman\n The Supernova Cosmology Project\n \n \n R. S. Ellis\n The Supernova Cosmology Project\n \n \n M. Irwin\n The Supernova Cosmology Project\n \n \n R. G. McMahon\n The Supernova Cosmology Project\n \n \n P. Ruiz-Lapuente\n The Supernova Cosmology Project\n \n \n N. Walton\n The Supernova Cosmology Project\n \n \n B. Schaefer\n The Supernova Cosmology Project\n \n \n B. J. Boyle\n The Supernova Cosmology Project\n \n \n A. V. Filippenko\n The Supernova Cosmology Project\n \n \n T. Matheson\n The Supernova Cosmology Project\n \n \n A. S. Fruchter\n The Supernova Cosmology Project\n \n \n N. Panagia\n The Supernova Cosmology Project\n \n \n H. J. M. Newberg\n The Supernova Cosmology Project\n \n \n W. J. Couch\n The Supernova Cosmology Project\n \n 10.1086/307221\n \n 21 pages and 10 figures. Accepted for publication in the\n Astrophysical Journal. Individual color figures, supplementary tables, and\n preprint also available at http://www-supernova.lbl.gov/\n Astrophys.J.517:565-586,1999\n \n \n \n \n \n \n \n\n", + 200, + null + ], + [ + [ + "http://dx.doi.org/10.1086/307221" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", + 200, + null + ], + [ + [ + "https://export.arxiv.org/api/query?id_list=math/0211159" + ], + {}, + "\n\n \n ArXiv Query: search_query=&id_list=math/0211159&start=0&max_results=10\n http://arxiv.org/api/4nVRTcAL5Np4oaGFQnqVPG0+c5k\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/math/0211159v1\n 2002-11-11T16:11:49Z\n 2002-11-11T16:11:49Z\n The entropy formula for the Ricci flow and its geometric applications\n We present a monotonic expression for the Ricci flow, valid in all dimensions\nand without curvature assumptions. It is interpreted as an entropy for a\ncertain canonical ensemble. Several geometric applications are given. In\nparticular, (1) Ricci flow, considered on the space of riemannian metrics\nmodulo diffeomorphism and scaling, has no nontrivial periodic orbits (that is,\nother than fixed points); (2) In a region, where singularity is forming in\nfinite time, the injectivity radius is controlled by the curvature; (3) Ricci\nflow can not quickly turn an almost euclidean region into a very curved one, no\nmatter what happens far away. We also verify several assertions related to\nRichard Hamilton's program for the proof of Thurston geometrization conjecture\nfor closed three-manifolds, and give a sketch of an eclectic proof of this\nconjecture, making use of earlier results on collapsing with local lower\ncurvature bound.\n\n \n Grisha Perelman\n \n 39 pages\n \n \n \n \n \n \n\n", + 200, + null + ] +] \ No newline at end of file From 0eb069c86a70b3544b05b68781f8e2c136c1689d Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Tue, 14 Aug 2018 17:20:23 +0900 Subject: [PATCH 18/20] fix test + sorted json --- tests/mock_requests.py | 2 +- tests/test_apis_data.json | 120 +++++++++++++++++++------------------- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/tests/mock_requests.py b/tests/mock_requests.py index 9fc765f..a28f745 100644 --- a/tests/mock_requests.py +++ b/tests/mock_requests.py @@ -94,7 +94,7 @@ elif mode == 'COLLECT': def _save_collected_responses(): with open(os.path.join(_data_filepath), 'w') as fd: - json.dump(_collected_responses, fd, indent=2) + json.dump(sorted(_collected_responses), fd, indent=2) elif mode == 'ONLINE': def mock_requests_get(*args, **kwargs): diff --git a/tests/test_apis_data.json b/tests/test_apis_data.json index 6ce46ae..75fd757 100644 --- a/tests/test_apis_data.json +++ b/tests/test_apis_data.json @@ -14,52 +14,82 @@ ], [ [ - "http://dx.doi.org/999999" + "http://dx.doi.org/10.1007/BF01700692" ], { "headers": { "accept": "application/x-bibtex" } }, - "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10/999999

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", - 404, - "404 Client Error: for url: http://dx.doi.org/999999" + "@article{G_del_1931,\n\tdoi = {10.1007/bf01700692},\n\turl = {https://doi.org/10.1007%2Fbf01700692},\n\tyear = 1931,\n\tmonth = {dec},\n\tpublisher = {Springer Nature},\n\tvolume = {38-38},\n\tnumber = {1},\n\tpages = {173--198},\n\tauthor = {Kurt G\u00f6del},\n\ttitle = {\u00dcber formal unentscheidbare S\u00e4tze der Principia Mathematica und verwandter Systeme I},\n\tjournal = {Monatshefte f\u00fcr Mathematik und Physik}\n}", + 200, + null ], [ [ - "http://dx.doi.org/10.1007/BF01700692" + "http://dx.doi.org/10.1086/307221" ], { "headers": { "accept": "application/x-bibtex" } }, - "@article{G_del_1931,\n\tdoi = {10.1007/bf01700692},\n\turl = {https://doi.org/10.1007%2Fbf01700692},\n\tyear = 1931,\n\tmonth = {dec},\n\tpublisher = {Springer Nature},\n\tvolume = {38-38},\n\tnumber = {1},\n\tpages = {173--198},\n\tauthor = {Kurt G\u00f6del},\n\ttitle = {\u00dcber formal unentscheidbare S\u00e4tze der Principia Mathematica und verwandter Systeme I},\n\tjournal = {Monatshefte f\u00fcr Mathematik und Physik}\n}", + "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", 200, null ], [ [ - "http://www.ottobib.com/isbn/9782081336742/bibtex" + "http://dx.doi.org/10.1086/307221" ], { - "headers": null + "headers": { + "accept": "application/x-bibtex" + } }, - "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", + "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", 200, null ], [ [ - "http://www.ottobib.com/isbn/9999999999999/bibtex" + "http://dx.doi.org/10.1103/INVALIDDOI.89.084044" ], { - "headers": null + "headers": { + "accept": "application/x-bibtex" + } }, - "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n\t

OttoBib

\n\t

Make a bibliography or works cited with just an ISBN. It's free, easy and FAST

\n\t

\n\t about ottobib and history\n\t \n\t

\n\t \n

\n\t
\n
\n\n
\n
\n\n
No Results for 9999999999999
\n
\n

\n Enter ISBN of book(s) - separate with commas (,)\n

\n \n read more about ISBN on Wikipedia\n \n
\n \n \n \n \n \n\n
\n \n
\n
\n\n
\n
\n\n

Did OttoBib help you? Then help us and Like us on Facebook!

\n
\n
\n\n\n
\n\n\n\n\n
\n \n\n \n", + "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10.1103/INVALIDDOI.89.084044

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", + 404, + "404 Client Error: for url: http://dx.doi.org/10.1103/INVALIDDOI.89.084044" + ], + [ + [ + "http://dx.doi.org/10.1186/s12984-017-0305-3" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "@article{Valero_Cuevas_2017,\n\tdoi = {10.1186/s12984-017-0305-3},\n\turl = {https://doi.org/10.1186%2Fs12984-017-0305-3},\n\tyear = 2017,\n\tmonth = {oct},\n\tpublisher = {Springer Nature},\n\tvolume = {14},\n\tnumber = {1},\n\tauthor = {Francisco J. Valero-Cuevas and Marco Santello},\n\ttitle = {On neuromechanical approaches for the study of biological and robotic grasp and manipulation},\n\tjournal = {Journal of {NeuroEngineering} and Rehabilitation}\n}", 200, null ], + [ + [ + "http://dx.doi.org/999999" + ], + { + "headers": { + "accept": "application/x-bibtex" + } + }, + "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10/999999

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", + 404, + "404 Client Error: for url: http://dx.doi.org/999999" + ], [ [ "http://www.ottobib.com/isbn/9782081336742/bibtex" @@ -67,62 +97,58 @@ { "headers": null }, - "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", 200, null ], [ [ - "https://export.arxiv.org/api/query?id_list=1710.08557" + "http://www.ottobib.com/isbn/9782081336742/bibtex" ], - {}, - "\n\n \n ArXiv Query: search_query=&id_list=1710.08557&start=0&max_results=10\n http://arxiv.org/api/bNB5RPNlUYbELau5YJ4IzaIq1x8\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1710.08557v1\n 2017-10-24T00:21:32Z\n 2017-10-24T00:21:32Z\n On Neuromechanical Approaches for the Study of Biological Grasp and\n Manipulation\n Biological and robotic grasp and manipulation are undeniably similar at the\nlevel of mechanical task performance. However, their underlying fundamental\nbiological vs. engineering mechanisms are, by definition, dramatically\ndifferent and can even be antithetical. Even our approach to each is\ndiametrically opposite: inductive science for the study of biological systems\nvs. engineering synthesis for the design and construction of robotic systems.\nThe past 20 years have seen several conceptual advances in both fields and the\nquest to unify them. Chief among them is the reluctant recognition that their\nunderlying fundamental mechanisms may actually share limited common ground,\nwhile exhibiting many fundamental differences. This recognition is particularly\nliberating because it allows us to resolve and move beyond multiple paradoxes\nand contradictions that arose from the initial reasonable assumption of a large\ncommon ground. Here, we begin by introducing the perspective of neuromechanics,\nwhich emphasizes that real-world behavior emerges from the intimate\ninteractions among the physical structure of the system, the mechanical\nrequirements of a task, the feasible neural control actions to produce it, and\nthe ability of the neuromuscular system to adapt through interactions with the\nenvironment. This allows us to articulate a succinct overview of a few salient\nconceptual paradoxes and contradictions regarding under-determined vs.\nover-determined mechanics, under- vs. over-actuated control, prescribed vs.\nemergent function, learning vs. implementation vs. adaptation, prescriptive vs.\ndescriptive synergies, and optimal vs. habitual performance. We conclude by\npresenting open questions and suggesting directions for future research. We\nhope this frank assessment of the state-of-the-art will encourage and guide\nthese communities to continue to interact and make progress in these important\nareas.\n\n \n Francisco J Valero-Cuevas\n \n \n Marco Santello\n \n 10.1186/s12984-017-0305-3\n \n Journal of NeuroEngineering and Rehabilitation, 2017\n \n \n \n \n \n\n", + { + "headers": null + }, + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", 200, null ], [ [ - "http://dx.doi.org/10.1186/s12984-017-0305-3" + "http://www.ottobib.com/isbn/9999999999999/bibtex" ], { - "headers": { - "accept": "application/x-bibtex" - } + "headers": null }, - "@article{Valero_Cuevas_2017,\n\tdoi = {10.1186/s12984-017-0305-3},\n\turl = {https://doi.org/10.1186%2Fs12984-017-0305-3},\n\tyear = 2017,\n\tmonth = {oct},\n\tpublisher = {Springer Nature},\n\tvolume = {14},\n\tnumber = {1},\n\tauthor = {Francisco J. Valero-Cuevas and Marco Santello},\n\ttitle = {On neuromechanical approaches for the study of biological and robotic grasp and manipulation},\n\tjournal = {Journal of {NeuroEngineering} and Rehabilitation}\n}", + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n\t

OttoBib

\n\t

Make a bibliography or works cited with just an ISBN. It's free, easy and FAST

\n\t

\n\t about ottobib and history\n\t \n\t

\n\t \n

\n\t
\n
\n\n
\n
\n\n
No Results for 9999999999999
\n
\n

\n Enter ISBN of book(s) - separate with commas (,)\n

\n \n read more about ISBN on Wikipedia\n \n
\n \n \n \n \n \n\n
\n \n
\n
\n\n
\n
\n\n

Did OttoBib help you? Then help us and Like us on Facebook!

\n
\n
\n\n\n
\n\n\n\n\n
\n \n\n \n", 200, null ], [ [ - "https://export.arxiv.org/api/query?id_list=1710.08557" + "https://export.arxiv.org/api/query?id_list=1312.2021" ], {}, - "\n\n \n ArXiv Query: search_query=&id_list=1710.08557&start=0&max_results=10\n http://arxiv.org/api/bNB5RPNlUYbELau5YJ4IzaIq1x8\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1710.08557v1\n 2017-10-24T00:21:32Z\n 2017-10-24T00:21:32Z\n On Neuromechanical Approaches for the Study of Biological Grasp and\n Manipulation\n Biological and robotic grasp and manipulation are undeniably similar at the\nlevel of mechanical task performance. However, their underlying fundamental\nbiological vs. engineering mechanisms are, by definition, dramatically\ndifferent and can even be antithetical. Even our approach to each is\ndiametrically opposite: inductive science for the study of biological systems\nvs. engineering synthesis for the design and construction of robotic systems.\nThe past 20 years have seen several conceptual advances in both fields and the\nquest to unify them. Chief among them is the reluctant recognition that their\nunderlying fundamental mechanisms may actually share limited common ground,\nwhile exhibiting many fundamental differences. This recognition is particularly\nliberating because it allows us to resolve and move beyond multiple paradoxes\nand contradictions that arose from the initial reasonable assumption of a large\ncommon ground. Here, we begin by introducing the perspective of neuromechanics,\nwhich emphasizes that real-world behavior emerges from the intimate\ninteractions among the physical structure of the system, the mechanical\nrequirements of a task, the feasible neural control actions to produce it, and\nthe ability of the neuromuscular system to adapt through interactions with the\nenvironment. This allows us to articulate a succinct overview of a few salient\nconceptual paradoxes and contradictions regarding under-determined vs.\nover-determined mechanics, under- vs. over-actuated control, prescribed vs.\nemergent function, learning vs. implementation vs. adaptation, prescriptive vs.\ndescriptive synergies, and optimal vs. habitual performance. We conclude by\npresenting open questions and suggesting directions for future research. We\nhope this frank assessment of the state-of-the-art will encourage and guide\nthese communities to continue to interact and make progress in these important\nareas.\n\n \n Francisco J Valero-Cuevas\n \n \n Marco Santello\n \n 10.1186/s12984-017-0305-3\n \n Journal of NeuroEngineering and Rehabilitation, 2017\n \n \n \n \n \n\n", + "\n\n \n ArXiv Query: search_query=&id_list=1312.2021&start=0&max_results=10\n http://arxiv.org/api/eXBvi61X4ShcFWF7lwJgRo7KSFk\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1312.2021v1\n 2013-12-06T21:33:40Z\n 2013-12-06T21:33:40Z\n Living with the Wrong Sign\n We describe a UV complete asymptotically fragile Lorentz-invariant theory\nexhibiting superluminal signal propagation. Its low energy effective action\ncontains \"wrong\" sign higher dimensional operators. Nevertheless, the theory\ngives rise to an S-matrix, which is defined at all energies. As expected for a\nnon-local theory, the corresponding scattering amplitudes are not exponentially\nbounded on the physical sheet, but otherwise are healthy. We study some of the\nphysical consequences of this S-matrix.\n\n \n Patrick Cooper\n \n \n Sergei Dubovsky\n \n \n Ali Mohsen\n \n 10.1103/PhysRevD.89.084044\n \n Phys. Rev. D 89, 084044 (2014)\n \n \n \n \n \n \n\n", 200, null ], [ [ - "https://export.arxiv.org/api/query?id_list=1312.2021" + "https://export.arxiv.org/api/query?id_list=1710.08557" ], {}, - "\n\n \n ArXiv Query: search_query=&id_list=1312.2021&start=0&max_results=10\n http://arxiv.org/api/eXBvi61X4ShcFWF7lwJgRo7KSFk\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1312.2021v1\n 2013-12-06T21:33:40Z\n 2013-12-06T21:33:40Z\n Living with the Wrong Sign\n We describe a UV complete asymptotically fragile Lorentz-invariant theory\nexhibiting superluminal signal propagation. Its low energy effective action\ncontains \"wrong\" sign higher dimensional operators. Nevertheless, the theory\ngives rise to an S-matrix, which is defined at all energies. As expected for a\nnon-local theory, the corresponding scattering amplitudes are not exponentially\nbounded on the physical sheet, but otherwise are healthy. We study some of the\nphysical consequences of this S-matrix.\n\n \n Patrick Cooper\n \n \n Sergei Dubovsky\n \n \n Ali Mohsen\n \n 10.1103/PhysRevD.89.084044\n \n Phys. Rev. D 89, 084044 (2014)\n \n \n \n \n \n \n\n", + "\n\n \n ArXiv Query: search_query=&id_list=1710.08557&start=0&max_results=10\n http://arxiv.org/api/bNB5RPNlUYbELau5YJ4IzaIq1x8\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1710.08557v1\n 2017-10-24T00:21:32Z\n 2017-10-24T00:21:32Z\n On Neuromechanical Approaches for the Study of Biological Grasp and\n Manipulation\n Biological and robotic grasp and manipulation are undeniably similar at the\nlevel of mechanical task performance. However, their underlying fundamental\nbiological vs. engineering mechanisms are, by definition, dramatically\ndifferent and can even be antithetical. Even our approach to each is\ndiametrically opposite: inductive science for the study of biological systems\nvs. engineering synthesis for the design and construction of robotic systems.\nThe past 20 years have seen several conceptual advances in both fields and the\nquest to unify them. Chief among them is the reluctant recognition that their\nunderlying fundamental mechanisms may actually share limited common ground,\nwhile exhibiting many fundamental differences. This recognition is particularly\nliberating because it allows us to resolve and move beyond multiple paradoxes\nand contradictions that arose from the initial reasonable assumption of a large\ncommon ground. Here, we begin by introducing the perspective of neuromechanics,\nwhich emphasizes that real-world behavior emerges from the intimate\ninteractions among the physical structure of the system, the mechanical\nrequirements of a task, the feasible neural control actions to produce it, and\nthe ability of the neuromuscular system to adapt through interactions with the\nenvironment. This allows us to articulate a succinct overview of a few salient\nconceptual paradoxes and contradictions regarding under-determined vs.\nover-determined mechanics, under- vs. over-actuated control, prescribed vs.\nemergent function, learning vs. implementation vs. adaptation, prescriptive vs.\ndescriptive synergies, and optimal vs. habitual performance. We conclude by\npresenting open questions and suggesting directions for future research. We\nhope this frank assessment of the state-of-the-art will encourage and guide\nthese communities to continue to interact and make progress in these important\nareas.\n\n \n Francisco J Valero-Cuevas\n \n \n Marco Santello\n \n 10.1186/s12984-017-0305-3\n \n Journal of NeuroEngineering and Rehabilitation, 2017\n \n \n \n \n \n\n", 200, null ], [ [ - "http://dx.doi.org/10.1103/INVALIDDOI.89.084044" + "https://export.arxiv.org/api/query?id_list=1710.08557" ], - { - "headers": { - "accept": "application/x-bibtex" - } - }, - "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10.1103/INVALIDDOI.89.084044

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", - 404, - "404 Client Error: for url: http://dx.doi.org/10.1103/INVALIDDOI.89.084044" + {}, + "\n\n \n ArXiv Query: search_query=&id_list=1710.08557&start=0&max_results=10\n http://arxiv.org/api/bNB5RPNlUYbELau5YJ4IzaIq1x8\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1710.08557v1\n 2017-10-24T00:21:32Z\n 2017-10-24T00:21:32Z\n On Neuromechanical Approaches for the Study of Biological Grasp and\n Manipulation\n Biological and robotic grasp and manipulation are undeniably similar at the\nlevel of mechanical task performance. However, their underlying fundamental\nbiological vs. engineering mechanisms are, by definition, dramatically\ndifferent and can even be antithetical. Even our approach to each is\ndiametrically opposite: inductive science for the study of biological systems\nvs. engineering synthesis for the design and construction of robotic systems.\nThe past 20 years have seen several conceptual advances in both fields and the\nquest to unify them. Chief among them is the reluctant recognition that their\nunderlying fundamental mechanisms may actually share limited common ground,\nwhile exhibiting many fundamental differences. This recognition is particularly\nliberating because it allows us to resolve and move beyond multiple paradoxes\nand contradictions that arose from the initial reasonable assumption of a large\ncommon ground. Here, we begin by introducing the perspective of neuromechanics,\nwhich emphasizes that real-world behavior emerges from the intimate\ninteractions among the physical structure of the system, the mechanical\nrequirements of a task, the feasible neural control actions to produce it, and\nthe ability of the neuromuscular system to adapt through interactions with the\nenvironment. This allows us to articulate a succinct overview of a few salient\nconceptual paradoxes and contradictions regarding under-determined vs.\nover-determined mechanics, under- vs. over-actuated control, prescribed vs.\nemergent function, learning vs. implementation vs. adaptation, prescriptive vs.\ndescriptive synergies, and optimal vs. habitual performance. We conclude by\npresenting open questions and suggesting directions for future research. We\nhope this frank assessment of the state-of-the-art will encourage and guide\nthese communities to continue to interact and make progress in these important\nareas.\n\n \n Francisco J Valero-Cuevas\n \n \n Marco Santello\n \n 10.1186/s12984-017-0305-3\n \n Journal of NeuroEngineering and Rehabilitation, 2017\n \n \n \n \n \n\n", + 200, + null ], [ [ @@ -142,19 +168,6 @@ 200, null ], - [ - [ - "http://dx.doi.org/10.1086/307221" - ], - { - "headers": { - "accept": "application/x-bibtex" - } - }, - "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", - 200, - null - ], [ [ "https://export.arxiv.org/api/query?id_list=astro-ph/9812133" @@ -164,19 +177,6 @@ 200, null ], - [ - [ - "http://dx.doi.org/10.1086/307221" - ], - { - "headers": { - "accept": "application/x-bibtex" - } - }, - "@article{Perlmutter_1999,\n\tdoi = {10.1086/307221},\n\turl = {https://doi.org/10.1086%2F307221},\n\tyear = 1999,\n\tmonth = {jun},\n\tpublisher = {{IOP} Publishing},\n\tvolume = {517},\n\tnumber = {2},\n\tpages = {565--586},\n\tauthor = {S. Perlmutter and G. Aldering and G. Goldhaber and R. A. Knop and P. Nugent and P. G. Castro and S. Deustua and S. Fabbro and A. Goobar and D. E. Groom and I. M. Hook and A. G. Kim and M. Y. Kim and J. C. Lee and N. J. Nunes and R. Pain and C. R. Pennypacker and R. Quimby and C. Lidman and R. S. Ellis and M. Irwin and R. G. McMahon and P. Ruiz-Lapuente and N. Walton and B. Schaefer and B. J. Boyle and A. V. Filippenko and T. Matheson and A. S. Fruchter and N. Panagia and H. J. M. Newberg and W. J. Couch and The Supernova Cosmology Project},\n\ttitle = {Measurements of $\\{upOmega}$ and $\\{upLambda}$ from 42 High-Redshift Supernovae},\n\tjournal = {The Astrophysical Journal}\n}", - 200, - null - ], [ [ "https://export.arxiv.org/api/query?id_list=math/0211159" From 8e30ac7400d93c95c846c277813ffb30e39ed084 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Tue, 14 Aug 2018 17:35:59 +0900 Subject: [PATCH 19/20] refix test + switch apis to https --- pubs/apis.py | 4 +- tests/mock_requests.py | 2 +- tests/test_apis_data.json | 86 +++++++++++++++++++-------------------- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pubs/apis.py b/pubs/apis.py index 78f9190..070d8fc 100644 --- a/pubs/apis.py +++ b/pubs/apis.py @@ -74,7 +74,7 @@ def _get_request(url, headers=None): def doi2bibtex(doi, **kwargs): """Return a bibtex string of metadata from a DOI""" - url = 'http://dx.doi.org/{}'.format(doi) + url = 'https://dx.doi.org/{}'.format(doi) headers = {'accept': 'application/x-bibtex'} r = _get_request(url, headers=headers) if r.encoding is None: @@ -89,7 +89,7 @@ def doi2bibtex(doi, **kwargs): def isbn2bibtex(isbn, **kwargs): """Return a bibtex string of metadata from an ISBN""" - url = 'http://www.ottobib.com/isbn/{}/bibtex'.format(isbn) + url = 'https://www.ottobib.com/isbn/{}/bibtex'.format(isbn) r = _get_request(url) soup = BeautifulSoup(r.text, "html.parser") citation = soup.find("textarea").text diff --git a/tests/mock_requests.py b/tests/mock_requests.py index a28f745..6660950 100644 --- a/tests/mock_requests.py +++ b/tests/mock_requests.py @@ -84,12 +84,12 @@ elif mode == 'COLLECT': except requests.exceptions.RequestException as e: error_msg = str(e) + text = intercept_text(text) _collected_responses.append((args, kwargs, text, status_code, error_msg)) _save_collected_responses() # yes, we save everytime, because it's not # clear how to run once after all the tests # have run. If you figure it out... - text = intercept_text(text) return MockingResponse(text, status_code, error_msg) def _save_collected_responses(): diff --git a/tests/test_apis_data.json b/tests/test_apis_data.json index 75fd757..8fe73aa 100644 --- a/tests/test_apis_data.json +++ b/tests/test_apis_data.json @@ -1,7 +1,7 @@ [ [ [ - "http://dx.doi.org/10.1007/BF01700692" + "https://dx.doi.org/10.1007/BF01700692" ], { "headers": { @@ -14,7 +14,7 @@ ], [ [ - "http://dx.doi.org/10.1007/BF01700692" + "https://dx.doi.org/10.1007/BF01700692" ], { "headers": { @@ -27,7 +27,7 @@ ], [ [ - "http://dx.doi.org/10.1086/307221" + "https://dx.doi.org/10.1086/307221" ], { "headers": { @@ -40,7 +40,7 @@ ], [ [ - "http://dx.doi.org/10.1086/307221" + "https://dx.doi.org/10.1086/307221" ], { "headers": { @@ -53,7 +53,7 @@ ], [ [ - "http://dx.doi.org/10.1103/INVALIDDOI.89.084044" + "https://dx.doi.org/10.1103/INVALIDDOI.89.084044" ], { "headers": { @@ -62,11 +62,11 @@ }, "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10.1103/INVALIDDOI.89.084044

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", 404, - "404 Client Error: for url: http://dx.doi.org/10.1103/INVALIDDOI.89.084044" + "404 Client Error: for url: https://dx.doi.org/10.1103/INVALIDDOI.89.084044" ], [ [ - "http://dx.doi.org/10.1186/s12984-017-0305-3" + "https://dx.doi.org/10.1186/s12984-017-0305-3" ], { "headers": { @@ -79,7 +79,7 @@ ], [ [ - "http://dx.doi.org/999999" + "https://dx.doi.org/999999" ], { "headers": { @@ -88,47 +88,14 @@ }, "\n\n\nError: DOI Not Found\n\n\n\n\n \n\n\n\n\n\n\n
\n\"Logo\"\n
\n\n
\n
\n
\n\n\n\n\n\n \n \n \n \n
\"\"\n HOME  | HANDBOOK  | FACTSHEETS  | FAQs  |  RESOURCES  | USERS  | NEWS  | MEMBERS AREA\n
\n\n\n
\n
\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
\n\"\"\n
\n\n

DOI Not Found

\n\n
 
\n\n\n\n

10/999999

\n\n
 
\n\n\n\n\n

This DOI cannot be found in the DOI System. Possible reasons are:

\n\n\n
    \n\n
  • The DOI is incorrect in your source. Search for the item by name, title, or other metadata using a search engine.
  • \n\n
  • The DOI was copied incorrectly. Check to see that the string includes all the characters before and after the slash and no sentence punctuation marks.
  • \n\n
  • The DOI has not been activated yet. Please try again later, and report the problem if the error continues.
  • \n\n
\n\n\n\n
 
\n\n

You may report this error to the responsible DOI Registration Agency using the form below. Include your email address to receive confirmation and feedback.

\n\n
\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
Your Email Address:
Additional Information About the Error:
\n\n

\n\n
\n
\n\n\n\n\n
\"\"
\n\n
 
\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n
\nDOI System Proxy Server Documentation\n
\n\"DOI_disc_logo\"\n\n®, DOI®, DOI.ORG®, and shortDOI® are trademarks of the International DOI Foundation.\n
\n\n\n", 404, - "404 Client Error: for url: http://dx.doi.org/999999" - ], - [ - [ - "http://www.ottobib.com/isbn/9782081336742/bibtex" - ], - { - "headers": null - }, - "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", - 200, - null - ], - [ - [ - "http://www.ottobib.com/isbn/9782081336742/bibtex" - ], - { - "headers": null - }, - "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", - 200, - null - ], - [ - [ - "http://www.ottobib.com/isbn/9999999999999/bibtex" - ], - { - "headers": null - }, - "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n\t

OttoBib

\n\t

Make a bibliography or works cited with just an ISBN. It's free, easy and FAST

\n\t

\n\t about ottobib and history\n\t \n\t

\n\t \n

\n\t
\n
\n\n
\n
\n\n
No Results for 9999999999999
\n
\n

\n Enter ISBN of book(s) - separate with commas (,)\n

\n \n read more about ISBN on Wikipedia\n \n
\n \n \n \n \n \n\n
\n \n
\n
\n\n
\n
\n\n

Did OttoBib help you? Then help us and Like us on Facebook!

\n
\n
\n\n\n
\n\n\n\n\n
\n \n\n \n", - 200, - null + "404 Client Error: for url: https://dx.doi.org/999999" ], [ [ "https://export.arxiv.org/api/query?id_list=1312.2021" ], {}, - "\n\n \n ArXiv Query: search_query=&id_list=1312.2021&start=0&max_results=10\n http://arxiv.org/api/eXBvi61X4ShcFWF7lwJgRo7KSFk\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1312.2021v1\n 2013-12-06T21:33:40Z\n 2013-12-06T21:33:40Z\n Living with the Wrong Sign\n We describe a UV complete asymptotically fragile Lorentz-invariant theory\nexhibiting superluminal signal propagation. Its low energy effective action\ncontains \"wrong\" sign higher dimensional operators. Nevertheless, the theory\ngives rise to an S-matrix, which is defined at all energies. As expected for a\nnon-local theory, the corresponding scattering amplitudes are not exponentially\nbounded on the physical sheet, but otherwise are healthy. We study some of the\nphysical consequences of this S-matrix.\n\n \n Patrick Cooper\n \n \n Sergei Dubovsky\n \n \n Ali Mohsen\n \n 10.1103/PhysRevD.89.084044\n \n Phys. Rev. D 89, 084044 (2014)\n \n \n \n \n \n \n\n", + "\n\n \n ArXiv Query: search_query=&id_list=1312.2021&start=0&max_results=10\n http://arxiv.org/api/eXBvi61X4ShcFWF7lwJgRo7KSFk\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/1312.2021v1\n 2013-12-06T21:33:40Z\n 2013-12-06T21:33:40Z\n Living with the Wrong Sign\n We describe a UV complete asymptotically fragile Lorentz-invariant theory\nexhibiting superluminal signal propagation. Its low energy effective action\ncontains \"wrong\" sign higher dimensional operators. Nevertheless, the theory\ngives rise to an S-matrix, which is defined at all energies. As expected for a\nnon-local theory, the corresponding scattering amplitudes are not exponentially\nbounded on the physical sheet, but otherwise are healthy. We study some of the\nphysical consequences of this S-matrix.\n\n \n Patrick Cooper\n \n \n Sergei Dubovsky\n \n \n Ali Mohsen\n \n 10.1103/INVALIDDOI.89.084044\n \n Phys. Rev. D 89, 084044 (2014)\n \n \n \n \n \n \n\n", 200, null ], @@ -185,5 +152,38 @@ "\n\n \n ArXiv Query: search_query=&id_list=math/0211159&start=0&max_results=10\n http://arxiv.org/api/4nVRTcAL5Np4oaGFQnqVPG0+c5k\n 2018-08-14T00:00:00-04:00\n 1\n 0\n 10\n \n http://arxiv.org/abs/math/0211159v1\n 2002-11-11T16:11:49Z\n 2002-11-11T16:11:49Z\n The entropy formula for the Ricci flow and its geometric applications\n We present a monotonic expression for the Ricci flow, valid in all dimensions\nand without curvature assumptions. It is interpreted as an entropy for a\ncertain canonical ensemble. Several geometric applications are given. In\nparticular, (1) Ricci flow, considered on the space of riemannian metrics\nmodulo diffeomorphism and scaling, has no nontrivial periodic orbits (that is,\nother than fixed points); (2) In a region, where singularity is forming in\nfinite time, the injectivity radius is controlled by the curvature; (3) Ricci\nflow can not quickly turn an almost euclidean region into a very curved one, no\nmatter what happens far away. We also verify several assertions related to\nRichard Hamilton's program for the proof of Thurston geometrization conjecture\nfor closed three-manifolds, and give a sketch of an eclectic proof of this\nconjecture, making use of earlier results on collapsing with local lower\ncurvature bound.\n\n \n Grisha Perelman\n \n 39 pages\n \n \n \n \n \n \n\n", 200, null + ], + [ + [ + "https://www.ottobib.com/isbn/9782081336742/bibtex" + ], + { + "headers": null + }, + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", + 200, + null + ], + [ + [ + "https://www.ottobib.com/isbn/9782081336742/bibtex" + ], + { + "headers": null + }, + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n
\n

OttoBib

\n

bibtex Format

\n
\n
\n\n
\n
\n \n
\n
\n
\n\n
\n

\n NOTE!\n
\n

    \n
  1. Verify accuracy of the data (particularly authors)
  2. \n
  3. Remember to do a HANGING INDENT (something I cannot do with HTML here)
  4. \n
  5. I strive for accuracy of the citations but you should treat this tool as a starting point in your works cited, because you still need to look it over.
  6. \n
\n

\n
\n
\n\n
\n \n\n \n", + 200, + null + ], + [ + [ + "https://www.ottobib.com/isbn/9999999999999/bibtex" + ], + { + "headers": null + }, + "\n\n\n\n \n \n \n \n \n \n \n \n\n \n\n Bibliography and Works Cited Generator for MLA, APA, Wikipedia and Bibtex - OttoBib.com \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n
\n \n
\n\t

OttoBib

\n\t

Make a bibliography or works cited with just an ISBN. It's free, easy and FAST

\n\t

\n\t about ottobib and history\n\t \n\t

\n\t \n

\n\t
\n
\n\n
\n
\n\n
No Results for 9999999999999
\n
\n

\n Enter ISBN of book(s) - separate with commas (,)\n

\n \n read more about ISBN on Wikipedia\n \n
\n \n \n \n \n \n\n
\n \n
\n
\n\n
\n
\n\n

Did OttoBib help you? Then help us and Like us on Facebook!

\n
\n
\n\n\n
\n\n\n\n\n
\n \n\n \n", + 200, + null ] ] \ No newline at end of file From 51aa9795fdbe1c794651351ea7fd74b714bc7786 Mon Sep 17 00:00:00 2001 From: "Fabien C. Y. Benureau" Date: Tue, 14 Aug 2018 17:41:58 +0900 Subject: [PATCH 20/20] add 3.7 tests --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index f2be365..9e31abd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,11 @@ matrix: - os: linux language: python python: 3.6 + - os: linux + language: python + python: 3.7 + dist: xenial + sudo: true - os: osx language: generic python: 2.7