diff --git a/bin/report/print_xml.py b/bin/report/print_xml.py index 03d22a70e18..e67108824b0 100644 --- a/bin/report/print_xml.py +++ b/bin/report/print_xml.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- ############################################################################## # -# OpenERP, Open Source Management Solution +# OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved # $Id$ # @@ -21,12 +21,11 @@ ############################################################################## import os,types -from xml.dom import minidom - +from lxml import etree import netsvc import tools import print_fnc - +import copy from osv.orm import browse_null, browse_record import pooler @@ -35,7 +34,7 @@ class InheritDict(dict): def __init__(self, parent=None): self.parent = parent - + def __getitem__(self, name): if name in self: return super(InheritDict, self).__getitem__(name) @@ -51,36 +50,32 @@ def tounicode(val): elif isinstance(val, unicode): unicode_val = val else: - unicode_val = unicode(val) + unicode_val = unicode(val) return unicode_val class document(object): def __init__(self, cr, uid, datas, func=False): # create a new document - self.cr = cr + self.cr = cr self.pool = pooler.get_pool(cr.dbname) - self.doc = minidom.Document() self.func = func or {} self.datas = datas self.uid = uid self.bin_datas = {} def node_attrs_get(self, node): - attrs = {} - nattr = node.attributes - for i in range(nattr.length): - attr = nattr.item(i) - attrs[attr.localName] = attr.nodeValue -# attrs[attr.name] = attr.nodeValue - return attrs - + if len(node.attrib): + return node.attrib + return {} + def get_value(self, browser, field_path): fields = field_path.split('.') if not len(fields): return '' - + value = browser + for f in fields: if isinstance(value, list): if len(value)==0: @@ -90,12 +85,12 @@ class document(object): return '' else: value = value[f] - + if isinstance(value, browse_null) or (type(value)==bool and not value): return '' - else: + else: return value - + def get_value2(self, browser, field_path): value = self.get_value(browser, field_path) if isinstance(value, browse_record): @@ -104,10 +99,10 @@ class document(object): return False else: return value - + def eval(self, record, expr): #TODO: support remote variables (eg address.title) in expr -# how to do that: parse the string, find dots, replace those dotted variables by temporary +# how to do that: parse the string, find dots, replace those dotted variables by temporary # "simple ones", fetch the value of those variables and add them (temporarily) to the _data # dictionary passed to eval @@ -120,13 +115,6 @@ class document(object): return eval(expr, {}, {'obj': record}) def parse_node(self, node, parent, browser, datas=None): - # node is the node of the xml template to be parsed - # parent = the parent node in the xml data tree we are creating - - if node.nodeType == node.ELEMENT_NODE: - - # convert the attributes of the node to a dictionary - attrs = self.node_attrs_get(node) if 'type' in attrs: if attrs['type']=='field': @@ -134,28 +122,26 @@ class document(object): #TODO: test this if value == '' and 'default' in attrs: value = attrs['default'] - el = self.doc.createElement(node.localName) - parent.appendChild(el) - el_txt = self.doc.createTextNode(tounicode(value)) - el.appendChild(el_txt) - + el = etree.Element(node.tag) + parent.append(el) + el.text = tounicode(value) #TODO: test this for key, value in attrs.iteritems(): if key not in ('type', 'name', 'default'): - el.setAttribute(key, value) + el.set(key, value) elif attrs['type']=='attachment': if isinstance(browser, list): model = browser[0]._table_name - else: + else: model = browser._table_name value = self.get_value(browser, attrs['name']) - + service = netsvc.LocalService("object_proxy") ids = service.execute(self.cr.dbname, self.uid, 'ir.attachment', 'search', [('res_model','=',model),('res_id','=',int(value))]) datas = service.execute(self.cr.dbname, self.uid, 'ir.attachment', 'read', ids) - + if len(datas): # if there are several, pick first datas = datas[0] @@ -169,37 +155,31 @@ class document(object): fp.write(dt) i = str(len(self.bin_datas)) self.bin_datas[i] = fp - - el = self.doc.createElement(node.localName) - parent.appendChild(el) - # node content is the length of the image - el_txt = self.doc.createTextNode(i) - el.appendChild(el_txt) - + el = etree.Element(node.tag) + el.text = i + parent.append(el) + elif attrs['type']=='data': #TODO: test this - el = self.doc.createElement(node.localName) - parent.appendChild(el) txt = self.datas.get('form', {}).get(attrs['name'], '') - el_txt = self.doc.createTextNode(tounicode(txt)) - el.appendChild(el_txt) + el = etree.Element(node.tag) + el.text = txt + parent.append(el) elif attrs['type']=='function': - el = self.doc.createElement(node.localName) - parent.appendChild(el) if attrs['name'] in self.func: txt = self.func[attrs['name']](node) else: txt = print_fnc.print_fnc(attrs['name'], node) - el_txt = self.doc.createTextNode(txt) - el.appendChild(el_txt) + el = etree.Element(node.tag) + el.text = txt + parent.append(el) elif attrs['type']=='eval': - el = self.doc.createElement(node.localName) - parent.appendChild(el) value = self.eval(browser, attrs['expr']) - el_txt = self.doc.createTextNode(str(value)) - el.appendChild(el_txt) + el = etree.Element(node.tag) + el.text = str(value) + parent.append(el) elif attrs['type']=='fields': fields = attrs['name'].split(',') @@ -216,26 +196,24 @@ class document(object): keys.reverse() v_list = [vals[k] for k in keys] - for v in v_list: - el = self.doc.createElement(node.localName) - parent.appendChild(el) - el_cld = node.firstChild - while el_cld: + for v in v_list: + el = etree.Element(node.tag) + parent.append(el) + for el_cld in node: self.parse_node(el_cld, el, v) - el_cld = el_cld.nextSibling elif attrs['type']=='call': if len(attrs['args']): -#TODO: test this +#TODO: test this # fetches the values of the variables which names where passed in the args attribute args = [self.eval(browser, arg) for arg in attrs['args'].split(',')] else: args = [] - + # get the object if attrs.has_key('model'): obj = self.pool.get(attrs['model']) - else: + else: if isinstance(browser, list): obj = browser[0]._table else: @@ -244,38 +222,28 @@ class document(object): # get the ids if attrs.has_key('ids'): ids = self.eval(browser, attrs['ids']) - else: + else: if isinstance(browser, list): - ids = [b.id for b in browser] + ids = [b.id for b in browser] else: ids = [browser.id] - + # call the method itself newdatas = getattr(obj, attrs['name'])(self.cr, self.uid, ids, *args) - + def parse_result_tree(node, parent, datas): - if node.nodeType == node.ELEMENT_NODE: - el = self.doc.createElement(node.localName) - parent.appendChild(el) + el = etree.Element(node.tag) + parent.append(el) atr = self.node_attrs_get(node) if 'value' in atr: if not isinstance(datas[atr['value']], (str, unicode)): - txt = self.doc.createTextNode(str(datas[atr['value']])) + txt = str(datas[atr['value']]) else: -# txt = self.doc.createTextNode(datas[atr['value']].decode('utf-8')) - txt = self.doc.createTextNode(datas[atr['value']]) - el.appendChild(txt) + txt = datas[atr['value']] + el.append(txt) else: - el_cld = node.firstChild - while el_cld: + for el_cld in node: parse_result_tree(el_cld, el, datas) - el_cld = el_cld.nextSibling - elif node.nodeType==node.TEXT_NODE: - el = self.doc.createTextNode(node.nodeValue) - parent.appendChild(el) - else: - pass - if not isinstance(newdatas, list): newdatas = [newdatas] for newdata in newdatas: @@ -283,50 +251,38 @@ class document(object): elif attrs['type']=='zoom': value = self.get_value(browser, attrs['name']) - + if value: if not isinstance(value, list): v_list = [value] else: v_list = value for v in v_list: - el = self.doc.createElement(node.localName) - parent.appendChild(el) - el_cld = node.firstChild - while el_cld: + el = etree.Element(node.tag) + parent.append(el) + for el_cld in node: self.parse_node(el_cld, el, v) - el_cld = el_cld.nextSibling else: # if there is no "type" attribute in the node, copy it to the xml data and parse its childs - el = self.doc.createElement(node.localName) - parent.appendChild(el) - el_cld = node.firstChild - while el_cld: - self.parse_node(el_cld, el, browser) - el_cld = el_cld.nextSibling - - elif node.nodeType==node.TEXT_NODE: - # if it's a text node, copy it to the xml data - el = self.doc.createTextNode(node.nodeValue) - parent.appendChild(el) - else: - pass + for el_cld in node: + self.parse_node(el_cld, parent, browser) def xml_get(self): - return self.doc.toxml('utf-8') + #return self.doc.toxml('utf-8') + return etree.tostring(self.doc,encoding="utf-8",xml_declaration=True) def parse_tree(self, ids, model, context=None): if not context: context={} browser = self.pool.get(model).browse(self.cr, self.uid, ids, context) - self.parse_node(self.dom.documentElement, self.doc, browser) - + self.parse_node(self.dom, self.doc, browser) + def parse_string(self, xml, ids, model, context=None): if not context: context={} # parses the xml template to memory - self.dom = minidom.parseString(xml) - + self.dom = etree.XML(xml) + # create the xml data from the xml template self.parse_tree(ids, model, context) @@ -334,9 +290,8 @@ class document(object): if not context: context={} # parses the xml template to memory - self.dom = minidom.parseString(tools.file_open(filename).read()) - - # create the xml data from the xml template + self.dom = etree.XML(tools.file_open(filename).read()) + self.doc = etree.Element(self.dom.tag) self.parse_tree(ids, model, context) def close(self): diff --git a/bin/report/printscreen/ps_form.py b/bin/report/printscreen/ps_form.py index a294383f90f..ac9c499dda3 100644 --- a/bin/report/printscreen/ps_form.py +++ b/bin/report/printscreen/ps_form.py @@ -26,7 +26,6 @@ import tools from report import render from lxml import etree -from xml.dom import minidom import libxml2 import libxslt @@ -38,24 +37,19 @@ class report_printscreen_list(report_int): def _parse_node(self, root_node): result = [] - for node in root_node.getchildren(): + for node in root_node: if node.tag == 'field': - #attrsa = node.attributes attrsa = node.attrib - print "typppppp",type(attrsa),dir(attrsa) attrs = {} if not attrsa is None: - for key,val in attrsa.items(): + for key,val in attrsa.items(): attrs[key] = val - #for i in range(attrsa.length): - # attrs[attrsa.item(i).localName] = attrsa.item(i).nodeValue result.append(attrs['name']) else: result.extend(self._parse_node(node)) return result def _parse_string(self, view): - #dom = minidom.parseString(view) dom = etree.XML(view) return self._parse_node(dom) @@ -85,16 +79,14 @@ class report_printscreen_list(report_int): pageSize=[297.0,210.0] impl = minidom.getDOMImplementation() - new_doc = impl.createDocument(None, "report", None) + new_doc = etree.Element("report") + config = etree.Element("config") # build header - config = new_doc.createElement("config") - def _append_node(name, text): - n = new_doc.createElement(name) - t = new_doc.createTextNode(text) - n.appendChild(t) - config.appendChild(n) + n = etree.Element(name) + n.text = text + config.append(n) _append_node('date', time.strftime('%d/%m/%Y')) _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize)) @@ -119,20 +111,17 @@ class report_printscreen_list(report_int): s = fields[fields_order[pos]].get('size', 56) / 28 + 1 l[pos] = strmax * s / t _append_node('tableSize', ','.join(map(str,l)) ) - new_doc.childNodes[0].appendChild(config) - header = new_doc.createElement("header") + new_doc.append(config) + header=etree.Element("header") for f in fields_order: - field = new_doc.createElement("field") - field_txt = new_doc.createTextNode(str(fields[f]['string'])) - field.appendChild(field_txt) - header.appendChild(field) - - new_doc.childNodes[0].appendChild(header) - - lines = new_doc.createElement("lines") + field = etree.Element("field") + field.text = fields[f]['string'] or '' + header.append(field) + new_doc.append(header) + lines = etree.Element("lines") for line in results: - node_line = new_doc.createElement("row") + node_line = etree.Element("row") for f in fields_order: if fields[f]['type']=='many2one' and line[f]: line[f] = line[f][1] @@ -141,16 +130,15 @@ class report_printscreen_list(report_int): if fields[f]['type'] == 'float': precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2 line[f]=round(line[f],precision) - col = new_doc.createElement("col") - col.setAttribute('tree','no') + col = etree.Element("col") + col.set('tree','no') if line[f] != None: - txt = new_doc.createTextNode(str(line[f] or '')) + col.text = tools.ustr(line[f] or '') else: - txt = new_doc.createTextNode('/') - col.appendChild(txt) - node_line.appendChild(col) - lines.appendChild(node_line) - new_doc.childNodes[0].appendChild(lines) + col.text = '/' + node_line.append(col) + lines.append(node_line) + new_doc.append(node_line) styledoc = libxml2.parseFile(os.path.join(tools.config['root_path'],'addons/base/report/custom_new.xsl')) style = libxslt.parseStylesheetDoc(styledoc)