ConfParser   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 125
rs 10
wmc 22

7 Methods

Rating   Name   Duplication   Size   Complexity  
B parse() 0 25 4
A get_section() 0 12 3
A __add_comment() 0 8 1
F __parse_lines() 0 48 11
A __refine_key() 0 3 1
A __init_sections() 0 4 1
A __init__() 0 17 1
1
import os
2
from collections import OrderedDict
3
from types import MappingProxyType
4
5
from coalib.misc import Constants
6
from coalib.parsing.LineParser import LineParser
7
from coalib.settings.Section import Section
8
from coalib.settings.Setting import Setting
9
10
11
class ConfParser:
12
13
    def __init__(self,
14
                 key_value_delimiters=('=',),
15
                 comment_seperators=('#',),
16
                 key_delimiters=(',', ' '),
17
                 section_name_surroundings=MappingProxyType({"[": "]"}),
18
                 remove_empty_iter_elements=True):
19
        self.line_parser = LineParser(key_value_delimiters,
20
                                      comment_seperators,
21
                                      key_delimiters,
22
                                      section_name_surroundings)
23
24
        self.__remove_empty_iter_elements = remove_empty_iter_elements
25
26
        # Declare it
27
        self.sections = None
28
        self.__rand_helper = None
29
        self.__init_sections()
30
31
    def parse(self, input_data, overwrite=False):
32
        """
33
        Parses the input and adds the new data to the existing.
34
35
        :param input_data: The filename to parse from.
36
        :param overwrite:  If True, wipes all existing Settings inside this
37
                           instance and adds only the newly parsed ones. If
38
                           False, adds the newly parsed data to the existing
39
                           one (and overwrites already existing keys with the
40
                           newly parsed values).
41
        :return:           A dictionary with (lowercase) section names as keys
42
                           and their Setting objects as values.
43
        """
44
        if os.path.isdir(input_data):
45
            input_data = os.path.join(input_data, Constants.default_coafile)
46
47
        with open(input_data, "r", encoding='utf-8') as _file:
48
            lines = _file.readlines()
49
50
        if overwrite:
51
            self.__init_sections()
52
53
        self.__parse_lines(lines, input_data)
54
55
        return self.sections
56
57
    def get_section(self, name, create_if_not_exists=False):
58
        key = self.__refine_key(name)
59
        sec = self.sections.get(key, None)
60
        if sec is not None:
61
            return sec
62
63
        if not create_if_not_exists:
64
            raise IndexError
65
66
        retval = self.sections[key] = Section(str(name),
67
                                              self.sections["default"])
68
        return retval
69
70
    @staticmethod
71
    def __refine_key(key):
72
        return str(key).lower().strip()
73
74
    def __add_comment(self, section, comment, origin):
75
        key = "comment" + str(self.__rand_helper)
76
        self.__rand_helper += 1
77
        section.append(Setting(
78
            key,
79
            comment,
80
            origin,
81
            remove_empty_iter_elements=self.__remove_empty_iter_elements))
82
83
    def __parse_lines(self, lines, origin):
84
        current_section_name = "default"
85
        current_section = self.get_section(current_section_name)
86
        current_keys = []
87
88
        for line in lines:
89
            section_name, keys, value, comment = self.line_parser.parse(line)
90
91
            if comment != "":
92
                self.__add_comment(current_section, comment, origin)
93
94
            if section_name != "":
95
                current_section_name = section_name
96
                current_section = self.get_section(current_section_name, True)
97
                current_keys = []
98
                continue
99
100
            if comment == "" and keys == [] and value == "":
101
                self.__add_comment(current_section, "", origin)
102
                continue
103
104
            if keys != []:
105
                current_keys = keys
106
107
            for section_override, key in current_keys:
108
                if key == "":
109
                    continue
110
111
                if section_override == "":
112
                    current_section.add_or_create_setting(
113
                        Setting(key,
114
                                value,
115
                                origin,
116
                                # Ignore PEP8Bear, it fails to format that
117
                                remove_empty_iter_elements=
118
                                self.__remove_empty_iter_elements),
119
                        allow_appending=(keys == []))
120
                else:
121
                    self.get_section(
122
                        section_override,
123
                        True).add_or_create_setting(
124
                            Setting(key,
125
                                    value,
126
                                    origin,
127
                                    # Ignore PEP8Bear, it fails to format that
128
                                    remove_empty_iter_elements=
129
                                    self.__remove_empty_iter_elements),
130
                            allow_appending=(keys == []))
131
132
    def __init_sections(self):
133
        self.sections = OrderedDict()
134
        self.sections["default"] = Section("Default")
135
        self.__rand_helper = 0
136