It depends on configobj, is cleaner and simpler than the previous implementation. It adds comments in the config file, and type verification. Related: #18main
parent
da4723d6db
commit
93c54939b3
@ -0,0 +1 @@
|
|||||||
|
from .conf import load_default_conf, load_conf, save_conf, get_pubspath
|
@ -0,0 +1,49 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
import configobj
|
||||||
|
import validate
|
||||||
|
|
||||||
|
from .spec import configspec
|
||||||
|
|
||||||
|
|
||||||
|
DFT_CONFIG_PATH = os.path.expanduser('~/.pubsrc')
|
||||||
|
|
||||||
|
def load_default_conf():
|
||||||
|
"""Loads the default configuration"""
|
||||||
|
default_conf = configobj.ConfigObj(configspec=configspec)
|
||||||
|
validator = validate.Validator()
|
||||||
|
default_conf.validate(validator, copy=True)
|
||||||
|
return default_conf
|
||||||
|
|
||||||
|
def get_pubspath(verify=True):
|
||||||
|
"""Returns the pubs path.
|
||||||
|
If verify is True, verify that pubs.conf exist in the directory,
|
||||||
|
and exit with an error if not.
|
||||||
|
"""
|
||||||
|
confpath = DFT_CONFIG_PATH
|
||||||
|
if 'PUBSCONF' in os.environ:
|
||||||
|
confpath = os.path.abspath(os.path.expanduser(os.environ['PUBSCONF']))
|
||||||
|
if verify:
|
||||||
|
if not os.path.isfile(confpath):
|
||||||
|
from .. import uis
|
||||||
|
ui = uis.get_ui()
|
||||||
|
ui.error('configuration file not found at `{}`'.format(confpath))
|
||||||
|
ui.exit(error_code=1)
|
||||||
|
return confpath
|
||||||
|
|
||||||
|
def load_conf(check_conf=True):
|
||||||
|
"""Load the user config"""
|
||||||
|
pubspath = get_pubspath(verify=True)
|
||||||
|
with open(pubspath, 'r') as f:
|
||||||
|
conf = configobj.ConfigObj(f.readlines(), configspec=configspec)
|
||||||
|
|
||||||
|
if check_conf:
|
||||||
|
validator = validate.Validator()
|
||||||
|
results = conf.validate(validator, copy=True)
|
||||||
|
assert results == True, '{}'.format(results) # TODO: precise error dialog when parsing error
|
||||||
|
|
||||||
|
return conf
|
||||||
|
|
||||||
|
def save_conf(conf):
|
||||||
|
with open(get_pubspath(verify=False), 'w') as f:
|
||||||
|
conf.write(outfile=f)
|
@ -0,0 +1,55 @@
|
|||||||
|
from .. import __version__
|
||||||
|
|
||||||
|
configspec = """
|
||||||
|
[main]
|
||||||
|
|
||||||
|
# Where the pubs repository files (bibtex, metadata, notes) are located
|
||||||
|
pubsdir = string(default='~/pubs')
|
||||||
|
|
||||||
|
# Where the documents files are located (default: $(pubsdir)/doc/)
|
||||||
|
docsdir = string(default="docsdir://")
|
||||||
|
|
||||||
|
# Specify if a document should be copied or moved in the docdir, or only
|
||||||
|
# linked when adding a publication.
|
||||||
|
doc_add = option('copy', 'move', 'link', default='move')
|
||||||
|
|
||||||
|
# if True, pubs will ask confirmation before copying/moving/linking the
|
||||||
|
# document file.
|
||||||
|
doc_add_ask = boolean(default=True)
|
||||||
|
|
||||||
|
# the command to use when opening document files
|
||||||
|
open_cmd = string(default=None)
|
||||||
|
|
||||||
|
# which editor to use when editing bibtex files.
|
||||||
|
# if using a graphical editor, use the --wait or --block option, i.e.:
|
||||||
|
# "atom --wait"
|
||||||
|
# "kate --block"
|
||||||
|
edit_cmd = string(default=None)
|
||||||
|
|
||||||
|
|
||||||
|
[formating]
|
||||||
|
|
||||||
|
# Enable bold formatting, if the terminal supports it.
|
||||||
|
bold = boolean(default=True)
|
||||||
|
|
||||||
|
# Enable italics, if the terminal supports it.
|
||||||
|
italics = boolean(default=True)
|
||||||
|
|
||||||
|
# Enable colors, if the terminal supports it.
|
||||||
|
color = boolean(default=True)
|
||||||
|
|
||||||
|
|
||||||
|
[theme]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[plugins]
|
||||||
|
# comma-separated list of the plugins to load
|
||||||
|
active = list(default=list())
|
||||||
|
|
||||||
|
[internal]
|
||||||
|
# The version of this configuration file. Do not edit.
|
||||||
|
version = string(min=5, default='{}')
|
||||||
|
|
||||||
|
""".format(__version__).split('\n')
|
@ -1,112 +0,0 @@
|
|||||||
import os
|
|
||||||
import sys
|
|
||||||
import collections
|
|
||||||
|
|
||||||
from .p3 import configparser, ConfigParser, _read_config
|
|
||||||
|
|
||||||
from .content import check_file, _open
|
|
||||||
from . import __version__
|
|
||||||
|
|
||||||
# constant stuff (DFT = DEFAULT)
|
|
||||||
|
|
||||||
MAIN_SECTION = 'pubs'
|
|
||||||
DFT_CONFIG_PATH = os.path.expanduser('~/.pubsrc')
|
|
||||||
try:
|
|
||||||
DFT_EDIT_CMD = os.environ['EDITOR']
|
|
||||||
except KeyError:
|
|
||||||
DFT_EDIT_CMD = 'vi'
|
|
||||||
|
|
||||||
DFT_PLUGINS = ''
|
|
||||||
|
|
||||||
DFT_CONFIG = collections.OrderedDict([
|
|
||||||
('pubsdir', os.path.expanduser('~/.pubs')),
|
|
||||||
('docsdir', ''),
|
|
||||||
('import_copy', True),
|
|
||||||
('import_move', False),
|
|
||||||
('color', True),
|
|
||||||
('version', __version__),
|
|
||||||
('version_warning', True),
|
|
||||||
('open_cmd', 'open'),
|
|
||||||
('edit_cmd', DFT_EDIT_CMD),
|
|
||||||
('plugins', DFT_PLUGINS)
|
|
||||||
])
|
|
||||||
|
|
||||||
BOOLEANS = {'import_copy', 'import_move', 'color', 'version_warning'}
|
|
||||||
|
|
||||||
|
|
||||||
# package-shared config that can be accessed using :
|
|
||||||
# from configs import config
|
|
||||||
_config = None
|
|
||||||
|
|
||||||
|
|
||||||
def config(section=MAIN_SECTION):
|
|
||||||
if _config is None:
|
|
||||||
raise ValueError('not config instanciated yet')
|
|
||||||
_config._section = section
|
|
||||||
return _config
|
|
||||||
|
|
||||||
|
|
||||||
class Config(object):
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
object.__setattr__(self, '_section', MAIN_SECTION) # active section
|
|
||||||
object.__setattr__(self, '_cfg', ConfigParser())
|
|
||||||
|
|
||||||
self._cfg.add_section(self._section)
|
|
||||||
for name, value in DFT_CONFIG.items():
|
|
||||||
self._cfg.set(self._section, name, str(value))
|
|
||||||
|
|
||||||
for name, value in kwargs.items():
|
|
||||||
self.__setattr__(name, value)
|
|
||||||
|
|
||||||
def as_global(self):
|
|
||||||
global _config
|
|
||||||
_config = self
|
|
||||||
|
|
||||||
def load(self, path=DFT_CONFIG_PATH):
|
|
||||||
if not check_file(path, fail=False):
|
|
||||||
raise IOError(("The configuration file {} does not exist."
|
|
||||||
" Did you run 'pubs init' ?").format(path))
|
|
||||||
b_flag = ''
|
|
||||||
if sys.version_info[0] == 2: # HACK, FIXME please
|
|
||||||
b_flag = 'b'
|
|
||||||
with _open(path, 'r{}+'.format(b_flag)) as f:
|
|
||||||
_read_config(self._cfg, f)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def save(self, path=DFT_CONFIG_PATH):
|
|
||||||
b_flag = ''
|
|
||||||
if sys.version_info[0] == 2: # HACK, FIXME please
|
|
||||||
b_flag = 'b'
|
|
||||||
with _open(path, 'w{}+'.format(b_flag)) as f:
|
|
||||||
self._cfg.write(f)
|
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
|
||||||
if name in ('_cfg', '_section'):
|
|
||||||
object.__setattr__(self, name, value)
|
|
||||||
else:
|
|
||||||
if type(value) is bool:
|
|
||||||
BOOLEANS.add(name)
|
|
||||||
self._cfg.set(self._section, name, str(value))
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
value = self._cfg.get(self._section, name)
|
|
||||||
if name in BOOLEANS:
|
|
||||||
value = str2bool(value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def get(self, name, default=None):
|
|
||||||
try:
|
|
||||||
return self.__getattr__(name)
|
|
||||||
except (configparser.NoOptionError, configparser.NoSectionError):
|
|
||||||
return default
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
for name, value in self._cfg.items(self._section):
|
|
||||||
if name in BOOLEANS:
|
|
||||||
value = str2bool(value)
|
|
||||||
yield name, value
|
|
||||||
|
|
||||||
|
|
||||||
def str2bool(s):
|
|
||||||
return str(s).lower() in ('yes', 'true', 't', 'y', '1')
|
|
Loading…
Reference in new issue