Source code for libvhc.config
# Virus Health Check: a validation tool for HETDEX/VIRUS data
# Copyright (C) 2015, 2016, 2017, 2018 "The HETDEX collaboration"
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Manage configurations.
"""
from __future__ import (absolute_import, division, print_function,
unicode_literals)
from collections import OrderedDict
import os
import re
import warnings
import configparser
from configparser import ExtendedInterpolation
from pyhetdex.doc import docstring
# configuration parser with extended interpolation
from pyhetdex.tools import configuration as confp
from pyhetdex.tools import six_ext
# private dictionary containing the configuration object
_config_dic = {}
DEF_CONFDIR = 'vhc_config'
"Default directory containing the configuration file"
DEF_CONFNAME = 'vhc_settings.cfg'
"Default name of the configuration file"
SVN_REVISION = 61
'''Minimum revision number of the vhc_settings.cfg file. If the revision number
is not found or smaller, warn the user'''
[docs]@docstring.format_docstring(dconf=DEF_CONFDIR, fconf=DEF_CONFNAME)
def config_file_name():
"""Returns the configuration file name.
It searches for the configuration file until it doesn't find it. The
resolution order is:
* environment variable ``VHC_CONFIG`` containing the file name
* ``./{dconf}/{fconf}``
* ``$HOME/.config/{dconf}/{fconf}``
* ``/etc/{dconf}/{fconf}``
Returns
-------
string
name of the file
Raises
------
pyhetdex.tool.six_ext.ConfigFileError
if the ``{fconf}`` is not found in any of the above places
"""
confname = os.path.join(DEF_CONFDIR, DEF_CONFNAME)
if "VHC_CONFIG" in os.environ and os.path.isfile(os.environ["VHC_CONFIG"]):
return os.environ["VHC_CONFIG"]
elif os.path.isfile(_loc_conf(confname)):
return _loc_conf(confname)
elif os.path.isfile(_home_conf(confname)):
return _home_conf(confname)
elif os.path.isfile(_global_conf(confname)):
return _global_conf(confname)
else:
raise six_ext.ConfigFileError(confname)
def _loc_conf(confname):
"""Returns the local configuration file name"""
return os.path.join(os.getcwd(), confname)
def _home_conf(confname):
"""Returns the user configuration file name"""
return os.path.join(os.path.expanduser("~"), '.config', confname)
def _global_conf(confname):
"""Returns the global configuration file name"""
return os.path.join('/etc', confname)
[docs]def default_dict(conf_file):
"""Default values of the configuration object
Parameters
----------
conf_file : string
name of the configuration file
Returns
-------
defaults : dict
options-values pairs
"""
defaults = {}
# get the name of the directory where the configuration file is and use it
# into the ``defaults`` section as ``vhc_config_dir`` to allow local file
# system interpolation
conf_dir = os.path.dirname(conf_file)
defaults['vhc_config_dir'] = conf_dir
return defaults
[docs]def load_config(name='default', conf_file=None, reload_=False, args=None):
"""Load the configuration
Parameters
----------
name : string, optional
name to associate with the configuration object
conf_name : string, optional
Name of the configuration file; if not provided search for it in the
default locations
reload : bool, optional
load the configuration, even if ``name`` configuration objects already
exists
args : object, optional
if given, use the ``args`` to override the configuration entries; it
uses :func:`~pyhetdex.tools.configuration.override_conf`
"""
if name in _config_dic and not reload_:
return
if conf_file:
conf_fn = conf_file
else:
conf_fn = config_file_name()
conf = confp.ConfigParser(interpolation=ExtendedInterpolation(),
defaults=default_dict(conf_fn))
conf.read(conf_fn)
try:
svn_revision = conf.get('svn', 'revision', raw=True)
rev_number = int(re.findall('.*?Revision: (\d+).*', svn_revision)[0])
except (configparser.Error, IndexError):
rev_number = -1
if rev_number < SVN_REVISION:
warnings.warn('The revision number of the vhc configuration file is {}'
' while the expected one is {}. This might cause some'
' failure if some configuration sections and/or options'
' are missing'.format(rev_number, SVN_REVISION))
if args:
conf = confp.override_conf(conf, args)
_config_dic[name] = conf
[docs]def get_config(name='default'):
"""Returns the configuration file with the specified name
All calls to this functions with a given ``name`` return the same
:class:`confp.ConfigParser` instance. This means that configuration
instances don't need to be passed between different parts of the
application.
Parameters
----------
name : string, optional
name to associate with the config parser,
Returns
-------
:class:`confp.ConfigParser` instance
"""
return _config_dic[name]
[docs]def conf_svn_info(conf):
'''Get the svn info from the configuration as raw values.
Parameters
----------
conf : :class:`pyhetdex.tools.configuration.ConfigParser`
configuration object
Returns
-------
conf_svn_info : OrderedDict
svn informations; keys: date, revision, author
'''
conf_svn_info = OrderedDict()
section = 'svn'
keys = ['date', 'revision', 'author']
for k in keys:
value = conf.get(section, k, raw=True)
conf_svn_info[k] = value
return conf_svn_info