18
20
ALL_CATEGORIES = [DESKTOP, LAPTOP, SERVER]
25
ALL_ARCHITECTURES = [I386, AMD64, SPARC]
21
28
class QuestionParser(object):
23
30
def __init__(self):
24
31
self.questions = []
26
def load_data(self, **data):
27
if "name" not in data:
33
def _load_properties(self, **properties):
34
if "name" not in properties:
29
"Question data does not contain a 'name': %s" % data
31
logging.info("Loading question data for: %s", data["name"])
33
if filter(lambda q: q["name"] == data["name"], self.questions):
36
"Question properties does not contain a 'name': %s" % properties
38
logging.info("Loading question properties for: %s", properties["name"])
40
if filter(lambda q: q["name"] == properties["name"], self.questions):
35
42
"Question %s already has a question of the same name." \
38
self.questions.append(data)
40
def load_path(self, path):
41
logging.info("Loading question from path: %s", path)
45
self.questions.append(properties)
47
def _load_descriptor(self, fd, name):
44
48
for string in reader(fd):
47
def save(field, value, extended, path):
53
properties["suite"] = os.path.basename(name)
55
def _save(field, value, extended, name):
48
56
if value and extended:
50
"Path %s has both a value and an extended value." % path
58
"Path %s has both a value and an extended value." % name
51
59
extended = extended.rstrip("\n")
53
if data.has_key(field):
61
if properties.has_key(field):
55
63
"Path %s has a duplicate field '%s' with a new value '%s'." \
56
% (path, field, value)
57
data[field] = value or extended
64
% (name, field, value)
65
properties[field] = value or extended
59
67
string = string.strip("\n")
60
68
field = value = extended = ''
63
71
match = re.search(r"^([-_.A-Za-z0-9]*):\s?(.*)", line)
65
save(field, value, extended, path)
73
_save(field, value, extended, name)
66
74
field = match.groups()[0].lower()
67
75
value = match.groups()[1].rstrip()
94
102
raise Exception, "Path %s parse error at: %s" \
97
save(field, value, extended, path)
98
self.load_data(**data)
105
_save(field, value, extended, name)
106
self._load_properties(**properties)
108
def load_string(self, str):
109
logging.info("Loading question from string")
111
self._load_descriptor(fd, "string")
113
def load_path(self, path):
114
logging.info("Loading question from path: %s", path)
117
self._load_descriptor(fd, path)
100
119
def load_directory(self, directory):
101
120
logging.info("Loading questions from directory: %s", directory)
149
168
class Question(object):
151
required_fields = ["name", "description"]
170
required_fields = ["name", "description", "suite"]
152
171
optional_fields = {
172
"architectures": ALL_ARCHITECTURES,
153
173
"categories": ALL_CATEGORIES,
156
176
"optional": False}
158
178
def __init__(self, **kwargs):
179
self.properties = kwargs
160
180
self.answer = None
183
def get_properties(self):
185
for f in Question.required_fields + Question.optional_fields.keys():
186
properties[f] = self.properties[f]
188
properties['answer'] = self.answer.get_properties()
163
191
def _validate(self):
164
for field in self.data.keys():
193
for field in self.properties.keys():
165
194
if field not in self.required_fields + self.optional_fields.keys():
166
195
raise Exception, \
167
"Question data contains unknown field: %s" \
196
"Question properties contains unknown field: %s" \
170
200
for field in self.required_fields:
171
if not self.data.has_key(field):
201
if not self.properties.has_key(field):
172
202
raise Exception, \
173
"Question data does not contain a '%s': %s" \
203
"Question properties does not contain a '%s': %s" \
204
% (field, properties)
207
for field in ["architectures", "categories", "depends"]:
208
if self.properties.has_key(field):
209
self.properties[field] = re.split(r"\s*,\s*", self.properties[field])
176
212
for field in self.optional_fields.keys():
177
if not self.data.has_key(field):
178
self.data[field] = self.optional_fields[field]
213
if not self.properties.has_key(field):
214
self.properties[field] = self.optional_fields[field]
180
216
def __str__(self):
183
219
def __getattr__(self, attr):
184
if attr in self.data:
185
return self.data[attr]
220
if attr in self.properties:
221
return self.properties[attr]
187
223
raise AttributeError, attr