#============================================================================
#Name : outputer.py
#Part of : Helium
#Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
#All rights reserved.
#This component and the accompanying materials are made available
#under the terms of the License "Eclipse Public License v1.0"
#which accompanies this distribution, and is available
#at the URL "http://www.eclipse.org/legal/epl-v10.html".
#
#Initial Contributors:
#Nokia Corporation - initial contribution.
#
#Contributors:
#
#Description:
#===============================================================================
"""Port to python of the ISIS::Logger3::XML2HTML perl module
1.0.0 (13/12/2006)
- First version of the module."""
import codecs
import xml.dom.minidom
from helium.output.widgets import *
import urllib2
import amara
import re
import dataurl
class Configuration:
""" Class for isis Configuration """
def __init__(self, url):
url_file = urllib2.urlopen(url)#
data = url_file.read()
url_file.close()
self.__xml = amara.parse(data)
def getClass(self, type_, default = None):
"""get Class"""
return self._getValue(type_, "class", default)
def getImg(self, type_, default = None):
""" get Image"""
return self._getValue(type_, "img", default)
def getWidth(self, type_, default = None):
"""get Width"""
return self._getValue(type_, "width", default)
def getHeight(self, type_, default = None):
"""get height"""
return self._getValue(type_, "height", default)
def _getValue(self, type_, attr, default = None):
"""get value"""
r_attr = self.__xml.xml_xpath("/htmloutput/icons/icon[@type='%s']" % type_)
if len(r_attr) == 0:
if default == None:
raise Exception("Not found")
else:
return default
return r_attr[0][attr]
class XML2XHTML:
""" This class is used to generate an html file from the given xml """
def __init__(self, filename, url="http://fawww.europe.nokia.com/isis/isis_interface/configuration.xml", usedataurl=False):
self.__title = None
self.__config = Configuration(url)
self.__filename = filename
self.__srcdoc = xml.dom.minidom.parse(filename)
self.__srcdoc.normalize()
self.__usedataurl = usedataurl
# xhtml output
dom = xml.dom.minidom.getDOMImplementation()
doctype = dom.createDocumentType("html",
"-//W3C//DTD XHTML 1.0 Strict//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")
self.__doc = dom.createDocument(None, "html", doctype)
self.__xhtml = self.__doc.getElementsByTagName("html")[0]
self.__xhtml.setAttributeNS("", "xmlns", "http://www.w3.org/1999/xhtml")
self.__id = 0
self.__xhtml_summary = None
self.__tags = {}
self.__css = ["http://fawww.europe.nokia.com/isis/isis_interface/css/logger2.css"]
self.__javascript = ["http://fawww.europe.nokia.com/isis/isis_interface/javascript/expand2.js"]
self.__factory = {'__header' : XML2XHTML.forname('helium.output.widgets.Header'),
'__footer' : XML2XHTML.forname('helium.output.widgets.Footer'),
'__maincontent' : XML2XHTML.forname('helium.output.widgets.Box'),
'__summary' : XML2XHTML.forname('helium.output.widgets.Summary'),
'__print' : XML2XHTML.forname('helium.output.widgets.Text'),
'__printraw' : XML2XHTML.forname('helium.output.widgets.RawText'),
'__event' : XML2XHTML.forname('helium.output.widgets.Event')}
def _getId(self):
"""get ID"""
self.__id += 1
return self.__id
def addCSSLink(self, url):
"""add CSS Link"""
self.__css.append(url)
def addJScriptLink(self, url):
"""add Script Link"""
self.__javascript.append(url)
def _generateCSSLinks(self, container):
"""generate CSS Links"""
for link in self.__css:
l_link = self.__doc.createElementNS("", "link")
if self.__usedataurl:
l_link.setAttributeNS("", "href", dataurl.from_url(link))
else:
l_link.setAttributeNS("", "href", link)
l_link.setAttributeNS("", "rel", "stylesheet")
l_link.setAttributeNS("", "type", "text/css")
container.appendChild(l_link)
def _generateJScriptLink(self, container):
"""generate J Script Link"""
for link in self.__javascript:
l_link = self.__doc.createElementNS("", "script")
if self.__usedataurl:
l_link.setAttributeNS("", "src", dataurl.from_url(link))
else:
l_link.setAttributeNS("", "src", link)
l_link.setAttributeNS("", "type", "text/javascript")
l_link.appendChild(self.__doc.createTextNode(""))
container.appendChild(l_link)
def generate(self):
"""generate"""
root = self.__srcdoc.documentElement
if root.tagName != "__log":
raise Exception("Invalid document must be __log.")
for cust_out in root.getElementsByTagName("__customoutputer"):
self.__factory[cust_out.attributes['type'].value] = XML2XHTML.forname(cust_out.attributes['module'].value)
head = self.__doc.createElementNS("", "head")
title = self.__doc.createElementNS("", "title")
self.__title = self.__doc.createTextNode("")
title.appendChild(self.__title)
head.appendChild(title)
self._generateCSSLinks(head)
self._generateJScriptLink(head)
body = self.__doc.createElementNS("", "body")
self.__xhtml.appendChild(head)
self.__xhtml.appendChild(body)
for child in root.childNodes:
if child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "__header":
self._handleHeader(child, body)
elif child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "__summary":
self._handleSummary(child, body)
elif child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "__maincontent":
self._handleMainContent(child, body)
elif child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "build":
self._handleBuild(child, body)
elif child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "task" and child.attributes.has_key('type') and child.attributes['type'] == "maincontent":
self._handleMainContent(child, body)
footer = root.getElementsByTagName("__footer")[0]
f_foot = self.__factory["__footer"](self.__doc, body)
if footer.attributes.has_key("title"):
f_foot.setTitle(footer.attributes['title'].value)
if footer.attributes.has_key("subtitle"):
f_foot.setSubTitle(footer.attributes['subtitle'].value)
# Generate summary
self._createSummary()
def _handleHeader(self, node, container):
"""handle Header"""
header = self.__factory["__header"](self.__doc, container)
if node.attributes.has_key('title'):
self.__title.data = node.attributes['title'].value
header.setTitle(node.attributes['title'].value)
if node.attributes.has_key("subtitle"):
header.setSubTitle(node.attributes['subtitle'].value)
def _handleSummary(self, node, container):
"""handle Summary"""
box = self.__factory["__summary"](self.__doc, container)
if node.attributes.has_key('title'):
box.setTitle(node.attributes["title"].value)
for c_tag in node.getElementsByTagName("__elmt"):
box.addElement(c_tag.attributes['tag'].value, c_tag.attributes['val'].value)
self.__xhtml_summary = box
def _handleBuild(self, node, container):
"""handle Build"""
for child in node.childNodes:
if child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "task" and child.attributes.has_key('type') and child.attributes['type'].value == 'maincontent':
self._handleMainContent(child, container)
def _handleMainContent(self, node, container):
"""handle Main Content"""
box = self.__factory["__maincontent"](self.__doc, container)
if node.attributes.has_key("title"):
box.setTitle(node.attributes["title"].value)
if node.attributes.has_key("name"):
box.setTitle(node.attributes["name"].value)
for child in node.childNodes:
if child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "__event":
self._handleEvent(child, box.getDOMContainer())
elif child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "task" and child.attributes.has_key('type') and child.attributes['type'].value == 'event':
self._handleEvent(child, box.getDOMContainer())
elif child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "message":
self._handleMessage(child, box.getDOMContainer())
elif child.nodeType == xml.dom.Node.ELEMENT_NODE:
self._handlePrint(child, box.getDOMContainer())
def _handleEvent(self, node, container):
"""hnadle Event"""
tags = self.__tags
self.__tags = {}
event = self.__factory["__event"](self.__doc, container, self._getId())
if node.attributes.has_key('title'):
event.setTitle(node.attributes['title'].value)
elif node.attributes.has_key('name'):
event.setTitle(node.attributes['name'].value)
for child in node.childNodes:
if child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "__event":
self._handleEvent(child, event.getDOMContainer())
elif child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "task" and child.attributes.has_key('type') and child.attributes['type'].value == 'event':
self._handleEvent(child, event.getDOMContainer())
elif child.nodeType == xml.dom.Node.ELEMENT_NODE and child.tagName == "message":
self._handleMessage(child, event.getDOMContainer())
elif child.nodeType == xml.dom.Node.ELEMENT_NODE:
self._handlePrint(child, event.getDOMContainer())
keys = self.__tags.keys()
keys.sort()
for name in keys:
event.addStatistics(name.replace("__", ""), self.__tags[name])
self.__tags = self._mergeStatistics(tags, self.__tags)
def _handleMessage(self, node, container):
""" handle Message"""
if node.attributes['priority'].value == "printraw":
t_print = self.__factory["__printraw"](self.__doc, container)
for n_node in node.childNodes:
if n_node.nodeType == xml.dom.Node.CDATA_SECTION_NODE:
t_print.appendText(n_node.data)
else:
t_print = self.__factory["__print"](self.__doc, container)
for n_node in node.childNodes:
if n_node.nodeType == xml.dom.Node.CDATA_SECTION_NODE:
t_print.appendText(n_node.data)
if node.attributes['priority'].value != "print":
t_print.setIcon(self.__config.getClass(node.attributes['priority'].value, "icn_dft"))
if self.__tags.has_key(node.attributes['priority'].value):
self.__tags[node.attributes['priority'].value] += 1
else:
self.__tags[node.attributes['priority'].value] = 1
def _handlePrint(self, node, container):
"""handle print"""
if node.tagName == "__printraw":
t_print = self.__factory["__printraw"](self.__doc, container)
for n_node in node.childNodes:
if n_node.nodeType == xml.dom.Node.CDATA_SECTION_NODE or n_node.nodeType == xml.dom.Node.TEXT_NODE:
t_print.appendText(n_node.data)
else:
t_print = self.__factory["__print"](self.__doc, container)
for n_node in node.childNodes:
if n_node.nodeType == xml.dom.Node.CDATA_SECTION_NODE or n_node.nodeType == xml.dom.Node.TEXT_NODE:
t_print.appendText(n_node.data)
if node.tagName != "__print":
t_print.setIcon(self.__config.getClass(node.tagName, "icn_dft"))
if self.__tags.has_key(node.tagName):
self.__tags[node.tagName] += 1
else:
self.__tags[node.tagName] = 1
def _createSummary(self):
"""create Summary"""
# pylint: disable=E1101
if self.__xhtml_summary == None:
self.__xhtml_summary = Summary(self.__doc, self.__body)
self.__xhtml_summary.setTitle("Global Statistics")
keys = self.__tags.keys()
keys.sort()
for name in keys:
self.__xhtml_summary.addStatistics(name.replace("__", ""), self.__tags[name])
# pylint: enable-msg=E1101
def _mergeStatistics(self, tags, newTags):
"""merge Statistics"""
for name in newTags.keys():
if tags.has_key(name):
tags[name] += newTags[name]
else:
tags[name] = newTags[name]
return tags
def WriteToFile(self, filename):
"""write to file"""
file_object = open(filename, "w")
file_object.write(codecs.BOM_UTF8)
file_object.write(self.__doc.toprettyxml(encoding="utf-8"))
file_object.close()
@staticmethod
def forname(classname):
"""forname"""
result = re.match("^(?P<modname>(?:\w+\.?)*)\.(?P<classname>(\w+?))$", classname)
if result != None:
return getattr(__import__(result.groupdict()['modname'], [], [], result.groupdict()['classname']), result.groupdict()['classname'])
else:
raise Exception("Error retreiving module and classname for %s" % classname)