Test Failed
Push — master ( db4166...efa4d0 )
by Thomas
11:36
created

exabgp.environment.environment   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 142
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 105
dl 0
loc 142
rs 9.92
c 0
b 0
f 0
wmc 31

6 Methods

Rating   Name   Duplication   Size   Complexity  
B Env.iter_ini() 0 16 7
A Env.settings() 0 3 1
A NoneDict.__getitem__() 0 2 1
B Env.iter_env() 0 18 7
C Env.setup() 0 42 10
A Env.default() 0 19 5
1
# encoding: utf-8
2
"""
3
environment.py
4
5
Created by Thomas Mangin on 2011-11-29.
6
Copyright (c) 2011-2017 Exa Networks. All rights reserved.
7
License: 3-clause BSD. (See the COPYRIGHT file)
8
"""
9
10
import os
11
12
import configparser as ConfigParser
13
14
from exabgp.environment import base
15
from exabgp.environment import parsing
16
from exabgp.environment.base import ENVFILE
17
from exabgp.environment.hashtable import HashTable
18
from exabgp.environment.hashtable import GlobalHashTable
19
20
21
class NoneDict(dict):
22
    def __getitem__(self, name):
23
        return None
24
25
26
nonedict = NoneDict()
27
28
29
class Env(object):
30
    _setup = False
31
32
    # the configuration to be set by the program
33
    definition = {}
34
35
    # one copy of the global configuration
36
    _env = GlobalHashTable()
37
38
    @classmethod
39
    def default(cls):
40
        for section in sorted(cls.definition):
41
            if section in ('internal', 'debug'):
42
                continue
43
            for option in sorted(cls.definition[section]):
44
                values = cls.definition[section][option]
45
                default = (
46
                    "'%s'" % values['value']
47
                    if values['write'] in (parsing.list, parsing.path, parsing.quote, parsing.syslog_name)
48
                    else values['value']
49
                )
50
                yield '%s.%s.%s %s %s. default (%s)' % (
51
                    base.APPLICATION,
52
                    section,
53
                    option,
54
                    ' ' * (18 - len(section) - len(option)),
55
                    values['help'],
56
                    default,
57
                )
58
59
    @classmethod
60
    def iter_ini(cls, diff=False):
61
        for section in sorted(cls._env):
62
            if section in ('internal', 'debug'):
63
                continue
64
            header = '\n[%s.%s]' % (base.APPLICATION, section)
65
            for k in sorted(cls._env[section]):
66
                v = cls._env[section][k]
67
                func = cls.definition[section][k]['read']
68
                value = cls.definition[section][k]['value']
69
                if diff and func(value) == v:
70
                    continue
71
                if header:
72
                    yield header
73
                    header = ''
74
                yield '%s = %s' % (k, cls.definition[section][k]['write'](v))
75
76
    @classmethod
77
    def iter_env(cls, diff=False):
78
        for section, values in cls._env.items():
79
            if section in ('internal', 'debug'):
80
                continue
81
            for k, v in values.items():
82
                func = cls.definition[section][k]['read']
83
                value = cls.definition[section][k]['value']
84
                if diff and func(value) == v:
85
                    continue
86
                if cls.definition[section][k]['write'] == parsing.quote:
87
                    yield "%s.%s.%s='%s'" % (base.APPLICATION, section, k, v)
88
                    continue
89
                yield "%s.%s.%s=%s" % (
90
                    base.APPLICATION,
91
                    section,
92
                    k,
93
                    cls.definition[section][k]['write'](v),
94
                )
95
96
    @classmethod
97
    def setup(cls, configuration):
98
        if cls._setup:
99
            return {}
100
        cls._setup = True
101
        cls.definition = configuration
102
103
        ini = ConfigParser.ConfigParser()
104
105
        _conf_paths = [
106
            ENVFILE,
107
        ]
108
109
        ini_files = [path for path in _conf_paths if os.path.exists(path)]
110
        if ini_files:
111
            ini.read(ini_files[0])
112
113
        for section in cls.definition:
114
            default = cls.definition[section]
115
116
            for option in default:
117
                convert = default[option]['read']
118
                try:
119
                    proxy_section = '%s.%s' % (base.APPLICATION, section)
120
                    env_name = '%s.%s' % (proxy_section, option)
121
                    rep_name = env_name.replace('.', '_')
122
123
                    if env_name in os.environ:
124
                        conf = os.environ.get(env_name)
125
                    elif rep_name in os.environ:
126
                        conf = os.environ.get(rep_name)
127
                    else:
128
                        conf = parsing.unquote(ini.get(proxy_section, option, vars=nonedict))
129
                        # name without an = or : in the configuration and no value
130
                        if conf is None:
131
                            conf = default[option]['value']
132
                except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
133
                    conf = default[option]['value']
134
                try:
135
                    cls._env.setdefault(section, HashTable())[option] = convert(conf)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable HashTable does not seem to be defined.
Loading history...
136
                except TypeError:
137
                    raise ValueError('invalid value for %s.%s : %s' % (section, option, conf))
138
139
    @classmethod
140
    def settings(cls):
141
        return cls._env
142