home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / problem_report.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  11.0 KB  |  327 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. '''Store, load, and handle problem reports.
  5.  
  6. Copyright (C) 2006 Canonical Ltd.
  7. Author: Martin Pitt <martin.pitt@ubuntu.com>
  8.  
  9. This program is free software; you can redistribute it and/or modify it
  10. under the terms of the GNU General Public License as published by the
  11. Free Software Foundation; either version 2 of the License, or (at your
  12. option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
  13. the full text of the license.
  14. '''
  15. import bz2
  16. import base64
  17. import time
  18. import UserDict
  19.  
  20. class ProblemReport(UserDict.IterableUserDict):
  21.     
  22.     def __init__(self, type = 'Crash', date = None):
  23.         """Initialize a fresh problem report.
  24. \t
  25. \ttype can be 'Crash', 'Packaging', or 'Kernel'. date is the desired
  26. \tdate/time string; if None (default), the current local time is used. """
  27.         if date == None:
  28.             date = time.asctime()
  29.         
  30.         self.data = {
  31.             'ProblemType': type,
  32.             'Date': date }
  33.  
  34.     
  35.     def load(self, file, binary = True):
  36.         '''Initialize problem report from a file-like object, using Debian
  37. \tcontrol file format.
  38. \t
  39. \tif binary is False, binary data is not loaded; the dictionary key is
  40. \tcreated, but its value will be an empty string.'''
  41.         self.data.clear()
  42.         key = None
  43.         value = None
  44.         b64_block = False
  45.         for line in file:
  46.             if line.startswith(' '):
  47.                 if b64_block and not binary:
  48.                     continue
  49.                 
  50.                 if b64_block:
  51.                     value += bd.decompress(base64.b64decode(line))
  52.                 elif len(value) > 0:
  53.                     value += '\n'
  54.                 
  55.                 value += line[1:-1]
  56.                 continue
  57.             if b64_block:
  58.                 b64_block = False
  59.                 bd = None
  60.             
  61.             if key:
  62.                 self.data[key] = value
  63.             
  64.             (key, value) = line.split(':', 1)
  65.             value = value.strip()
  66.             if value == 'base64':
  67.                 value = ''
  68.                 b64_block = True
  69.                 if binary:
  70.                     bd = bz2.BZ2Decompressor()
  71.                 
  72.             binary
  73.         
  74.         if key != None:
  75.             self.data[key] = value
  76.         
  77.  
  78.     
  79.     def has_removed_fields(self):
  80.         '''Check whether the report has any keys which were not loaded in load()
  81. \tdue to being compressed binary.'''
  82.         return '' in self.itervalues()
  83.  
  84.     
  85.     def _is_binary(self, string):
  86.         '''Check if the given strings contains binary data.'''
  87.         for c in string:
  88.             if c < ' ' and not c.isspace():
  89.                 return True
  90.                 continue
  91.         
  92.         return False
  93.  
  94.     
  95.     def write(self, file):
  96.         """Write information into the given file-like object, using Debian
  97. \tcontrol file format.
  98.  
  99. \tIf a value is a string, it is written directly. Otherwise it must be a
  100. \ttuple containing a string, and an optional boolean value (in that
  101. \torder); the first argument is interpreted as a file name, which will be
  102. \tread and its content will become the value of this key.
  103.  
  104. \tThe second argument specifies whether the contents will be
  105. \tbzip2'ed and base64-encoded (this defaults to True).
  106. \t"""
  107.         keys = self.data.keys()
  108.         keys.remove('ProblemType')
  109.         keys.sort()
  110.         keys.insert(0, 'ProblemType')
  111.         for k in keys:
  112.             v = self.data[k]
  113.             if hasattr(v, 'find'):
  114.                 if self._is_binary(v):
  115.                     file.write(k + ': base64\n ')
  116.                     bc = bz2.BZ2Compressor(9)
  117.                     outblock = bc.compress(v)
  118.                     if outblock:
  119.                         file.write(base64.b64encode(outblock))
  120.                         file.write('\n ')
  121.                     
  122.                     file.write(base64.b64encode(bc.flush()))
  123.                     file.write('\n')
  124.                 elif v.find('\n') >= 0:
  125.                     print >>file, k + ':'
  126.                     print >>file, '', v.replace('\n', '\n ')
  127.                 else:
  128.                     print >>file, k + ':', v
  129.             self._is_binary(v)
  130.             f = open(v[0])
  131.             if len(v) >= 2 and not v[1]:
  132.                 v = f.read()
  133.                 if v.find('\n') >= 0:
  134.                     print >>file, k + ':'
  135.                     print >>file, '', v.replace('\n', '\n ')
  136.                 else:
  137.                     print >>file, k + ':', v
  138.             v.find('\n') >= 0
  139.             print >>file, k + ': base64'
  140.             file.write(' ')
  141.             bc = bz2.BZ2Compressor(9)
  142.             while True:
  143.                 block = f.read(512 * 1024)
  144.                 if block:
  145.                     outblock = bc.compress(block)
  146.                     if outblock:
  147.                         file.write(base64.b64encode(outblock))
  148.                         file.write('\n ')
  149.                     
  150.                 outblock
  151.                 file.write(base64.b64encode(bc.flush()))
  152.                 file.write('\n')
  153.                 break
  154.         
  155.  
  156.     
  157.     def __setitem__(self, k, v):
  158.         return self.data.__setitem__(k, v)
  159.  
  160.  
  161. import unittest
  162. import StringIO
  163. import tempfile
  164. import os
  165.  
  166. class _ProblemReportTest(unittest.TestCase):
  167.     
  168.     def test_basic_operations(self):
  169.         '''Test basic creation and operation.'''
  170.         pr = ProblemReport()
  171.         pr['foo'] = 'bar'
  172.         pr['bar'] = ' foo   bar\nbaz\n   blip  '
  173.         self.assertEqual(pr['foo'], 'bar')
  174.         self.assertEqual(pr['bar'], ' foo   bar\nbaz\n   blip  ')
  175.         self.assertEqual(pr['ProblemType'], 'Crash')
  176.         self.assert_(time.strptime(pr['Date']))
  177.  
  178.     
  179.     def test_ctor_arguments(self):
  180.         '''Test non-default constructor arguments.'''
  181.         pr = ProblemReport('Kernel')
  182.         self.assertEqual(pr['ProblemType'], 'Kernel')
  183.         pr = ProblemReport(date = '19801224 12:34')
  184.         self.assertEqual(pr['Date'], '19801224 12:34')
  185.  
  186.     
  187.     def test_sanity_checks(self):
  188.         '''Test various error conditions.'''
  189.         pr = ProblemReport()
  190.         self.assertRaises(AssertionError, pr.__setitem__, 'a b', '1')
  191.         self.assertRaises(AssertionError, pr.__setitem__, 'a', 1)
  192.         self.assertRaises(AssertionError, pr.__setitem__, 'a', 1)
  193.         self.assertRaises(AssertionError, pr.__setitem__, 'a', (1,))
  194.         self.assertRaises(AssertionError, pr.__setitem__, 'a', ('/tmp/nonexistant', ''))
  195.         self.assertRaises(KeyError, pr.__getitem__, 'Nonexistant')
  196.  
  197.     
  198.     def test_write(self):
  199.         '''Test write() and proper formatting.'''
  200.         pr = ProblemReport(date = 'now!')
  201.         pr['Simple'] = 'bar'
  202.         pr['WhiteSpace'] = ' foo   bar\nbaz\n  blip  '
  203.         io = StringIO.StringIO()
  204.         pr.write(io)
  205.         self.assertEqual(io.getvalue(), 'ProblemType: Crash\nDate: now!\nSimple: bar\nWhiteSpace:\n  foo   bar\n baz\n   blip  \n')
  206.  
  207.     
  208.     def test_load(self):
  209.         '''Test load() with various formatting.'''
  210.         pr = ProblemReport()
  211.         pr.load(StringIO.StringIO('ProblemType: Crash\nDate: now!\nSimple: bar\nWhiteSpace:\n  foo   bar\n baz\n   blip  \n'))
  212.         self.assertEqual(pr['ProblemType'], 'Crash')
  213.         self.assertEqual(pr['Date'], 'now!')
  214.         self.assertEqual(pr['Simple'], 'bar')
  215.         self.assertEqual(pr['WhiteSpace'], ' foo   bar\nbaz\n  blip  ')
  216.         pr.load(StringIO.StringIO('ProblemType: Crash\nDate: now!\nSimple: bar\nWhiteSpace:\n  foo   bar\n baz\n   blip  \n \n'))
  217.         self.assertEqual(pr['ProblemType'], 'Crash')
  218.         self.assertEqual(pr['Date'], 'now!')
  219.         self.assertEqual(pr['Simple'], 'bar')
  220.         self.assertEqual(pr['WhiteSpace'], ' foo   bar\nbaz\n  blip  \n')
  221.         pr = ProblemReport()
  222.         pr.load(StringIO.StringIO('ProblemType: Crash\nWhiteSpace:\n  foo   bar\n baz\n   blip  \nLast: foo\n'))
  223.         self.assertEqual(pr['WhiteSpace'], ' foo   bar\nbaz\n  blip  ')
  224.         self.assertEqual(pr['Last'], 'foo')
  225.         pr.load(StringIO.StringIO('ProblemType: Crash\nWhiteSpace:\n  foo   bar\n baz\n   blip  \nLast: foo\n \n'))
  226.         self.assertEqual(pr['WhiteSpace'], ' foo   bar\nbaz\n  blip  ')
  227.         self.assertEqual(pr['Last'], 'foo\n')
  228.         pr.load(StringIO.StringIO('ProblemType: Crash'))
  229.         self.assertEqual(pr.keys(), [
  230.             'ProblemType'])
  231.  
  232.     
  233.     def test_write_file(self):
  234.         '''Test writing a report with binary file data.'''
  235.         temp = tempfile.NamedTemporaryFile()
  236.         temp.write('AB' * 10 + '\x00' * 10 + 'Z')
  237.         temp.flush()
  238.         pr = ProblemReport(date = 'now!')
  239.         pr['File'] = (temp.name,)
  240.         io = StringIO.StringIO()
  241.         pr.write(io)
  242.         temp.close()
  243.         self.assertEqual(io.getvalue(), 'ProblemType: Crash\nDate: now!\nFile: base64\n QlpoOTFBWSZTWc5ays4AAAdGAEEAMAAAECAAMM0AkR6fQsBSDhdyRThQkM5ays4=\n')
  244.         temp = tempfile.NamedTemporaryFile()
  245.         temp.write('foo\x00bar')
  246.         temp.flush()
  247.         pr = ProblemReport(date = 'now!')
  248.         pr['File'] = (temp.name, False)
  249.         io = StringIO.StringIO()
  250.         pr.write(io)
  251.         self.assertEqual(io.getvalue(), 'ProblemType: Crash\nDate: now!\nFile: foo\x00bar\n')
  252.         pr['File'] = (temp.name, True)
  253.         io = StringIO.StringIO()
  254.         pr.write(io)
  255.         self.assertEqual(io.getvalue(), 'ProblemType: Crash\nDate: now!\nFile: base64\n QlpoOTFBWSZTWQ7a+J8AAAHBgEAAMQCQACAAIhhoMAsZAwu5IpwoSAdtfE+A\n')
  256.         temp.close()
  257.  
  258.     
  259.     def test_read_file(self):
  260.         '''Test reading a report with binary data.'''
  261.         bin_report = 'ProblemType: Crash\nDate: now!\nFile: base64\n QlpoOTFBWSZTWc5ays4AAAdGAEEAMAAAECAAMM0AkR6fQsBSDhdyRThQkM5ays4=\nFoo: Bar\n'
  262.         pr = ProblemReport()
  263.         pr.load(StringIO.StringIO(bin_report))
  264.         self.assertEqual(pr['File'], 'AB' * 10 + '\x00' * 10 + 'Z')
  265.         self.assertEqual(pr.has_removed_fields(), False)
  266.         pr.load(StringIO.StringIO(bin_report), binary = False)
  267.         self.assertEqual(pr['File'], '')
  268.         self.assertEqual(pr.has_removed_fields(), True)
  269.  
  270.     
  271.     def test_big_file(self):
  272.         '''Test writing and re-decoding a big random file.'''
  273.         temp = tempfile.NamedTemporaryFile()
  274.         data = os.urandom(1048576)
  275.         temp.write(data)
  276.         temp.flush()
  277.         pr = ProblemReport()
  278.         pr['File'] = (temp.name,)
  279.         pr['Before'] = 'xtestx'
  280.         pr['ZAfter'] = 'ytesty'
  281.         io = StringIO.StringIO()
  282.         pr.write(io)
  283.         temp.close()
  284.         io.seek(0)
  285.         pr = ProblemReport()
  286.         pr.load(io)
  287.         self.assert_(pr['File'] == data)
  288.         self.assertEqual(pr['Before'], 'xtestx')
  289.         self.assertEqual(pr['ZAfter'], 'ytesty')
  290.         io2 = StringIO.StringIO()
  291.         pr.write(io2)
  292.         self.assertEqual(io.getvalue(), io2.getvalue())
  293.  
  294.     
  295.     def test_iter(self):
  296.         '''Test ProblemReport iteration.'''
  297.         pr = ProblemReport()
  298.         pr['foo'] = 'bar'
  299.         keys = []
  300.         for k in pr:
  301.             keys.append(k)
  302.         
  303.         keys.sort()
  304.         self.assertEqual(' '.join(keys), 'Date ProblemType foo')
  305.         []([](_[1]), 2)
  306.  
  307.     
  308.     def test_modify(self):
  309.         '''Test reading, modifying fields, and writing back.'''
  310.         report = 'ProblemType: Crash\nDate: now!\nFile: base64\n QlpoOTFBWSZTWc5ays4AAAdGAEEAMAAAECAAMM0AkR6fQsBSDhdyRThQkM5ays4=\nLong:\n xxx\n .\n yyy\nShort: Bar\n'
  311.         pr = ProblemReport()
  312.         pr.load(StringIO.StringIO(report))
  313.         self.assertEqual(pr['Long'], 'xxx\n.\nyyy')
  314.         io = StringIO.StringIO()
  315.         pr.write(io)
  316.         self.assertEqual(io.getvalue(), report)
  317.         pr['Short'] = 'aaa\nbbb'
  318.         pr['Long'] = '123'
  319.         io = StringIO.StringIO()
  320.         pr.write(io)
  321.         self.assertEqual(io.getvalue(), 'ProblemType: Crash\nDate: now!\nFile: base64\n QlpoOTFBWSZTWc5ays4AAAdGAEEAMAAAECAAMM0AkR6fQsBSDhdyRThQkM5ays4=\nLong: 123\nShort:\n aaa\n bbb\n')
  322.  
  323.  
  324. if __name__ == '__main__':
  325.     unittest.main()
  326.  
  327.