2
# This file is part of Checkbox.
4
# Copyright 2008 Canonical Ltd.
6
# Checkbox is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License version 3,
8
# as published by the Free Software Foundation.
11
# Checkbox is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
23
EXTENDED_STRING = "_extended"
28
def _reader(self, file, size=4096, delimiter=r"\n{2,}"):
31
buffer_new = file.read(size)
35
lines = re.split(delimiter, buffer_old + buffer_new)
36
buffer_old = lines.pop(-1)
43
def dump_file(self, elements, file, filename="<stream>"):
44
for element in elements:
45
for long_key in list(element.keys()):
46
if long_key.endswith(EXTENDED_STRING):
47
short_key = long_key.replace(EXTENDED_STRING, "")
48
del element[short_key]
50
for key, value in element.items():
51
if key.endswith(EXTENDED_STRING):
52
key = key.replace(EXTENDED_STRING, "")
53
file.write("%s:\n" % key)
54
for line in value.split("\n"):
55
file.write(" %s\n" % line)
56
elif isinstance(value, (list, tuple)):
57
file.write("%s:\n" % key)
59
file.write(" %s\n" % v)
61
file.write("%s: %s\n" % (key, value))
65
def dump_filename(self, elements, filename):
66
logging.info("Dumping elements to filename: %s", filename)
68
with open(filename, "w") as stream:
69
return self.dump_file(elements, stream, filename)
71
def load_file(self, file, filename="<stream>"):
73
for string in self._reader(file):
79
def _save(field, value, extended):
80
extended = extended.rstrip("\n")
83
raise Exception("Template %s has a duplicate "
84
"field '%s' with a new value '%s'."
85
% (filename, field, value))
86
element[field] = value
88
element["%s%s" % (field, EXTENDED_STRING)] = extended
90
string = string.strip("\n")
91
field = value = extended = ""
92
for line in string.split("\n"):
94
if line.startswith("#"):
97
match = re.search(r"^([-_.A-Za-z0-9@]*):\s?(.*)", line)
99
_save(field, value, extended)
100
field = match.groups()[0]
101
value = match.groups()[1].rstrip()
105
if re.search(r"^\s\.$", line):
109
match = re.search(r"^\s(\s+.*)", line)
111
bit = match.groups()[0].rstrip()
112
if len(extended) and not re.search(r"[\n ]$", extended):
115
extended += bit + "\n"
118
match = re.search(r"^\s(.*)", line)
120
bit = match.groups()[0].rstrip()
121
if len(extended) and not re.search(r"[\n ]$", extended):
122
if extended.endswith("\\"):
123
extended = extended[:-1].rstrip() + " "
130
raise Exception("Template %s parse error at: %s" \
133
_save(field, value, extended)
135
elements.append(element)
139
def load_filename(self, filename):
140
logging.info("Loading elements from filename: %s", filename)
142
with open(filename, "r", encoding="utf-8") as stream:
143
return self.load_file(stream, filename)