aboutsummaryrefslogtreecommitdiff
path: root/lib/dodai/config/sections.py
blob: d789a246d849e19ec9df479b3290aed938eb09e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# Copyright (C) 2010  Leonard Thomas
#
# This file is part of Dodai.
#
# Dodai is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Dodai is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Dodai.  If not, see <http://www.gnu.org/licenses/>.


class ConfigSections(object):
    """
    An iterable object that contains ConfigSection objects

    """

    def __init__(self, ordered_dict_object, section_object,
                 string_object = None,):
        """
        Iterable object that handles the conversion of a config
        parser object to a list of section objects.


        string_object:  This is an object (non instantiated or
                        callable) that the results of the config's
                        sections, and options will be stored in.
                        This enables you to store your values as a
                        custom object.  A good object to use is the
                        dodai.tools.himo Himo object.  If the
                        string_object is not given the default python
                        str() object will be used. The callable of
                        this object must also allow for encoding
                        to be passed in string_object(data, 'UTF-8')


        """
        self._string_object = string_object or ''
        self._ordered_dict_object = ordered_dict_object
        self._section_object = section_object
        self._sections = self._ordered_dict_object()

    def __call__(self, parser, encoding=None):
        """
        Parses the given parser object into this object's sections.

        parser:         The actual parser object that is used to
                        get the sections.  This object must have
                        the sections(), options() and get()
                        methods.  A good object to use is the native
                        ConfigParse object.  However, you can create
                        your own

        """
        self._build_sections(parser, encoding)

    def _build_sections(self, parser, encoding):
        # Builds ConfigSection objects from the parser object

        for section_name in parser.sections():
            section = self.get_section(section_name, encoding)
            self._build_options(parser, section_name, section, encoding)

    def _build_options(self, parser, section_name, section, encoding):
        # Adds the options to the section object

        for key in parser.options(section_name):
            value = self._build_string_object(parser.get(section_name, key),
                                              encoding)
            key = self._build_string_object(key, encoding)
            section[key] = value

    def _build_string_object(self, data, encoding=None):
        if self._string_object:
            return self._string_object(data, encoding)
        else:
            return data

    def get_section(self, section_name, encoding=None):
        """
        Returns a Section (aka dict) object from this object's section
        dictionary or creates a new ConfigSection object, which is
        stored int this object's section dictionary then is returned

        """
        section_name = self._build_string_object(section_name, encoding)
        if section_name in self._sections:
            return self._sections[section_name]
        else:
            section = self._section_object(section_name)
            self._sections[section_name] = section
            return section

    def __getitem__(self, key):
        return self._sections[key]

    def __getattr__(self, key):
        try:
            out = self._sections[key]
        except KeyError:
            return getattr(self._sections, key)
        else:
            return out

    def __iter__(self, *args, **kargs):
        return self._sections.__iter__(*args, **kargs)


    def __len__(self):
        return len(self._sections)