10
10
the full text of the license.
13
import bz2, base64, time
13
import bz2, base64, time, UserDict
15
class ProblemReport(UserDict.IterableUserDict):
16
16
def __init__(self, type = 'Crash', date = None):
17
17
'''Initialize a fresh problem report.
23
23
date = time.asctime()
24
self.info = {'ProblemType': type, 'Date': date}
24
self.data = {'ProblemType': type, 'Date': date}
26
26
def load(self, file, binary=True):
27
27
'''Initialize problem report from a file-like object, using Debian
59
62
bd = bz2.BZ2Decompressor()
62
self.info[key] = value
65
self.data[key] = value
67
def _is_binary(self, string):
68
'''Check if the given strings contains binary data.'''
71
if c < ' ' and not c.isspace():
64
75
def write(self, file):
65
76
'''Write information into the given file-like object, using Debian
70
81
which will be read, bzip2'ed, and base64-encoded.
73
keys = self.info.keys()
84
keys = self.data.keys()
74
85
keys.remove('ProblemType')
76
87
keys.insert(0, 'ProblemType')
79
90
# if it's a string, copy it
80
91
if hasattr(v, 'find'):
92
if self._is_binary(v):
93
file.write (k + ': base64\n ')
94
bc = bz2.BZ2Compressor(9)
95
outblock = bc.compress(v)
97
file.write(base64.b64encode(outblock))
99
file.write(base64.b64encode(bc.flush()))
101
elif v.find('\n') >= 0:
82
102
assert v.find('\n\n') < 0
83
103
print >> file, k + ':'
84
104
print >> file, '', v.replace('\n', '\n ')
105
def __getitem__(self, k):
106
return self.info.__getitem__(k)
108
125
def __setitem__(self, k, v):
109
126
assert hasattr(k, 'isalnum')
110
127
assert k.isalnum()
113
130
(hasattr(v, '__getitem__') and len(v) == 1
114
131
and hasattr(v[0], 'isalnum')))
116
return self.info.__setitem__(k, v)
118
def __delitem__(self, k):
119
return self.info.__delitem__(k)
122
return self.info.__iter__()
125
return self.info.has_key(k)
133
return self.data.__setitem__(k, v)
194
203
self.assertEqual(pr['ProblemType'], 'Crash')
195
204
self.assertEqual(pr['Date'], 'now!')
196
205
self.assertEqual(pr['Simple'], 'bar')
206
self.assertEqual(pr['WhiteSpace'], ' foo bar\nbaz\n blip ')
208
# test last field a bit more
209
pr.load(StringIO.StringIO(
210
'''ProblemType: Crash
219
self.assertEqual(pr['ProblemType'], 'Crash')
220
self.assertEqual(pr['Date'], 'now!')
221
self.assertEqual(pr['Simple'], 'bar')
197
222
self.assertEqual(pr['WhiteSpace'], ' foo bar\nbaz\n blip \n')
224
pr.load(StringIO.StringIO(
225
'''ProblemType: Crash
232
self.assertEqual(pr['WhiteSpace'], ' foo bar\nbaz\n blip ')
233
self.assertEqual(pr['Last'], 'foo')
235
pr.load(StringIO.StringIO(
236
'''ProblemType: Crash
244
self.assertEqual(pr['WhiteSpace'], ' foo bar\nbaz\n blip ')
245
self.assertEqual(pr['Last'], 'foo\n')
247
# test that load() cleans up properly
248
pr.load(StringIO.StringIO('ProblemType: Crash'))
249
self.assertEqual(pr.keys(), ['ProblemType'])
199
251
def test_write_file(self):
200
252
'''Test writing a report with binary file data.'''
262
314
self.assertEqual(pr['Before'], 'xtestx')
263
315
self.assertEqual(pr['ZAfter'], 'ytesty')
318
io2 = StringIO.StringIO()
320
self.assertEqual(io.getvalue(), io2.getvalue())
265
322
def test_iter(self):
266
323
'''Test ProblemReport iteration.'''
277
334
self.assertEqual(len([k for k in pr if k != 'foo']), 2)
336
def test_modify(self):
337
'''Test reading, modifying fields, and writing back.'''
339
report = '''ProblemType: Crash
342
QlpoOTFBWSZTWc5ays4AAAdGAEEAMAAAECAAMM0AkR6fQsBSDhdyRThQkM5ays4=
351
pr.load(StringIO.StringIO(report))
353
self.assertEqual(pr['Long'], 'xxx\n.\nyyy')
355
# write back unmodified
356
io = StringIO.StringIO()
358
self.assertEqual(io.getvalue(), report)
360
pr['Short'] = 'aaa\nbbb'
362
io = StringIO.StringIO()
364
self.assertEqual(io.getvalue(),
365
'''ProblemType: Crash
368
QlpoOTFBWSZTWc5ays4AAAdGAEEAMAAAECAAMM0AkR6fQsBSDhdyRThQkM5ays4=
279
375
if __name__ == '__main__':