Conf.set_conf()   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
c 0
b 0
f 0
dl 0
loc 16
rs 9.2
1
# -*- coding: utf-8 -*-
2
"""Simple configuration file helpers for small configurations in yaml.
3
4
.. moduleauthor:: Kenny Freeman <[email protected]>
5
6
"""
7
import fnmatch
8
import os.path
9
import collections
10
11
import yaml  # pip install pyaml
0 ignored issues
show
Configuration introduced by
The import yaml could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
12
13
import plumd
14
15
__author__ = 'Kenny Freeman'
16
__email__ = '[email protected]'
17
__license__ = "ISCL"
18
__docformat__ = 'reStructuredText'
19
20
21
def find(dname, ext):
22
    """Helper to yield a recursive list of the yaml files in a directory.
23
24
    :param dname: Path to list files in
25
    :type name: str
26
    :param ext: File extension to search for
27
    :type name: str
28
    :rtype: list -- a list of of the filenames found or []
29
    """
30
    if os.path.isdir(dname):
31
        try:
32
            for rdir, _, fnames in os.walk(dname, topdown=True, onerror=None,
33
                                           followlinks=False):
34
                for fname in fnmatch.filter(fnames, "*.{0}".format(ext)):
35
                    yield os.path.join(rdir, fname)
36
        except AttributeError as exc:
37
            raise plumd.ConfigError("Invalid path: {0} : {1}".format(dname, exc))
38
        except OSError as exc:
39
            raise plumd.ConfigError("OSError: {0} : {1}".format(dname, exc))
40
    else:
41
        yield None
42
43
44
class Conf(object):
45
    """Simple key/value configuration helper class for small yaml files.
46
47
    :param cfile: Full path to the configuration file to load
48
    :type name: str
49
    :raises: ConfigError: if the specified file does not exist
50
    """
51
52
    def __init__(self, cfile):
53
        """conf constructor.
54
55
        :param cfile: Full path to the configuration file to load
56
        :type name: str
57
        :rtype: conf -- an instance of conf
58
        :raises: ConfigError: if the specified file does not exist
59
        """
60
        self.conf = collections.OrderedDict()
61
        self.path = cfile
62
        if (not cfile) or (not os.path.isfile(cfile)):
63
            raise plumd.ConfigError("file {0} does not exist".format(cfile))
64
        with open(cfile) as cfd:
65
            try:
66
                self.conf = yaml.safe_load(cfd)
67
            except yaml.scanner.ScannerError as exc:
68
                msg = "invalid: {0} : {1}".format(cfile, exc)
69
                raise plumd.ConfigError(msg)
70
71
    def __str__(self):
72
        """Return a nicely formatted string of our config.
73
74
        :rtype: str
75
        """
76
        return yaml.dump(self.conf, allow_unicode=False, default_flow_style=False)
77
78
    def __repr__(self):
79
        """Return a nicely formatted string of our config.
80
81
        :rtype: str
82
        """
83
        return yaml.dump(self.conf, allow_unicode=True, default_flow_style=False)
84
85
    def get(self, name, exception=False, default=None, rtype=None):
86
        """Return the requested value, the provided default or None.
87
88
        raises:
89
            ConfigError if exception=True and the requested key is not found.
90
91
        :param name: The configuration value to lookup and return
92
        :type name: str
93
        :param exception: If True raise a ConfigError if the vlaue is not present
94
        :type exception: bool
95
        :param default: The default value to return if value is not found
96
        :rtype: value -- the configured value for the requested name or default
97
        :raises: ConfigError
98
        """
99
        val = default
100
        if name in self.conf and self.conf[name] is not None:
101
            val = self.conf[name]
102
        elif exception:
103
            msg = "missing {0} in: {1}".format(name, self.path)
104
            raise plumd.ConfigError(msg)
105
        if rtype:
106
            try:
107
                val = rtype(val)
108
            except (ValueError, TypeError) as exc:
109
                msg = "{0} from file: {1} is not a(n) {2}, exception: {3}"
110
                rname = rtype.__name__
111
                raise plumd.ConfigError(msg.format(name, self.path, rname, exc))
112
        return val
113
114
    def set_conf(self, name, val, overwrite=None):
115
        """Set the named configuration to the provided value.
116
117
        If overwrite is False and the value exists it will be left unchanged.
118
119
        :param name: The configuration key to set
120
        :type name: str
121
        :param val: The configuration key is set to this value
122
        :rtype: self -- this object - allows chaining calls
123
        """
124
        name = name.strip()
125
        if name in self.conf and overwrite:
126
            self.conf[name] = val
127
        elif name not in self.conf:
128
            self.conf[name] = val
129
        return self
130
131
    def defaults(self, defconf):
132
        """Update any missing configuration with values from defconf.
133
134
        :param defconf: dict of default values to set
135
        :type defconf: dict
136
        :rtype: self -- this object - allows chaining calls
137
        """
138
        for key, val in defconf.items():
139
            key = key.strip()
140
            if key not in self.conf or self.conf[key] is None:
141
                self.conf[key] = val
142
        return self
143
144
    def write(self):
145
        """Write configuration to self.path."""
146
        with open(self.path, 'w') as wfd:
147
            yaml.dump(self.conf, wfd, default_flow_style=False)
148
            wfd.flush()
149