implements #19
This commit is contained in:
parent
0bfe921ad9
commit
2871588703
@ -2,6 +2,7 @@ import os
|
|||||||
import platform
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
import configobj
|
import configobj
|
||||||
import validate
|
import validate
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ from .spec import configspec
|
|||||||
|
|
||||||
DFT_CONFIG_PATH = os.path.expanduser('~/.pubsrc')
|
DFT_CONFIG_PATH = os.path.expanduser('~/.pubsrc')
|
||||||
|
|
||||||
|
|
||||||
def load_default_conf():
|
def load_default_conf():
|
||||||
"""Load the default configuration"""
|
"""Load the default configuration"""
|
||||||
default_conf = configobj.ConfigObj(configspec=configspec)
|
default_conf = configobj.ConfigObj(configspec=configspec)
|
||||||
@ -17,6 +19,7 @@ def load_default_conf():
|
|||||||
default_conf.validate(validator, copy=True)
|
default_conf.validate(validator, copy=True)
|
||||||
return default_conf
|
return default_conf
|
||||||
|
|
||||||
|
|
||||||
def get_confpath(verify=True):
|
def get_confpath(verify=True):
|
||||||
"""Return the configuration filepath
|
"""Return the configuration filepath
|
||||||
If verify is True, verify that the file exists and exit with an error if not.
|
If verify is True, verify that the file exists and exit with an error if not.
|
||||||
@ -32,31 +35,36 @@ def get_confpath(verify=True):
|
|||||||
ui.exit(error_code=1)
|
ui.exit(error_code=1)
|
||||||
return confpath
|
return confpath
|
||||||
|
|
||||||
|
|
||||||
def check_conf(conf):
|
def check_conf(conf):
|
||||||
"""Type check a configuration"""
|
"""Type check a configuration"""
|
||||||
validator = validate.Validator()
|
validator = validate.Validator()
|
||||||
results = conf.validate(validator, copy=True)
|
results = conf.validate(validator, copy=True)
|
||||||
assert results == True, '{}'.format(results) # TODO: precise error dialog when parsing error
|
assert results == True, '{}'.format(results) # TODO: precise error dialog when parsing error
|
||||||
|
|
||||||
|
|
||||||
def load_conf(check=True, path=None):
|
def load_conf(check=True, path=None):
|
||||||
"""Load the configuration"""
|
"""Load the configuration"""
|
||||||
if path is None:
|
if path is None:
|
||||||
path = get_confpath(verify=True)
|
path = get_confpath(verify=True)
|
||||||
with open(path, 'rb') as f:
|
with open(path, 'rb') as f:
|
||||||
conf = configobj.ConfigObj(f.readlines(), configspec=configspec)
|
conf = configobj.ConfigObj(f.readlines(), configspec=configspec)
|
||||||
|
|
||||||
if check:
|
if check:
|
||||||
check_conf(conf)
|
check_conf(conf)
|
||||||
|
conf.filename = path
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
|
|
||||||
def save_conf(conf, path=None):
|
def save_conf(conf, path=None):
|
||||||
"""Save the configuration."""
|
"""Save the configuration."""
|
||||||
if path is None:
|
if path is not None:
|
||||||
path = get_confpath(verify=False)
|
conf.filename = path
|
||||||
with open(path, 'wb') as f:
|
elif conf.filename is None:
|
||||||
|
conf.filename = get_confpath(verify=False)
|
||||||
|
with open(conf.filename, 'wb') as f:
|
||||||
conf.write(outfile=f)
|
conf.write(outfile=f)
|
||||||
|
|
||||||
|
|
||||||
def default_open_cmd():
|
def default_open_cmd():
|
||||||
"""Chooses the default command to open documents"""
|
"""Chooses the default command to open documents"""
|
||||||
if platform.system() == 'Darwin':
|
if platform.system() == 'Darwin':
|
||||||
@ -68,6 +76,7 @@ def default_open_cmd():
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def which(cmd):
|
def which(cmd):
|
||||||
try:
|
try:
|
||||||
return shutil.which(cmd) # available in python 3.3
|
return shutil.which(cmd) # available in python 3.3
|
||||||
@ -78,6 +87,7 @@ def which(cmd):
|
|||||||
return filepath
|
return filepath
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def default_edit_cmd():
|
def default_edit_cmd():
|
||||||
"""Find an available editor"""
|
"""Find an available editor"""
|
||||||
if 'EDITOR' in os.environ:
|
if 'EDITOR' in os.environ:
|
||||||
|
@ -1,57 +1,68 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from . import uis
|
from . import uis
|
||||||
from . import config
|
from . import config
|
||||||
from . import commands
|
from . import commands
|
||||||
from . import update
|
from . import update
|
||||||
from . import plugins
|
from . import plugins
|
||||||
|
from .__init__ import __version__
|
||||||
|
|
||||||
CORE_CMDS = collections.OrderedDict([
|
CORE_CMDS = collections.OrderedDict([
|
||||||
('init', commands.init_cmd),
|
('init', commands.init_cmd),
|
||||||
('conf', commands.conf_cmd),
|
('conf', commands.conf_cmd),
|
||||||
|
|
||||||
('add', commands.add_cmd),
|
('add', commands.add_cmd),
|
||||||
('rename', commands.rename_cmd),
|
('rename', commands.rename_cmd),
|
||||||
('remove', commands.remove_cmd),
|
('remove', commands.remove_cmd),
|
||||||
('list', commands.list_cmd),
|
('list', commands.list_cmd),
|
||||||
|
|
||||||
('attach', commands.attach_cmd),
|
('attach', commands.attach_cmd),
|
||||||
('open', commands.open_cmd),
|
('open', commands.open_cmd),
|
||||||
('tag', commands.tag_cmd),
|
('tag', commands.tag_cmd),
|
||||||
('note', commands.note_cmd),
|
('note', commands.note_cmd),
|
||||||
|
|
||||||
('export', commands.export_cmd),
|
('export', commands.export_cmd),
|
||||||
('import', commands.import_cmd),
|
('import', commands.import_cmd),
|
||||||
|
|
||||||
('websearch', commands.websearch_cmd),
|
('websearch', commands.websearch_cmd),
|
||||||
('edit', commands.edit_cmd),
|
('edit', commands.edit_cmd),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
def execute(raw_args=sys.argv):
|
def execute(raw_args=sys.argv):
|
||||||
|
|
||||||
|
conf_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
conf_parser.add_argument("-c", "--config", help="path to config file",
|
||||||
|
type=str, metavar="FILE")
|
||||||
|
args, remaining_args = conf_parser.parse_known_args(raw_args[1:])
|
||||||
|
|
||||||
|
if args.config:
|
||||||
|
conf_path = args.config
|
||||||
|
else:
|
||||||
|
conf_path = config.get_confpath(verify=False) # will be checked on load
|
||||||
|
|
||||||
# loading config
|
# loading config
|
||||||
if len(raw_args) > 1 and raw_args[1] != 'init':
|
if len(remaining_args) > 0 and remaining_args[0] != 'init':
|
||||||
try:
|
try:
|
||||||
conf = config.load_conf(check=False)
|
conf = config.load_conf(path=conf_path, check=False)
|
||||||
if update.update_check(conf): # an update happened, reload conf.
|
if update.update_check(conf, path=conf.filename): # an update happened, reload conf.
|
||||||
conf = config.load_conf(check=False)
|
conf = config.load_conf(path=conf_path, check=False)
|
||||||
config.check_conf(conf)
|
config.check_conf(conf)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
print('error: {}'.format(str(e)))
|
print('error: {}'.format(str(e)))
|
||||||
sys.exit()
|
sys.exit()
|
||||||
else:
|
else:
|
||||||
conf = config.load_default_conf()
|
conf = config.load_default_conf()
|
||||||
|
conf.filename = conf_path
|
||||||
|
|
||||||
uis.init_ui(conf)
|
uis.init_ui(conf)
|
||||||
ui = uis.get_ui()
|
ui = uis.get_ui()
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="research papers repository")
|
parser = argparse.ArgumentParser(parents=[conf_parser],
|
||||||
|
description="research papers repository",
|
||||||
|
prog="pubs", version=__version__, add_help=True)
|
||||||
subparsers = parser.add_subparsers(title="valid commands", dest="command")
|
subparsers = parser.add_subparsers(title="valid commands", dest="command")
|
||||||
|
|
||||||
cmd_funcs = collections.OrderedDict()
|
cmd_funcs = collections.OrderedDict()
|
||||||
for cmd_name, cmd_mod in CORE_CMDS.items():
|
for cmd_name, cmd_mod in CORE_CMDS.items():
|
||||||
cmd_mod.parser(subparsers)
|
cmd_mod.parser(subparsers)
|
||||||
@ -62,7 +73,7 @@ def execute(raw_args=sys.argv):
|
|||||||
for p in plugins.get_plugins().values():
|
for p in plugins.get_plugins().values():
|
||||||
cmd_funcs.update(p.get_commands(subparsers))
|
cmd_funcs.update(p.get_commands(subparsers))
|
||||||
|
|
||||||
args = parser.parse_args(raw_args[1:])
|
args = parser.parse_args(remaining_args)
|
||||||
args.prog = parser.prog # Hack: there might be a better way...
|
args.prog = parser.prog # Hack: there might be a better way...
|
||||||
cmd = args.command
|
cmd = args.command
|
||||||
del args.command
|
del args.command
|
||||||
|
@ -6,6 +6,7 @@ import codecs
|
|||||||
|
|
||||||
from .content import editor_input
|
from .content import editor_input
|
||||||
from . import color
|
from . import color
|
||||||
|
from . import config
|
||||||
from .p3 import _get_raw_stdout, _get_raw_stderr, input, ustr
|
from .p3 import _get_raw_stdout, _get_raw_stderr, input, ustr
|
||||||
|
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ def _get_encoding(conf):
|
|||||||
|
|
||||||
def get_ui():
|
def get_ui():
|
||||||
if _ui is None:
|
if _ui is None:
|
||||||
return PrintUI() # no editor support. (#FIXME?)
|
return PrintUI(config.load_default_conf()) # no editor support. (#FIXME?)
|
||||||
return _ui
|
return _ui
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ class CommandTestCase(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.fs = fake_env.create_fake_fs([content, filebroker, conf, init_cmd, import_cmd, configobj, update])
|
self.fs = fake_env.create_fake_fs([content, filebroker, conf, init_cmd, import_cmd, configobj, update])
|
||||||
self.default_pubs_dir = self.fs['os'].path.expanduser('~/.pubs')
|
self.default_pubs_dir = self.fs['os'].path.expanduser('~/.pubs')
|
||||||
|
self.default_conf_path = self.fs['os'].path.expanduser('~/.pubsrc')
|
||||||
|
|
||||||
def execute_cmds(self, cmds, capture_output=CAPTURE_OUTPUT):
|
def execute_cmds(self, cmds, capture_output=CAPTURE_OUTPUT):
|
||||||
""" Execute a list of commands, and capture their output
|
""" Execute a list of commands, and capture their output
|
||||||
@ -509,8 +510,21 @@ class TestUsecase(DataCommandTestCase):
|
|||||||
'pubs attach --move Page99 data/pagerank.pdf'
|
'pubs attach --move Page99 data/pagerank.pdf'
|
||||||
]
|
]
|
||||||
self.execute_cmds(cmds)
|
self.execute_cmds(cmds)
|
||||||
|
self.assertTrue(self.fs['os'].path.isfile(self.default_conf_path))
|
||||||
self.assertFalse(self.fs['os'].path.exists('/data/pagerank.pdf'))
|
self.assertFalse(self.fs['os'].path.exists('/data/pagerank.pdf'))
|
||||||
|
|
||||||
|
def test_alternate_config(self):
|
||||||
|
alt_conf = self.fs['os'].path.expanduser('~/.alt_conf')
|
||||||
|
cmds = ['pubs -c ' + alt_conf + ' init',
|
||||||
|
'pubs --config ' + alt_conf + ' import data/ Page99',
|
||||||
|
'pubs list -c ' + alt_conf
|
||||||
|
]
|
||||||
|
outs = self.execute_cmds(cmds)
|
||||||
|
# check if pubs works as expected
|
||||||
|
self.assertEqual(1 + 1, len(outs[-1].split('\n')))
|
||||||
|
# check whether we actually changed the config file
|
||||||
|
self.assertFalse(self.fs['os'].path.isfile(self.default_conf_path))
|
||||||
|
self.assertTrue(self.fs['os'].path.isfile(alt_conf))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user