Merge branch 'master' into feat/dialogedit
This commit is contained in:
commit
6957ae3cbb
68
pubs/uis.py
68
pubs/uis.py
@ -38,35 +38,9 @@ def _get_encoding(conf):
|
|||||||
def _get_local_editor():
|
def _get_local_editor():
|
||||||
"""Get the editor from environment variables.
|
"""Get the editor from environment variables.
|
||||||
|
|
||||||
Use nano as a default.
|
Use vi as a default.
|
||||||
"""
|
"""
|
||||||
return os.environ.get('EDITOR', 'nano')
|
return os.environ.get('EDITOR', 'vi')
|
||||||
|
|
||||||
|
|
||||||
def _editor_input(editor, initial='', suffix='.tmp'):
|
|
||||||
"""Use an editor to get input"""
|
|
||||||
str_initial = initial.encode('utf-8') # TODO: make it a configuration item
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as temp_file:
|
|
||||||
tfile_name = temp_file.name
|
|
||||||
temp_file.write(str_initial)
|
|
||||||
cmd = shlex.split(editor) # this enable editor command with option, e.g. gvim -f
|
|
||||||
cmd.append(tfile_name)
|
|
||||||
subprocess.call(cmd)
|
|
||||||
content = read_text_file(tfile_name)
|
|
||||||
os.remove(tfile_name)
|
|
||||||
return content
|
|
||||||
|
|
||||||
|
|
||||||
def _edit_file(editor, path_to_file, temporary=True):
|
|
||||||
if temporary:
|
|
||||||
check_file(path_to_file, fail=True)
|
|
||||||
content = read_text_file(path_to_file)
|
|
||||||
content = _editor_input(editor, content)
|
|
||||||
write_file(path_to_file, content)
|
|
||||||
else:
|
|
||||||
cmd = editor.split() # this enable editor command with option, e.g. gvim -f
|
|
||||||
cmd.append(system_path(path_to_file))
|
|
||||||
subprocess.call(cmd)
|
|
||||||
|
|
||||||
|
|
||||||
def get_ui():
|
def get_ui():
|
||||||
@ -223,7 +197,41 @@ class InputUI(PrintUI):
|
|||||||
return [True, False][answer]
|
return [True, False][answer]
|
||||||
|
|
||||||
def editor_input(self, initial="", suffix='.tmp'):
|
def editor_input(self, initial="", suffix='.tmp'):
|
||||||
return _editor_input(self.editor, initial=initial, suffix=suffix)
|
"""Use an editor to get input"""
|
||||||
|
str_initial = initial.encode('utf-8') # TODO: make it a configuration item
|
||||||
|
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as temp_file:
|
||||||
|
tfile_name = temp_file.name
|
||||||
|
temp_file.write(str_initial)
|
||||||
|
self._call_editor(tfile_name)
|
||||||
|
content = read_text_file(tfile_name)
|
||||||
|
os.remove(tfile_name)
|
||||||
|
return content
|
||||||
|
|
||||||
def edit_file(self, path, temporary):
|
def edit_file(self, path, temporary):
|
||||||
_edit_file(self.editor, path, temporary=temporary)
|
if temporary:
|
||||||
|
check_file(path, fail=True)
|
||||||
|
content = read_text_file(path)
|
||||||
|
content = self.editor_input(content)
|
||||||
|
write_file(path, content)
|
||||||
|
else:
|
||||||
|
self._call_editor(path)
|
||||||
|
|
||||||
|
def _call_editor(self, path):
|
||||||
|
"""Call the editor, and checks that no error were raised by the OS"""
|
||||||
|
cmd = shlex.split(self.editor) # this enable editor command with option, e.g. gvim -f
|
||||||
|
cmd.append(path)
|
||||||
|
try:
|
||||||
|
subprocess.call(cmd)
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno == os.errno.ENOENT:
|
||||||
|
self.error(("Error while calling editor '{}'. The editor may "
|
||||||
|
"not be present. You can change the text editor "
|
||||||
|
"that pubs uses by setting the $EDITOR environment "
|
||||||
|
"variable, or by running `pubs conf` and setting "
|
||||||
|
"the `edit_cmd` field."
|
||||||
|
).format(self.editor))
|
||||||
|
# handle file not found error.
|
||||||
|
self.exit()
|
||||||
|
else:
|
||||||
|
# Something else went wrong while trying to run `wget`
|
||||||
|
self.handle_exception(e)
|
||||||
|
10
readme.md
10
readme.md
@ -64,7 +64,7 @@ If you use latex, you can automatize references, by running `pubs export > refer
|
|||||||
This ensures that your reference file is always up-to-date; you can cite a paper in your manuscript a soon as you add it in pubs. This means that if you have, for instance, a doi on a webpage, you only need to do:
|
This ensures that your reference file is always up-to-date; you can cite a paper in your manuscript a soon as you add it in pubs. This means that if you have, for instance, a doi on a webpage, you only need to do:
|
||||||
|
|
||||||
pubs add -D 10.1007/s00422-012-0514-6
|
pubs add -D 10.1007/s00422-012-0514-6
|
||||||
|
|
||||||
and then add `\cite{Loeb_2012}` in your manuscript. After exporting the bibliography, the citation will correctly appear in your compiled pdf.
|
and then add `\cite{Loeb_2012}` in your manuscript. After exporting the bibliography, the citation will correctly appear in your compiled pdf.
|
||||||
|
|
||||||
|
|
||||||
@ -112,18 +112,12 @@ For *zsh* completion, the global activation is not supported but bash completion
|
|||||||
You can access the self-documented configuration by using `pubs conf`, and all the commands' help is available with the `--help` option. Did not find an answer to your question? Drop us an issue. We may not answer right away (science comes first!) but we'll eventually look into it.
|
You can access the self-documented configuration by using `pubs conf`, and all the commands' help is available with the `--help` option. Did not find an answer to your question? Drop us an issue. We may not answer right away (science comes first!) but we'll eventually look into it.
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
- python >= 2.7 or >= 3.3
|
|
||||||
- [bibtexparser](https://github.com/sciunto-org/python-bibtexparser)
|
|
||||||
- [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup)
|
|
||||||
- [argcomplete](https://argcomplete.readthedocs.io) (optional, for autocompletion)
|
|
||||||
|
|
||||||
## Authors
|
## Authors
|
||||||
|
|
||||||
- [Fabien Benureau](http://fabien.benureau.com)
|
- [Fabien Benureau](http://fabien.benureau.com)
|
||||||
- [Olivier Mangin](http://olivier.mangin.com)
|
- [Olivier Mangin](http://olivier.mangin.com)
|
||||||
|
|
||||||
|
|
||||||
### Contributors
|
### Contributors
|
||||||
|
|
||||||
- [Jonathan Grizou](https://github.com/jgrizou)
|
- [Jonathan Grizou](https://github.com/jgrizou)
|
||||||
|
6
requirements.txt
Normal file
6
requirements.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
pyyaml
|
||||||
|
bibtexparser>=1.0
|
||||||
|
python-dateutil
|
||||||
|
requests
|
||||||
|
configobj
|
||||||
|
beautifulsoup4
|
7
setup.py
7
setup.py
@ -26,10 +26,9 @@ setup(
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
install_requires=['pyyaml', 'bibtexparser>=1.0', 'python-dateutil', 'requests',
|
install_requires=['pyyaml', 'bibtexparser>=1.0', 'python-dateutil',
|
||||||
'configobj',
|
'requests', 'configobj', 'beautifulsoup4'],
|
||||||
'beautifulsoup4'], # to be made optional?
|
tests_require=['pyfakefs>=2.7', 'mock'],
|
||||||
tests_require=['pyfakefs>=2.7'],
|
|
||||||
extras_require={'autocompletion': ['argcomplete'],
|
extras_require={'autocompletion': ['argcomplete'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -74,12 +74,11 @@ class FakeInput():
|
|||||||
def as_global(self):
|
def as_global(self):
|
||||||
for md in self.module_list:
|
for md in self.module_list:
|
||||||
md.input = self
|
md.input = self
|
||||||
md._editor_input = self
|
if md.__name__ == 'pubs.uis':
|
||||||
md._edit_file = self.input_to_file
|
md.InputUI.editor_input = self
|
||||||
# if mdname.endswith('files'):
|
md.InputUI.edit_file = self.input_to_file
|
||||||
# md.editor_input = self
|
|
||||||
|
|
||||||
def input_to_file(self, _, path_to_file, temporary=True):
|
def input_to_file(self, path_to_file, temporary=True):
|
||||||
content.write_file(path_to_file, self())
|
content.write_file(path_to_file, self())
|
||||||
|
|
||||||
def add_input(self, inp):
|
def add_input(self, inp):
|
||||||
|
@ -45,9 +45,8 @@ class FakeSystemExit(Exception):
|
|||||||
"Exited with code: {}.".format(self.code), *args)
|
"Exited with code: {}.".format(self.code), *args)
|
||||||
|
|
||||||
|
|
||||||
# code for fake fs
|
class TestInput(unittest.TestCase):
|
||||||
|
"""Test that the fake input mechanisms work correctly in the tests"""
|
||||||
class TestFakeInput(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_input(self):
|
def test_input(self):
|
||||||
input = fake_env.FakeInput(['yes', 'no'])
|
input = fake_env.FakeInput(['yes', 'no'])
|
||||||
@ -65,13 +64,16 @@ class TestFakeInput(unittest.TestCase):
|
|||||||
color.input()
|
color.input()
|
||||||
|
|
||||||
def test_editor_input(self):
|
def test_editor_input(self):
|
||||||
|
sample_conf = conf.load_default_conf()
|
||||||
|
ui = uis.InputUI(sample_conf)
|
||||||
|
|
||||||
other_input = fake_env.FakeInput(['yes', 'no'],
|
other_input = fake_env.FakeInput(['yes', 'no'],
|
||||||
module_list=[uis, color])
|
module_list=[uis, color])
|
||||||
other_input.as_global()
|
other_input.as_global()
|
||||||
self.assertEqual(uis._editor_input(), 'yes')
|
self.assertEqual(ui.editor_input(), 'yes')
|
||||||
self.assertEqual(uis._editor_input(), 'no')
|
self.assertEqual(ui.editor_input(), 'no')
|
||||||
with self.assertRaises(fake_env.FakeInput.UnexpectedInput):
|
with self.assertRaises(fake_env.FakeInput.UnexpectedInput):
|
||||||
color.input()
|
ui.editor_input()
|
||||||
|
|
||||||
|
|
||||||
class CommandTestCase(fake_env.TestFakeFs):
|
class CommandTestCase(fake_env.TestFakeFs):
|
||||||
@ -355,8 +357,8 @@ class TestList(DataCommandTestCase):
|
|||||||
|
|
||||||
def test_list_several_no_date(self):
|
def test_list_several_no_date(self):
|
||||||
self.execute_cmds(['pubs init -p testrepo'])
|
self.execute_cmds(['pubs init -p testrepo'])
|
||||||
os.chdir('/') # weird fix for shutil.rmtree invocation.
|
os.chdir('/') # weird fix for shutil.rmtree invocation.
|
||||||
shutil.rmtree(self.rootpath + '/testrepo')
|
shutil.rmtree(os.path.join(self.rootpath, 'testrepo'))
|
||||||
os.chdir(self.rootpath)
|
os.chdir(self.rootpath)
|
||||||
self.fs.add_real_directory(os.path.join(self.rootpath, 'testrepo'), read_only=False)
|
self.fs.add_real_directory(os.path.join(self.rootpath, 'testrepo'), read_only=False)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user