2
# Copyright (c) 2008 Canonical
4
# Written by Marc Tardif <marc@interunion.ca>
6
# This file is part of Checkbox.
8
# Checkbox is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
13
# Checkbox is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
27
class RepositorySection(object):
29
Repository section which is essentially a container of entries. These
30
map to the modules referenced in the configuration passed as argument
34
def __init__(self, config, name):
36
Constructor which takes a configuration instance and name as
37
argument. The former is expected to contain directories and
45
def directories(self):
47
Directory contained for this sections.
49
directories = re.split(r"\s+", self._config.directories)
50
return [posixpath.expanduser(d) for d in directories]
54
Get all the module names contained in the directories for this
57
if self._names is None:
58
if "whitelist" in self._config.attributes:
59
self._names = re.split(r"\s+", self._config.whitelist)
62
if "blacklist" in self._config.attributes:
63
blacklist = re.split(r"\s", self._config.blacklist)
65
for directory in self.directories:
66
names = [p.replace(".py", "")
67
for p in os.listdir(directory)
68
if p.endswith(".py") and p != "__init__.py"]
69
self._names = list(set(names).difference(set(blacklist)))
73
def get_arguments(self, name):
74
config_name = "/".join([self.name, name])
75
config = self._config.parent.get_section(config_name)
81
Load all modules contained in this section.
84
for name in self.get_names():
85
entries.append(self.load_entry(name))
89
def has_entry(self, name):
91
Check if the given name is in this section.
93
return name in self.get_names()
95
def load_entry(self, name):
97
Load a single module by name from this section.
99
logging.info("Loading name %s from section %s",
102
for directory in self.directories:
103
path = posixpath.join(directory, "%s.py" % name)
104
if posixpath.exists(path):
106
exec open(path) in globals
107
if "factory" not in globals:
108
raise Exception, "Variable 'factory' not found: %s" % path
110
arguments = self.get_arguments(name)
111
return globals["factory"](*arguments)
113
raise Exception, "Failed to find module '%s' in directories: %s" \
114
% (name, self.directories)
117
class RepositoryManager(object):
119
Repository manager which is essentially a container of sections.
122
_section_factory = RepositorySection
124
def __init__(self, config):
126
Constructor which takes a configuration instance as argument. This
127
will be used to load sections by name.
129
self._config = config
131
def load_section(self, name):
133
Load a section by name which must correspond to an entry in the
134
configuration instance pased as argument to the constructor.
136
logging.info("Loading repository section %s", name)
137
config = self._config.get_section(name)
138
return self._section_factory(config, name)
141
class Repository(object):
143
Repository base class which should be inherited by each repository
147
required_attributes = []
148
optional_attributes = []
150
def __init__(self, config):
152
Constructor which takes a configuration instance as argument. This
153
can be used to pass options to repositories.
155
self._config = config
159
all_required_attributes = []
160
all_optional_attributes = []
163
for cls_mro in cls.__mro__:
164
for attr, descr in cls_mro.__dict__.iteritems():
165
if attr == "required_attributes":
166
all_required_attributes.extend(descr)
167
elif attr == "optional_attributes":
168
all_optional_attributes.extend(descr)
170
if all_required_attributes and not self._config:
172
"Missing configuration section for required attributes: %s" \
173
% ", ".join(all_required_attributes)
178
for attribute in all_required_attributes:
179
if attribute not in self._config.attributes:
181
"Configuration section '%s' missing required attribute: %s" \
182
% (self._config.name, attribute)
183
elif self._config.attributes[attribute] == "":
185
"Configuration section '%s' has empty required attribute: %s" \
186
% (self._config.name, attribute)
188
for attribute in all_optional_attributes:
189
if attribute not in self._config.attributes:
190
self._config.attributes[attribute] = None
192
all_attributes = all_required_attributes \
193
+ all_optional_attributes \
194
+ self._config.parent.get_defaults().attributes.keys()
195
for attribute in self._config.attributes.keys():
196
if attribute not in all_attributes:
197
logging.info("Configuration section '%s' "
198
"contains unknown attribute: %s",
199
self._config.name, attribute)