Failed Conditions
Branch Makman2/conf-parser-auto-trim (6dfaa8)
by Mischa
01:32
created

coalib.parsing.ConfParser.parse()   B

Complexity

Conditions 4

Size

Total Lines 25

Duplication

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