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