Completed
Push — master ( d058c9...ca4b9c )
by Kenny
45s
created

plumd.Conf.__init__()   A

Complexity

Conditions 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 4
dl 0
loc 19
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
__author__ = 'Kenny Freeman'
8
__email__ = '[email protected]'
9
__license__     = "ISCL"
10
__docformat__   = 'reStructuredText'
11
12
import os.path
13
import glob
14
15
import yaml # pip install pyaml
16
17
import plumd
18
19
20
def ls(dname, ext):
21
    """Helper to return a list of the yaml files in a directory.
22
23
    :param dname: Path to list files in
24
    :type name: str
25
    :param ext: Extension to use in glob call, default "yaml"
26
    :type name: str
27
    :rtype: list -- a list of of the filenames found or []
28
    """
29
    if os.path.isdir(dname):
30
        try:
31
            return glob.glob(os.path.join(dname, "*.{0}".format(ext)))
32
        except AttributeError as e:
33
            raise plumd.ConfigError("invalid path? {0} : {1}".format(dname, e))
34
    return []
35
36
37
class Conf(object):
38
    """Simple key/value configuration helper class for small yaml files.
39
40
    :param cfile: Full path to the configuration file to load
41
    :type name: str
42
    :raises: ConfigError: if the specified file does not exist
43
    """
44
45
    def __init__(self, cfile):
46
        """conf constructor.
47
48
        :param cfile: Full path to the configuration file to load
49
        :type name: str
50
        :rtype: conf -- an instance of conf
51
        :raises: ConfigError: if the specified file does not exist
52
        """
53
        self.conf = {}
54
        self.path = cfile
55
        if os.path.isfile(cfile):
56
            with open(cfile) as fd:
57
                try:
58
                    self.conf = yaml.safe_load(fd)
59
                except yaml.scanner.ScannerError as e:
60
                    msg = "invalid: {0} : {1}".format(cfile, e)
61
                    raise plumd.ConfigError(msg)
62
        else:
63
            raise plumd.ConfigError("file {0} does not exist".format(cfile))
64
65
66
    def __str__(self):
67
        """Return a nicely formatted string of our config.
68
        :rtype: str
69
        """
70
        return yaml.dump(self.conf,allow_unicode=False,default_flow_style=False)
71
72
73
    def __repr__(self):
74
        """Return a nicely formatted string of our config.
75
        :rtype: str
76
        """
77
        return yaml.dump(self.conf,allow_unicode=True,default_flow_style=False)
78
79
80
    def get(self, name, exception=False, default=None, rtype=None):
81
        """Returns the requested value, the provided default or None.
82
83
        raises:
84
            ConfigError if exception=True and the requested key is not found.
85
86
        :param name: The configuration value to lookup and return
87
        :type name: str
88
        :param exception: If True raise a ConfigError if the vlaue is not present
89
        :type exception: bool
90
        :param default: The default value to return if value is not found
91
        :rtype: value -- the configured value for the requested name or default
92
        :raises: ConfigError
93
        """
94
        val = default
95
        if name in self.conf and self.conf[name] is not None:
96
            val = self.conf[name]
97
        elif exception:
98
            msg = "missing {0} in: {1}".format(name, self.path)
99
            raise plumd.ConfigError(msg)
100
        if rtype is not None:
101
            try:
102
                val = rtype(val)
103
            except (ValueError, TypeError) as e:
104
                msg = "value error for {0} in: {1} : {2}"
105
                raise plumd.ConfigError(msg.format(name, self.path, e))
106
        return val
107
108
109
    def set_conf(self, name, val, overwrite=False):
110
        """Sets the named configuration to the provided value.
111
112
        If overwrite is False and the value exists it will be left unchanged.
113
114
        :param name: The configuration key to set
115
        :type name: str
116
        :param val: The configuration key is set to this value
117
        :rtype: self -- this object - allows chaining calls
118
        """
119
        name = name.strip()
120
        if name in self.conf and overwrite:
121
            self.conf[name] = val
122
        elif name not in self.conf:
123
            self.conf[name] = val
124
        return self
125
126
127
    def defaults(self, defconf):
128
        """Updates any missing configurations with values from defconf.
129
130
        :param defconf: dict of default values to set
131
        :type defconf: dict
132
        :rtype: self -- this object - allows chaining calls
133
        """
134
        for key, val in defconf.items():
135
            key = key.strip()
136
            if key not in self.conf or self.conf[key] is None:
137
                self.conf[key] = val
138
        return self
139