Source code for lala.config

"""
Config module

.. versionchanged:: 0.5
The function set_default_options was removed. To achieve the same behaviour,
set a module-level dict called "DEFAULT_OPTIONS" where the keys are the
option names and the values are the default values in your plugin.
"""
import logging


from appdirs import user_config_dir
from inspect import getframeinfo, stack
from os import getenv
from os.path import basename, expanduser, join
from six import iteritems, string_types
from six.moves import configparser

_CFG = None
_FILENAME = None

#: Used as a separator when storing lists of values in the config file
_LIST_SEPARATOR = ","

#: Default settings
_CONFIG_DEFAULTS = {
    "channels": "",
    "plugins": "",
    "nickserv_password": None,
    "log_folder": expanduser("~/.lala/logs"),
    "log_file": expanduser("~/.lala/lala.log"),
    "encoding": "utf-8",
    "fallback_encoding": "utf-8",
    "max_log_days": 2,
    "nickserv_admin_tracking": "false"
}


def _initialize(filename=None):
    global _CFG
    global _FILENAME
    cfg = configparser.RawConfigParser(_CONFIG_DEFAULTS)
    if filename is None:
        configfiles = [join(user_config_dir(appname="lala"),
                            "config"),
                       join(getenv("HOME"), ".lala", "config"),
                       "/etc/lala/config"]
    else:
        configfiles = [filename]
    files = cfg.read(configfiles)
    if not cfg.has_section("base"):
        cfg.add_section("base")

    logging.info("Read config files %s", files)
    logging.info("Using %s to save setting", files[0])

    _CFG = cfg
    _FILENAME = files[0]


def _find_current_plugin_name():
    """Tries to find the filename of the current plugin. This is essentially
    the first filename different from the filename of this file ("config.py")
    on the stack
    """
    for elem in stack():
        frameinfo = getframeinfo(elem[0])
        filename = frameinfo.filename
        if not __file__.startswith(filename):
            return basename(filename.replace(".py", ""))


def _set(section, key, value):
    if _CFG.has_section(section):
        _CFG.set(section, key, value)
    else:
        _CFG.add_section(section)
        _CFG.set(section, key, value)
    if _FILENAME is not None:
        with open(_FILENAME, "w") as fp:
            _CFG.write(fp)


[docs]def get(key, converter=None): """Returns the value of a config option. The section is the name of the calling file. Default values for all keys can be set with :meth:`set_default_options`. :param key: The key to lookup """ plugin = _find_current_plugin_name() logging.info("%s wants to get the value of %s" % (plugin, key)) value = None value = _CFG.get(plugin, key) if converter is not None: value = converter(value) return value
def _get(section, key): return _CFG.get(section, key)
[docs]def get_int(*args): """Returns the value of a config option as an int. :param *args: See :meth:`lala.config.get` :rtype: int """ return get(*args, converter=int)
[docs]def set(key, value, plugin=None): """Sets the ``value`` of ``key``. The section is the name of the calling file.""" plugin = _find_current_plugin_name() if not isinstance(value, string_types): value = str(value) logging.info("%s wants to set the value of %s to %s" % (plugin, key, value)) _set(plugin, key, value)
def _list_converter(value): """Converts a list of values into a string in which the values will be separated by :data:`_LIST_SEPARATOR`.""" if not isinstance(value, string_types): value = map(str, value) value = _LIST_SEPARATOR.join(value) return value
[docs]def get_list(*args): """Gets a list option. :param *args: See :meth:`lala.config.get` :rtype: list of strings """ value = get(*args, converter=_list_converter) return value.split(_LIST_SEPARATOR)
[docs]def set_list(key, value, *args): """Sets option ``key`` to ``value`` where ``value`` is a list of values. None of the values in ``value`` are allowed to contain :data:`lala.config._LIST_SEPARATOR`. This method does *not* preserve the type of the items in the list, they're all passed through :meth:`str`. :param key: See :meth:`lala.config.set` :param value: A list of values for ``key``. """ value = _list_converter(value) set(key, value, *args)
def _set_default_options(plugin, opts): """Sets the default options for a plugin. The names of the arguments in ``kwargs`` will be used as the option names, the values as the values of the options. """ for key, value in iteritems(opts): if not _CFG.has_option(plugin, key): if not isinstance(value, list): _set(plugin, key, value) else: set_list(key, value, plugin)