home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / checkbox / reports / xml_report.py < prev   
Encoding:
Python Source  |  2009-04-27  |  6.7 KB  |  192 lines

  1. #
  2. # This file is part of Checkbox.
  3. #
  4. # Copyright 2008 Canonical Ltd.
  5. #
  6. # Checkbox is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  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.
  15. #
  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/>.
  18. #
  19. import re
  20.  
  21. from xml.dom.minidom import Node
  22.  
  23. from checkbox.report import Report, ReportManager
  24.  
  25.  
  26. class XmlReportManager(ReportManager):
  27.  
  28.     def __init__(self, *args, **kwargs):
  29.         super(XmlReportManager, self).__init__(*args, **kwargs)
  30.         self.add(XmlReport())
  31.  
  32.  
  33. class XmlReport(Report):
  34.     """Report for basic data types."""
  35.  
  36.     def register_dumps(self):
  37.         for (dt, dh) in [(bool, self.dumps_bool),
  38.                          (int, self.dumps_int),
  39.                          (long, self.dumps_int),
  40.                          (float, self.dumps_float),
  41.                          (str, self.dumps_str),
  42.                          (unicode, self.dumps_unicode),
  43.                          (list, self.dumps_list),
  44.                          (tuple, self.dumps_list),
  45.                          (dict, self.dumps_dict),
  46.                          (type(None), self.dumps_none)]:
  47.             self._manager.handle_dumps(dt, dh)
  48.  
  49.     def register_loads(self):
  50.         for (lt, lh) in [("default", self.loads_default),
  51.                          ("bool", self.loads_bool),
  52.                          ("int", self.loads_int),
  53.                          ("long", self.loads_int),
  54.                          ("float", self.loads_float),
  55.                          ("str", self.loads_str),
  56.                          ("unicode", self.loads_str),
  57.                          ("list", self.loads_list),
  58.                          ("value", self.loads_value),
  59.                          ("property", self.loads_property),
  60.                          ("properties", self.loads_properties),
  61.                          (type(None), self.loads_none)]:
  62.             self._manager.handle_loads(lt, lh)
  63.  
  64.     def _dumps_text(self, obj, parent, type):
  65.         parent.setAttribute("type", type)
  66.         text_node = self._create_text_node(obj, parent)
  67.  
  68.     def dumps_bool(self, obj, parent):
  69.         obj = convert_bool(str(obj))
  70.         self._dumps_text(str(obj), parent, "bool")
  71.  
  72.     def dumps_int(self, obj, parent):
  73.         if obj >= 2**31:
  74.             self._dumps_text(str(obj), parent, "long")
  75.         else:
  76.             self._dumps_text(str(obj), parent, "int")
  77.  
  78.     def dumps_float(self, obj, parent):
  79.         self._dumps_text(str(obj), parent, "float")
  80.  
  81.     def dumps_str(self, obj, parent):
  82.         self._dumps_text(obj, parent, "str")
  83.  
  84.     def dumps_unicode(self, obj, parent):
  85.         self._dumps_text(obj, parent, "unicode")
  86.  
  87.     def dumps_list(self, obj, parent):
  88.         parent.setAttribute("type", "list")
  89.         for value in obj:
  90.             # HACK: lists are supposedly expressed as a property
  91.             element = self._create_element("value", parent)
  92.             self._manager.call_dumps(value, element)
  93.  
  94.     def dumps_dict(self, obj, parent):
  95.         for key in sorted(obj.keys()):
  96.             value = obj[key]
  97.             if self._manager.dumps_table.has_key(key):
  98.                 # Custom dumps handler
  99.                 element = self._create_element(key, parent)
  100.                 self._manager.dumps_table[key](value, element)
  101.             elif type(value) == dict:
  102.                 # <key type="">value</key>
  103.                 element = self._create_element(key, parent)
  104.                 self._manager.call_dumps(value, element)
  105.             else:
  106.                 # <property name="key" type="">value</property>
  107.                 property = self._create_element("property", parent)
  108.                 property.setAttribute("name", key)
  109.                 self._manager.call_dumps(value, property)
  110.  
  111.     def dumps_none(self, obj, parent):
  112.         self._create_element("none", parent)
  113.  
  114.     def loads_default(self, node):
  115.         default = {}
  116.         for child in (c for c in node.childNodes if c.nodeType != Node.TEXT_NODE):
  117.             if child.hasAttribute("name"):
  118.                 name = child.getAttribute("name")
  119.             else:
  120.                 name = child.localName
  121.             default[str(name)] = self._manager.call_loads(child)
  122.         return default
  123.  
  124.     def loads_bool(self, node):
  125.         return convert_bool(node.data.strip())
  126.  
  127.     def loads_int(self, node):
  128.         return int(node.data)
  129.  
  130.     def loads_float(self, node):
  131.         return float(node.data)
  132.  
  133.     def loads_str(self, node):
  134.         return str(node.data.strip())
  135.  
  136.     def loads_list(self, node):
  137.         nodes = []
  138.         for child in node.childNodes:
  139.             if child.nodeType != Node.TEXT_NODE:
  140.                 nodes.append(self._manager.call_loads(child))
  141.         return nodes
  142.  
  143.     def loads_value(self, node):
  144.         child = node.firstChild
  145.         return self.loads_str(child)
  146.  
  147.     def loads_property(self, node):
  148.         type = node.getAttribute("type")
  149.         if type == "list":
  150.             # HACK: see above in dumps_list
  151.             ret = []
  152.             for property in (p for p in node.childNodes if p.localName == "property"):
  153.                 value = self._manager.call_loads(property)
  154.                 if property.hasAttribute("name"):
  155.                     name = property.getAttribute("name")
  156.                     ret.append({name: value})
  157.                 else:
  158.                     ret.append(value)
  159.         elif not type:
  160.             # HACK: assuming no type means a dictionary
  161.             ret = {}
  162.             for property in (p for p in node.childNodes if p.localName == "property"):
  163.                 assert property.hasAttribute("name")
  164.                 name = property.getAttribute("name")
  165.                 value = self._manager.call_loads(property)
  166.                 ret[str(name)] = value
  167.         else:
  168.             child = node.firstChild
  169.             ret = self._manager.loads_table[type](child)
  170.         return ret
  171.  
  172.     def loads_properties(self, node):
  173.         properties = {}
  174.         for property in (p for p in node.childNodes if p.localName == "property"):
  175.             key = property.getAttribute("name")
  176.             value = self._manager.call_loads(property)
  177.             properties[str(key)] = value
  178.  
  179.         return properties
  180.  
  181.     def loads_none(self, node):
  182.         return None
  183.  
  184.  
  185. def convert_bool(string):
  186.     if re.match('^(yes|true|1)$', string, re.IGNORECASE):
  187.         return True
  188.     elif re.match('^(no|false|0)$', string, re.IGNORECASE):
  189.         return False
  190.     else:
  191.         raise Exception, "Invalid boolean type: %s" % string
  192.