Package helium :: Module outputer |
[hide private]
[frames] | no frames]

# Source Code for Module helium.outputer

      1  #============================================================================
      2  #Name        : outputer.py
      3  #Part of     : Helium
      4
      5  #Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
      6  #All rights reserved.
      7  #This component and the accompanying materials are made available
      8  #under the terms of the License "Eclipse Public License v1.0"
      9  #which accompanies this distribution, and is available
     10  #at the URL "http://www.eclipse.org/legal/epl-v10.html".
     11  #
     12  #Initial Contributors:
     13  #Nokia Corporation - initial contribution.
     14  #
     15  #Contributors:
     16  #
     17  #Description:
     18  #===============================================================================
     19
     20  ##
     21  # Outputer module
     22  # Description : Port to python of the ISIS::Logger3::XML2HTML perl module
     23  #
     24  # 1.0.0 (13/12/2006)
     25  #  - First version of the module.
     26  ##
     27  import codecs
     28  import xml.dom.minidom
     29  from helium.output.widgets import *
     30  import urllib2
     31  import amara
     32  import re
     33  import dataurl
     34
     35 -class Configuration:
     36 -    def __init__(self, url):
     37          f = urllib2.urlopen(url)#
     38          data = f.read()
     39          f.close()
     40          self.__xml = amara.parse(data)
     41
     42 -    def getClass(self, type, default = None):
     43          return self._getValue(type, "class", default)
     44
     45 -    def getImg(self, type, default = None):
     46          return self._getValue(type, "img", default)
     47
     48 -    def getWidth(self, type, default = None):
     49          return self._getValue(type, "width", default)
     50
     51 -    def getHeight(self, type, default = None):
     52          return self._getValue(type, "height", default)
     53
     54 -    def _getValue(self, type, attr, default = None):
     55          r = self.__xml.xml_xpath("/htmloutput/icons/icon[@type='%s']" % type)
     56          if len(r) == 0:
     57              if default == None:
     58                  raise Exception("Not found")
     59              else:
     60                  return default
     61          return r[0][attr]
     62
     63 -class XML2XHTML:
     64
     65 -    def __init__(self, filename, url="http://fawww.europe.nokia.com/isis/isis_interface/configuration.xml", usedataurl=False):
     66          self.__config = Configuration(url)
     67          self.__filename = filename
     68          self.__srcdoc = xml.dom.minidom.parse(filename)
     69          self.__srcdoc.normalize()
     70          self.__usedataurl = usedataurl
     71
     72          # xhtml output
     73          dom = xml.dom.minidom.getDOMImplementation()
     74          doctype = dom.createDocumentType("html",
     75                "-//W3C//DTD XHTML 1.0 Strict//EN",
     76                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")
     77          self.__doc = dom.createDocument(None, "html", doctype)
     78          self.__xhtml = self.__doc.getElementsByTagName("html")[0]
     79          self.__xhtml.setAttributeNS("", "xmlns", "http://www.w3.org/1999/xhtml")
     80          self.__id = 0
     81          self.__xhtml_summary = None
     82          self.__tags = {}
     83          self.__css = ["http://fawww.europe.nokia.com/isis/isis_interface/css/logger2.css"]
     84          self.__javascript = ["http://fawww.europe.nokia.com/isis/isis_interface/javascript/expand2.js"]
     85          self.__factory = {'__header' : XML2XHTML.forname('helium.output.widgets.Header'),
     86                            '__footer' : XML2XHTML.forname('helium.output.widgets.Footer'),
     87                            '__maincontent' : XML2XHTML.forname('helium.output.widgets.Box'),
     88                            '__summary' : XML2XHTML.forname('helium.output.widgets.Summary'),
     89                            '__print' : XML2XHTML.forname('helium.output.widgets.Text'),
     90                            '__printraw' : XML2XHTML.forname('helium.output.widgets.RawText'),
     91                            '__event' : XML2XHTML.forname('helium.output.widgets.Event')}
     92
     93 -    def _getId(self):
     94          self.__id += 1
     95          return self.__id
     96
     97 -    def addCSSLink(self, url):
     98          self.__css.append(url)
     99
    100 -    def addJScriptLink(self, url):
    101          self.__javascript.append(url)
    102
    103 -    def _generateCSSLinks(self, container):
    104          for link in self.__css:
    105              l = self.__doc.createElementNS("", "link")
    106              if self.__usedataurl:
    107                  l.setAttributeNS("", "href", dataurl.from_url(link))
    108              else:
    109                  l.setAttributeNS("", "href", link)
    110              l.setAttributeNS("", "rel", "stylesheet")
    111              l.setAttributeNS("", "type", "text/css")
    112              container.appendChild(l)
    113
    114 -    def _generateJScriptLink(self, container):
    115          for link in self.__javascript:
    116              l = self.__doc.createElementNS("", "script")
    117              if self.__usedataurl:
    118                  l.setAttributeNS("", "src", dataurl.from_url(link))
    119              else:
    120                  l.setAttributeNS("", "src", link)
    121              l.setAttributeNS("", "type", "text/javascript")
    122              l.appendChild(self.__doc.createTextNode(""))
    123              container.appendChild(l)
    124
    125
    126 -    def generate(self):
    127          root = self.__srcdoc.documentElement
    128          if root.tagName != "__log":
    129              raise Exception("Invalid document must be __log.")
    130
    131          for c in root.getElementsByTagName("__customoutputer"):
    132              self.__factory[c.attributes['type'].value] = XML2XHTML.forname(c.attributes['module'].value)
    133
    134
    135          head = self.__doc.createElementNS("", "head")
    136          title = self.__doc.createElementNS("", "title")
    137          self.__title = self.__doc.createTextNode("")
    138          title.appendChild(self.__title)
    139          head.appendChild(title)
    140
    141          self._generateCSSLinks(head)
    142          self._generateJScriptLink(head)
    143
    144          body = self.__doc.createElementNS("", "body")
    145          self.__xhtml.appendChild(head)
    146          self.__xhtml.appendChild(body)
    147
    148
    149          for c in root.childNodes:
    150              if c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "__header":
    151                  self._handleHeader(c, body)
    152              elif c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "__summary":
    153                  self._handleSummary(c, body)
    154              elif c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "__maincontent":
    155                  self._handleMainContent(c, body)
    156              elif c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "build":
    157                  self._handleBuild(c, body)
    158              elif c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "task" and c.attributes.has_key('type') and c.attributes['type'] == "maincontent":
    159                  self._handleMainContent(c, body)
    160
    161          try:
    162              footer = root.getElementsByTagName("__footer")[0]
    163              f = self.__factory["__footer"](self.__doc, body)
    164              if footer.attributes.has_key("title"):
    165                  f.setTitle(footer.attributes['title'].value)
    166              if footer.attributes.has_key("subtitle"):
    167                  f.setSubTitle(footer.attributes['subtitle'].value)
    168          except Exception:
    169              pass
    170          # Generate summary
    171          self._createSummary()
    172
    173 -    def _handleHeader(self, node, container):
    174          h = self.__factory["__header"](self.__doc, container)
    175          if node.attributes.has_key('title'):
    176              self.__title.data = node.attributes['title'].value
    177              h.setTitle(node.attributes['title'].value)
    178          if node.attributes.has_key("subtitle"):
    179              h.setSubTitle(node.attributes['subtitle'].value)
    180
    181 -    def _handleSummary(self, node, container):
    182          box = self.__factory["__summary"](self.__doc, container)
    183          if node.attributes.has_key('title'):
    184              box.setTitle(node.attributes["title"].value)
    185
    186          for c in node.getElementsByTagName("__elmt"):
    187              box.addElement(c.attributes['tag'].value, c.attributes['val'].value)
    188          self.__xhtml_summary = box
    189
    190 -    def _handleBuild(self, node, container):
    191          for c in node.childNodes:
    192              if c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "task" and c.attributes.has_key('type') and c.attributes['type'].value == 'maincontent':
    193                  self._handleMainContent(c, container)
    194
    195
    196 -    def _handleMainContent(self, node, container):
    197          box = self.__factory["__maincontent"](self.__doc, container)
    198          if node.attributes.has_key("title"):
    199              box.setTitle(node.attributes["title"].value)
    200          if node.attributes.has_key("name"):
    201              box.setTitle(node.attributes["name"].value)
    202          for c in node.childNodes:
    203              if c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "__event":
    204                  self._handleEvent(c, box.getDOMContainer())
    205              elif c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "task" and c.attributes.has_key('type') and c.attributes['type'].value == 'event':
    206                  self._handleEvent(c, box.getDOMContainer())
    207              elif c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "message":
    208                  self._handleMessage(c, box.getDOMContainer())
    209              elif c.nodeType == xml.dom.Node.ELEMENT_NODE:
    210                  self._handlePrint(c, box.getDOMContainer())
    211
    212 -    def _handleEvent(self, node, container):
    213          tags = self.__tags
    214          self.__tags = {}
    215          event = self.__factory["__event"](self.__doc, container, self._getId())
    216          if node.attributes.has_key('title'):
    217              event.setTitle(node.attributes['title'].value)
    218          elif node.attributes.has_key('name'):
    219              event.setTitle(node.attributes['name'].value)
    220          for c in node.childNodes:
    221              if c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "__event":
    222                  self._handleEvent(c, event.getDOMContainer())
    223              elif c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "task" and c.attributes.has_key('type') and c.attributes['type'].value == 'event':
    224                  self._handleEvent(c, event.getDOMContainer())
    225              elif c.nodeType == xml.dom.Node.ELEMENT_NODE and c.tagName == "message":
    226                  self._handleMessage(c, event.getDOMContainer())
    227              elif c.nodeType == xml.dom.Node.ELEMENT_NODE:
    228                  self._handlePrint(c, event.getDOMContainer())
    229
    230          keys = self.__tags.keys()
    231          keys.sort()
    232          for name in keys:
    233              event.addStatistics(name.replace("__", ""), self.__tags[name])
    234          self.__tags = self._mergeStatistics(tags, self.__tags)
    235
    236 -    def _handleMessage(self, node, container):
    237          if node.attributes['priority'].value == "printraw":
    238              t = self.__factory["__printraw"](self.__doc, container)
    239              for n in node.childNodes:
    240                  if n.nodeType == xml.dom.Node.CDATA_SECTION_NODE:
    241                      t.appendText(n.data)
    242          else:
    243              t = self.__factory["__print"](self.__doc, container)
    244              for n in node.childNodes:
    245                  if n.nodeType == xml.dom.Node.CDATA_SECTION_NODE:
    246                      t.appendText(n.data)
    247              if node.attributes['priority'].value != "print":
    248                  t.setIcon(self.__config.getClass(node.attributes['priority'].value, "icn_dft"))
    249                  if self.__tags.has_key(node.attributes['priority'].value):
    250                      self.__tags[node.attributes['priority'].value] += 1
    251                  else:
    252                      self.__tags[node.attributes['priority'].value] = 1
    253
    254 -    def _handlePrint(self, node, container):
    255          if node.tagName == "__printraw":
    256              t = self.__factory["__printraw"](self.__doc, container)
    257              for n in node.childNodes:
    258                  if n.nodeType == xml.dom.Node.CDATA_SECTION_NODE or n.nodeType == xml.dom.Node.TEXT_NODE:
    259                      t.appendText(n.data)
    260          else:
    261              t = self.__factory["__print"](self.__doc, container)
    262              for n in node.childNodes:
    263                  if n.nodeType == xml.dom.Node.CDATA_SECTION_NODE or n.nodeType == xml.dom.Node.TEXT_NODE:
    264                      t.appendText(n.data)
    265              if node.tagName != "__print":
    266                  t.setIcon(self.__config.getClass(node.tagName, "icn_dft"))
    267                  if self.__tags.has_key(node.tagName):
    268                      self.__tags[node.tagName] += 1
    269                  else:
    270                      self.__tags[node.tagName] = 1
    271
    272 -    def _createSummary(self):
    273          # pylint: disable-msg=E1101
    274          if self.__xhtml_summary == None:
    275              self.__xhtml_summary = Summary(self.__doc, self.__body)
    276              self.__xhtml_summary.setTitle("Global Statistics")
    277          keys = self.__tags.keys()
    278          keys.sort()
    279          for name in keys:
    280              self.__xhtml_summary.addStatistics(name.replace("__", ""), self.__tags[name])
    281
    282
    283 -    def _mergeStatistics(self, tags, newTags):
    284          for name in newTags.keys():
    285              if tags.has_key(name):
    286                  tags[name] += newTags[name]
    287              else:
    288                  tags[name] = newTags[name]
    289          return tags
    290
    291 -    def WriteToFile(self, filename):
    292          file_object = open(filename, "w")
    293          file_object.write(codecs.BOM_UTF8)
    294          file_object.write(self.__doc.toprettyxml(encoding="utf-8"))
    295          file_object.close()
    296
    297
    298      @staticmethod
    299 -    def forname(classname):
    300          r = re.match("^(?P<modname>(?:\w+\.?)*)\.(?P<classname>(\w+?))$", classname)
    301          if r != None:
    302              return getattr(__import__(r.groupdict()['modname'], [], [], r.groupdict()['classname']), r.groupdict()['classname'])
    303          else:
    304              raise Exception("Error retreiving module and classname for %s" % classname)
    305