Failed Conditions
Pull Request — master (#1152)
by Lasse
03:36
created

coalib.settings.LogMessage   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 44
Duplicated Lines 0 %
Metric Value
dl 0
loc 44
rs 10
wmc 9

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __ne__() 0 2 1
A to_string_dict() 0 15 2
A __eq__() 0 4 1
A __str__() 0 3 1
A __init__() 0 15 4
1
from collections import OrderedDict
2
import copy
3
import os
4
5
from coalib.misc.Decorators import generate_repr
6
from coalib.settings.Setting import Setting, path_list
7
from coalib.misc.DictUtilities import update_ordered_dict_key
8
from coalib.misc.Constants import Constants
9
10
11
def append_to_sections(sections,
12
                       key,
13
                       value,
14
                       origin,
15
                       section_name=None,
16
                       from_cli=False):
17
    """
18
    Appends the given data as a Setting to a Section with the given name. If
19
    the Section does not exist before it will be created empty.
20
21
    :param sections:     The sections dictionary to add to.
22
    :param key:          The key of the setting to add.
23
    :param value:        The value of the setting to add.
24
    :param origin:       The origin value of the setting to add.
25
    :param section_name: The name of the section to add to.
26
    :param from_cli:     Whether or not this data comes from the CLI.
27
    """
28
    if key == '' or value is None:
29
        return
30
31
    if section_name == "" or section_name is None:
32
        section_name = "default"
33
34
    if not section_name.lower() in sections:
35
        sections[section_name.lower()] = Section(section_name)
36
37
    sections[section_name.lower()].append(
38
        Setting(key, str(value), origin, from_cli=from_cli))
39
40
41
@generate_repr()
42
class Section:
43
    """
44
    This class holds a set of settings.
45
    """
46
47
    @staticmethod
48
    def __prepare_key(key):
49
        return str(key).lower().strip()
50
51
    def __init__(self,
52
                 name,
53
                 defaults=None):
54
        if defaults is not None and not isinstance(defaults, Section):
55
            raise TypeError("defaults has to be a Section object or None.")
56
        if defaults is self:
57
            raise ValueError("defaults may not be self for non-recursivity.")
58
59
        self.name = str(name)
60
        self.defaults = defaults
61
        self.contents = OrderedDict()
62
63
    def bear_dirs(self):
64
        bear_dirs = path_list(self.get("bear_dirs", ""))
65
        bear_dirs.append(os.path.join(Constants.coalib_bears_root, "**"))
66
67
        return bear_dirs
68
69
    def is_enabled(self, targets):
70
        """
71
        Checks if this section is enabled or, if targets is not empty, if it is
72
        included in the targets list.
73
74
        :param targets: List of target section names, all lower case.
75
        :return:        True or False
76
        """
77
        if len(targets) == 0:
78
            return bool(self.get("enabled", "true"))
79
80
        return self.name.lower() in targets
81
82
    def append(self, setting, custom_key=None):
83
        if not isinstance(setting, Setting):
84
            raise TypeError
85
        if custom_key is None:
86
            key = self.__prepare_key(setting.key)
87
        else:
88
            key = self.__prepare_key(custom_key)
89
90
        # Setting asserts key != "" for us
91
        self.contents[key] = setting
92
93
    def add_or_create_setting(self,
94
                              setting,
95
                              custom_key=None,
96
                              allow_appending=True):
97
        """
98
        Adds the value of the setting to an existing setting if there is
99
        already a setting  with the key. Otherwise creates a new setting.
100
        """
101
        if custom_key is None:
102
            key = setting.key
103
        else:
104
            key = custom_key
105
106
        if self.__contains__(key, ignore_defaults=True) and allow_appending:
107
            val = self[key]
108
            val.value = str(val.value) + "\n" + setting.value
109
        else:
110
            self.append(setting, custom_key=key)
111
112
    def __iter__(self, ignore_defaults=False):
113
        joined = self.contents.copy()
114
        if self.defaults is not None and not ignore_defaults:
115
            # Since we only return the iterator of joined (which doesnt contain
116
            # values) it's ok to override values here
117
            joined.update(self.defaults.contents)
118
119
        return iter(joined)
120
121
    def __contains__(self, item, ignore_defaults=False):
122
        try:
123
            self.__getitem__(item, ignore_defaults)
124
125
            return True
126
        except IndexError:
127
            return False
128
129
    def __getitem__(self, item, ignore_defaults=False):
130
        key = self.__prepare_key(item)
131
        if key == "":
132
            raise IndexError("Empty keys are invalid.")
133
134
        res = self.contents.get(key, None)
135
        if res is not None:
136
            return res
137
138
        if self.defaults is None or ignore_defaults:
139
            raise IndexError("Required index is unavailable.")
140
141
        return self.defaults[key]
142
143
    def __str__(self):
144
        value_list = ", ".join(key + " : " + repr(str(self.contents[key]))
145
                               for key in self.contents)
146
        return self.name + " {" + value_list + "}"
147
148
    def get(self, key, default="", ignore_defaults=False):
149
        """
150
        Retrieves the item without raising an exception. If the item is not
151
        available an appropriate Setting will be generated from your provided
152
        default value.
153
154
        :param key:             The key of the setting to return.
155
        :param default:         The default value
156
        :param ignore_defaults: Whether or not to ignore the default section.
157
        :return:                The setting.
158
        """
159
        try:
160
            return self.__getitem__(key, ignore_defaults)
161
        except IndexError:
162
            return Setting(key, str(default))
163
164
    def copy(self):
165
        """
166
        :return: a deep copy of this object
167
        """
168
        result = copy.copy(self)
169
        result.contents = copy.deepcopy(self.contents)
170
        if self.defaults is not None:
171
            result.defaults = self.defaults.copy()
172
173
        return result
174
175
    def update(self, other_section, ignore_defaults=False):
176
        """
177
        Incorporates all keys and values from the other section into this one.
178
        Values from the other section override the ones from this one.
179
180
        Default values from the other section override the default values from
181
        this only.
182
183
        :param other_section:   Another Section
184
        :param ignore_defaults: If set to true, do not take default values from
185
                                other
186
        :return:                self
187
        """
188
        if not isinstance(other_section, Section):
189
            raise TypeError("other_section has to be a Section")
190
191
        self.contents.update(other_section.contents)
192
193
        if not ignore_defaults and other_section.defaults is not None:
194
            if self.defaults is None:
195
                self.defaults = other_section.defaults.copy()
196
            else:
197
                self.defaults.update(other_section.defaults)
198
199
        return self
200
201
    def update_setting(self,
202
                       key,
203
                       new_key=None,
204
                       new_value=None):
205
        """
206
        Updates a setting with new values.
207
        :param key:       The old key string.
208
        :param new_key:   The new key string.
209
        :param new_value: The new value for the setting
210
        """
211
        if new_key is not None:
212
            self.contents[key].key = new_key
213
            self.contents = update_ordered_dict_key(self.contents,
214
                                                    key,
215
                                                    new_key)
216
        if new_value is not None:
217
            if new_key is not None:
218
                self.contents[new_key].value = new_value
219
            else:
220
                self.contents[key].value = new_value
221
222
    def delete_setting(self, key):
223
        """
224
        Delete a setting
225
        :param key: The key of the setting to be deleted
226
        """
227
        del self.contents[key]
228