From bff1f5763d505a1436b31abe78fe4d1ab183001d Mon Sep 17 00:00:00 2001 From: ksunden Date: Tue, 8 May 2018 22:32:12 -0500 Subject: [PATCH 1/8] Add a command to open urls --- pubs/commands/__init__.py | 1 + pubs/commands/url_cmd.py | 35 +++++++++++++++++++++++++++++++++++ pubs/pubs_cmd.py | 1 + 3 files changed, 37 insertions(+) create mode 100644 pubs/commands/url_cmd.py diff --git a/pubs/commands/__init__.py b/pubs/commands/__init__.py index 150dae5..cd17fa3 100644 --- a/pubs/commands/__init__.py +++ b/pubs/commands/__init__.py @@ -15,5 +15,6 @@ from . import export_cmd from . import import_cmd # bonus from . import websearch_cmd +from . import url_cmd from . import edit_cmd diff --git a/pubs/commands/url_cmd.py b/pubs/commands/url_cmd.py new file mode 100644 index 0000000..716653f --- /dev/null +++ b/pubs/commands/url_cmd.py @@ -0,0 +1,35 @@ +from __future__ import unicode_literals + +import webbrowser + +from .. import p3 +from .. import repo +from ..uis import get_ui +from ..utils import resolve_citekey, resolve_citekey_list + + + +def parser(subparsers, conf): + parser = subparsers.add_parser('url', + help="open the url in the browser") + parser.add_argument("citekey", nargs = '*', + help="one or more citeKeys to open") + return parser + + +def command(conf, args): + """Open the url for a publication.""" + + ui = get_ui() + rp = repo.Repository(conf) + + for key in resolve_citekey_list(rp, args.citekey, ui=ui, exit_on_fail=True): + try: + paper = rp.pull_paper(key) + url = paper.bibdata['url'] + webbrowser.open(url) + + except KeyError as e: + ui.error(key, 'has no url') + + rp.close() diff --git a/pubs/pubs_cmd.py b/pubs/pubs_cmd.py index 8955cfb..949fd4a 100644 --- a/pubs/pubs_cmd.py +++ b/pubs/pubs_cmd.py @@ -29,6 +29,7 @@ CORE_CMDS = collections.OrderedDict([ ('import', commands.import_cmd), ('websearch', commands.websearch_cmd), + ('url', commands.url_cmd), ('edit', commands.edit_cmd), ]) From 247554c24890cc5fdb06b809e1b452da5ad22549 Mon Sep 17 00:00:00 2001 From: ksunden Date: Tue, 8 May 2018 23:20:32 -0500 Subject: [PATCH 2/8] Fix error handling --- pubs/commands/url_cmd.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pubs/commands/url_cmd.py b/pubs/commands/url_cmd.py index 716653f..5591b77 100644 --- a/pubs/commands/url_cmd.py +++ b/pubs/commands/url_cmd.py @@ -30,6 +30,7 @@ def command(conf, args): webbrowser.open(url) except KeyError as e: - ui.error(key, 'has no url') + ui.error('{} has no url'.format(key)) + print(key) rp.close() From 7c82a8518b1f75714bf1e108eed8a7c814044fb4 Mon Sep 17 00:00:00 2001 From: Kyle Sunden Date: Mon, 14 May 2018 18:03:39 -0500 Subject: [PATCH 3/8] remove extraneous print --- pubs/commands/url_cmd.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pubs/commands/url_cmd.py b/pubs/commands/url_cmd.py index 5591b77..a2fd002 100644 --- a/pubs/commands/url_cmd.py +++ b/pubs/commands/url_cmd.py @@ -31,6 +31,5 @@ def command(conf, args): except KeyError as e: ui.error('{} has no url'.format(key)) - print(key) rp.close() From 54a056c27745df92d41b8ce95ab481f3dd55b7e1 Mon Sep 17 00:00:00 2001 From: ksunden Date: Mon, 14 May 2018 18:38:43 -0500 Subject: [PATCH 4/8] Change error to warning --- pubs/commands/url_cmd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubs/commands/url_cmd.py b/pubs/commands/url_cmd.py index a2fd002..019edca 100644 --- a/pubs/commands/url_cmd.py +++ b/pubs/commands/url_cmd.py @@ -23,13 +23,13 @@ def command(conf, args): ui = get_ui() rp = repo.Repository(conf) - for key in resolve_citekey_list(rp, args.citekey, ui=ui, exit_on_fail=True): + for key in resolve_citekey_list(rp, args.citekey, ui=ui, exit_on_fail=False): try: paper = rp.pull_paper(key) url = paper.bibdata['url'] webbrowser.open(url) except KeyError as e: - ui.error('{} has no url'.format(key)) + ui.warning('{} has no url'.format(key)) rp.close() From e177b43d141d28f3068fcdc60d5f1e7f96765aa1 Mon Sep 17 00:00:00 2001 From: ksunden Date: Sun, 20 May 2018 20:17:45 -0500 Subject: [PATCH 5/8] Remove unused imports, update strings --- pubs/commands/url_cmd.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pubs/commands/url_cmd.py b/pubs/commands/url_cmd.py index 019edca..7ac7b7f 100644 --- a/pubs/commands/url_cmd.py +++ b/pubs/commands/url_cmd.py @@ -2,23 +2,22 @@ from __future__ import unicode_literals import webbrowser -from .. import p3 from .. import repo from ..uis import get_ui -from ..utils import resolve_citekey, resolve_citekey_list +from ..utils import resolve_citekey_list def parser(subparsers, conf): parser = subparsers.add_parser('url', - help="open the url in the browser") + help="open a paper's url in the default web browser") parser.add_argument("citekey", nargs = '*', help="one or more citeKeys to open") return parser def command(conf, args): - """Open the url for a publication.""" + """Open the url of one or several papers in a web browser.""" ui = get_ui() rp = repo.Repository(conf) @@ -27,6 +26,7 @@ def command(conf, args): try: paper = rp.pull_paper(key) url = paper.bibdata['url'] + ui.info('opening url {}'.format(url)) webbrowser.open(url) except KeyError as e: From aaf2ed52c133c6e3103aa81fca5a0df212e1597b Mon Sep 17 00:00:00 2001 From: ksunden Date: Tue, 22 May 2018 10:31:11 -0500 Subject: [PATCH 6/8] Use mock to test url command --- tests/requirements.txt | 1 + tests/test_usecase.py | 53 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/tests/requirements.txt b/tests/requirements.txt index c3ee05b..2790d94 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -2,3 +2,4 @@ six pyfakefs==3.3 ddt +mock diff --git a/tests/test_usecase.py b/tests/test_usecase.py index 7d98492..8273901 100644 --- a/tests/test_usecase.py +++ b/tests/test_usecase.py @@ -6,6 +6,7 @@ import os import re import sys import shutil +import mock import six import ddt @@ -23,7 +24,6 @@ import fixtures from pubs.commands import init_cmd, import_cmd - # makes the tests very noisy PRINT_OUTPUT = False CAPTURE_OUTPUT = True @@ -104,13 +104,14 @@ class CommandTestCase(fake_env.TestFakeFs): actual_cmd = cmd if not isinstance(cmd, p3.ustr): actual_cmd = cmd[0] - if len(cmd) == 2: # Inputs provided + if len(cmd) >= 2 and cmd[1] is not None: # Inputs provided inputs = cmd[1] - if len(cmd) == 3: # Expected output provided + if len(cmd) >= 3: # Expected output provided capture_output = True - expected_out = color.undye(cmd[2]) - if len(cmd) == 4: # Expected error output provided - expected_err = color.undye(cmd[3]) + if cmd[2] is not None: + expected_out = color.undye(cmd[2]) + if len(cmd) >= 4 and cmd[3] is not None: # Expected error output provided + expected_err = color.undye(cmd[3]) # Always set fake input: test should not ask unexpected user input input = fake_env.FakeInput(inputs, [content, uis, p3]) input.as_global() @@ -153,6 +154,7 @@ class DataCommandTestCase(CommandTestCase): super(DataCommandTestCase, self).setUp(nsec_stat=nsec_stat) self.fs.add_real_directory(os.path.join(self.rootpath, 'data'), read_only=False) self.fs.add_real_directory(os.path.join(self.rootpath, 'bibexamples'), read_only=False) + self.fs.CreateFile('/dev/null') # fake_env.copy_dir(self.fs, os.path.join(os.path.dirname(__file__), 'data'), 'data') # fake_env.copy_dir(self.fs, os.path.join(os.path.dirname(__file__), 'bibexamples'), 'bibexamples') @@ -497,6 +499,45 @@ class TestTag(DataCommandTestCase): with self.assertRaises(FakeSystemExit): self.execute_cmds(cmds) +class TestURL(DataCommandTestCase): + + def setUp(self): + super(TestURL, self).setUp() + init = ['pubs init', + 'pubs add data/pagerank.bib', + 'pubs add data/turing1950.bib', + 'pubs add data/martius.bib', + ] + #self.fs.add_real_file('/dev/null') + #webbrowser.register('true', None, webbrowser.GenericBrowser('/usr/bin/true'), -1) + self.execute_cmds(init) + + @mock.patch('webbrowser.open') + def test_url_open_one(self, wb_open): + cmds = [('pubs url Page99', 'qy'), + ] + correct = ['info: opening url http://ilpubs.stanford.edu:8090/422/\n', + ] + out = self.execute_cmds(cmds) + self.assertEqual(out, correct) + + @mock.patch('webbrowser.open') + def test_url_open_missing(self, wb_open): + cmds = [('pubs url turing1950computing', None, None, 'warning: turing1950computing has no url\n'), + ] + self.execute_cmds(cmds) + + @mock.patch('webbrowser.open') + def test_url_open_multiple(self, wb_open): + cmds = [('pubs url Page99 10.1371_journal.pone.0063400', 'qyqy'), + ] + correct = ['info: opening url http://ilpubs.stanford.edu:8090/422/\n' + + 'info: opening url http://dx.doi.org/10.1371%2Fjournal.pone.0063400\n', + ] + out = self.execute_cmds(cmds) + self.assertEqual(out, correct) + + class TestNote(DataCommandTestCase): From 2f59b4f2cea5aeb50742dd1c1acb948f49404c55 Mon Sep 17 00:00:00 2001 From: ksunden Date: Tue, 22 May 2018 20:16:50 -0500 Subject: [PATCH 7/8] Clean up tests --- tests/test_usecase.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/test_usecase.py b/tests/test_usecase.py index 8273901..c066b3a 100644 --- a/tests/test_usecase.py +++ b/tests/test_usecase.py @@ -508,13 +508,11 @@ class TestURL(DataCommandTestCase): 'pubs add data/turing1950.bib', 'pubs add data/martius.bib', ] - #self.fs.add_real_file('/dev/null') - #webbrowser.register('true', None, webbrowser.GenericBrowser('/usr/bin/true'), -1) self.execute_cmds(init) @mock.patch('webbrowser.open') def test_url_open_one(self, wb_open): - cmds = [('pubs url Page99', 'qy'), + cmds = ['pubs url Page99', ] correct = ['info: opening url http://ilpubs.stanford.edu:8090/422/\n', ] @@ -529,7 +527,7 @@ class TestURL(DataCommandTestCase): @mock.patch('webbrowser.open') def test_url_open_multiple(self, wb_open): - cmds = [('pubs url Page99 10.1371_journal.pone.0063400', 'qyqy'), + cmds = ['pubs url Page99 10.1371_journal.pone.0063400', ] correct = ['info: opening url http://ilpubs.stanford.edu:8090/422/\n' + 'info: opening url http://dx.doi.org/10.1371%2Fjournal.pone.0063400\n', From a0525b5147e59404ed18862c2f07be02c749a007 Mon Sep 17 00:00:00 2001 From: ksunden Date: Tue, 22 May 2018 20:56:34 -0500 Subject: [PATCH 8/8] Remove unused /dev/null --- tests/test_usecase.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_usecase.py b/tests/test_usecase.py index c066b3a..8091f69 100644 --- a/tests/test_usecase.py +++ b/tests/test_usecase.py @@ -154,7 +154,6 @@ class DataCommandTestCase(CommandTestCase): super(DataCommandTestCase, self).setUp(nsec_stat=nsec_stat) self.fs.add_real_directory(os.path.join(self.rootpath, 'data'), read_only=False) self.fs.add_real_directory(os.path.join(self.rootpath, 'bibexamples'), read_only=False) - self.fs.CreateFile('/dev/null') # fake_env.copy_dir(self.fs, os.path.join(os.path.dirname(__file__), 'data'), 'data') # fake_env.copy_dir(self.fs, os.path.join(os.path.dirname(__file__), 'bibexamples'), 'bibexamples')