[merge] 5.0-lxml-fixes into trunk

bzr revid: xmo@tinyerp.com-20091202092042-36gz0wkbu27aetvc
bzr revid: xmo@tinyerp.com-20091202093008-9uwo63c0bwdh8eaw
This commit is contained in:
Xavier Morel 2009-12-02 10:30:08 +01:00
commit 91c515382c
18 changed files with 218 additions and 331 deletions

View File

@ -3,3 +3,17 @@
.bzrignore .bzrignore
bin/addons/* bin/addons/*
bin/filestore* bin/filestore*
.Python
include
lib
bin/activate
bin/activate_this.py
bin/easy_install
bin/easy_install-2.6
bin/pip
bin/python
bin/python2.6
*.pyc
*.pyo
build/
bin/yolk

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- encoding: utf-8 -*-
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
@ -207,4 +207,3 @@ while True:
time.sleep(60) time.sleep(60)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1254,7 +1254,7 @@ class orm_template(object):
if pos == 'replace': if pos == 'replace':
parent = node.getparent() parent = node.getparent()
if parent is None: if parent is None:
src = copy.deepcopy(node2.getchildren()[0]) src = copy.deepcopy(node2[0])
else: else:
for child in node2: for child in node2:
node.addprevious(child) node.addprevious(child)

View File

@ -32,12 +32,10 @@ from osv.osv import except_osv
from osv.orm import browse_null from osv.orm import browse_null
from osv.orm import browse_record_list from osv.orm import browse_record_list
import pooler import pooler
from xml.dom import minidom
import libxml2
import libxslt
from pychart import * from pychart import *
import misc import misc
import cStringIO import cStringIO
from lxml import etree
class external_pdf(render.render): class external_pdf(render.render):
def __init__(self, pdf): def __init__(self, pdf):
@ -286,17 +284,13 @@ class report_custom(report_int):
if report['print_orientation']=='landscape': if report['print_orientation']=='landscape':
pageSize=[pageSize[1],pageSize[0]] pageSize=[pageSize[1],pageSize[0]]
impl = minidom.getDOMImplementation() new_doc = etree.Element('report')
new_doc = impl.createDocument(None, "report", None)
# build header config = etree.SubElement(new_doc, 'config')
config = new_doc.createElement("config")
def _append_node(name, text): def _append_node(name, text):
n = new_doc.createElement(name) n = etree.SubElement(config, name)
t = new_doc.createTextNode(text) t.text = text
n.appendChild(t)
config.appendChild(n)
_append_node('date', time.strftime('%d/%m/%Y')) _append_node('date', time.strftime('%d/%m/%Y'))
_append_node('PageFormat', '%s' % report['print_format']) _append_node('PageFormat', '%s' % report['print_format'])
@ -316,45 +310,33 @@ class report_custom(report_int):
_append_node('report-header', '%s' % (report['title'],)) _append_node('report-header', '%s' % (report['title'],))
_append_node('report-footer', '%s' % (report['footer'],)) _append_node('report-footer', '%s' % (report['footer'],))
new_doc.childNodes[0].appendChild(config) header = etree.SubElement(new_doc, 'header')
header = new_doc.createElement("header")
for f in fields: for f in fields:
field = new_doc.createElement("field") field = etree.SubElement(header, 'field')
field_txt = new_doc.createTextNode('%s' % (f['name'],)) field.text = f['name']
field.appendChild(field_txt)
header.appendChild(field)
new_doc.childNodes[0].appendChild(header)
lines = new_doc.createElement("lines") lines = etree.SubElement(new_doc, 'lines')
level.reverse() level.reverse()
for line in results: for line in results:
shift = level.pop() shift = level.pop()
node_line = new_doc.createElement("row") node_line = etree.SubElement(lines, 'row')
prefix = '+' prefix = '+'
for f in range(len(fields)): for f in range(len(fields)):
col = new_doc.createElement("col") col = etree.SubElement(node_line, 'col')
if f == 0: if f == 0:
col.setAttribute('para','yes') col.attrib.update(para='yes',
col.setAttribute('tree','yes') tree='yes',
col.setAttribute('space',str(3*shift)+'mm') space=str(3*shift)+'mm')
if line[f] != None: if line[f] != None:
txt = new_doc.createTextNode(prefix+str(line[f]) or '') col.text = prefix+str(line[f]) or ''
else: else:
txt = new_doc.createTextNode('/') col.text = '/'
col.appendChild(txt)
node_line.appendChild(col)
prefix = '' prefix = ''
lines.appendChild(node_line)
new_doc.childNodes[0].appendChild(lines)
styledoc = libxml2.parseFile(os.path.join(tools.config['root_path'],'addons/base/report/custom_new.xsl')) transform = etree.XSLT(
style = libxslt.parseStylesheetDoc(styledoc) etree.parse(os.path.join(tools.config['root_path'],
doc = libxml2.parseDoc(new_doc.toxml()) 'addons/base/report/custom_new.xsl')))
rml_obj = style.applyStylesheet(doc, None) rml = etree.tostring(transform(new_doc))
rml = style.saveResultToString(rml_obj)
self.obj = render.rml(rml) self.obj = render.rml(rml)
self.obj.render() self.obj.render()
@ -591,17 +573,12 @@ class report_custom(report_int):
if report['print_orientation']=='landscape': if report['print_orientation']=='landscape':
pageSize=[pageSize[1],pageSize[0]] pageSize=[pageSize[1],pageSize[0]]
impl = minidom.getDOMImplementation() new_doc = etree.Element('report')
new_doc = impl.createDocument(None, "report", None) config = etree.SubElement(new_doc, 'config')
# build header
config = new_doc.createElement("config")
def _append_node(name, text): def _append_node(name, text):
n = new_doc.createElement(name) n = etree.SubElement(config, name)
t = new_doc.createTextNode(text) n.text = text
n.appendChild(t)
config.appendChild(n)
_append_node('date', time.strftime('%d/%m/%Y')) _append_node('date', time.strftime('%d/%m/%Y'))
_append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize)) _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
@ -621,40 +598,25 @@ class report_custom(report_int):
_append_node('report-header', '%s' % (report['title'],)) _append_node('report-header', '%s' % (report['title'],))
_append_node('report-footer', '%s' % (report['footer'],)) _append_node('report-footer', '%s' % (report['footer'],))
new_doc.childNodes[0].appendChild(config) header = etree.SubElement(new_doc, 'header')
header = new_doc.createElement("header")
for f in fields: for f in fields:
field = new_doc.createElement("field") field = etree.SubElement(header, 'field')
field_txt = new_doc.createTextNode('%s' % (f['name'],)) field.text = f['name']
field.appendChild(field_txt)
header.appendChild(field)
new_doc.childNodes[0].appendChild(header)
lines = new_doc.createElement("lines") lines = etree.SubElement(new_doc, 'lines')
for line in results: for line in results:
node_line = new_doc.createElement("row") node_line = etree.SubElement(lines, 'row')
for f in range(len(fields)): for f in range(len(fields)):
col = new_doc.createElement("col") col = etree.SubElement(node_line, 'col', tree='no')
col.setAttribute('tree','no')
if line[f] != None: if line[f] != None:
txt = new_doc.createTextNode(str(line[f] or '')) col.text = line[f] or ''
else: else:
txt = new_doc.createTextNode('/') col.text = '/'
col.appendChild(txt)
node_line.appendChild(col)
lines.appendChild(node_line)
new_doc.childNodes[0].appendChild(lines)
# file('/tmp/terp.xml','w+').write(new_doc.toxml()) transform = etree.XSLT(
etree.parse(os.path.join(tools.config['root_path'],
styledoc = libxml2.parseFile(os.path.join(tools.config['root_path'],'addons/base/report/custom_new.xsl')) 'addons/base/report/custom_new.xsl')))
style = libxslt.parseStylesheetDoc(styledoc) rml = etree.tostring(transform(new_doc))
doc = libxml2.parseDoc(new_doc.toxml())
rml_obj = style.applyStylesheet(doc, None)
rml = style.saveResultToString(rml_obj)
self.obj = render.rml(rml) self.obj = render.rml(rml)
self.obj.render() self.obj.render()

View File

@ -22,8 +22,6 @@
import os import os
import re import re
import libxml2
import libxslt
from lxml import etree from lxml import etree
import netsvc import netsvc
import pooler import pooler
@ -146,48 +144,34 @@ class report_rml(report_int):
if not self.xsl: if not self.xsl:
return xml return xml
# load XSL (parse it to the XML level) stylesheet = etree.parse(tools.file_open(self.xsl))
styledoc = libxml2.parseDoc(tools.file_open(self.xsl).read()) xsl_path, _ = os.path.split(self.xsl)
xsl_path, tail = os.path.split(self.xsl) for import_child in stylesheet.findall('./import'):
for child in styledoc.children: if 'href' in import_child.attrib:
if child.name == 'import': imp_file = import_child.get('href')
if child.hasProp('href'): _, imp_file = tools.file_open(imp_file, subdir=xsl_path, pathinfo=True)
imp_file = child.prop('href') import_child.set('href', urllib.quote(str(imp_file)))
_x, imp_file = tools.file_open(imp_file, subdir=xsl_path, pathinfo=True)
child.setProp('href', urllib.quote(str(imp_file)))
#TODO: get all the translation in one query. That means we have to: #TODO: get all the translation in one query. That means we have to:
# * build a list of items to translate, # * build a list of items to translate,
# * issue the query to translate them, # * issue the query to translate them,
# * (re)build/update the stylesheet with the translated items # * (re)build/update the stylesheet with the translated items
# translate the XSL stylesheet def translate(doc, lang):
def look_down(child, lang): for node in doc.xpath('//*[@t]'):
while child is not None: translation = service.execute(
if (child.type == "element") and child.hasProp('t'): cr.dbname, uid, 'ir.translation', '_get_source',
#FIXME: use cursor self.name2, 'xsl', lang, node.text)
res = service.execute(cr.dbname, uid, 'ir.translation', if translation:
'_get_source', self.name2, 'xsl', lang, child.content) node.text = translation
if res:
child.setContent(res.encode('utf-8'))
look_down(child.children, lang)
child = child.next
if context.get('lang', False): if context.get('lang', False):
look_down(styledoc.children, context['lang']) translate(stylesheet, context['lang'])
# parse XSL transform = etree.XSLT(stylesheet)
style = libxslt.parseStylesheetDoc(styledoc) xml = etree.tostring(
# load XML (data) transform(etree.fromstring(xml)))
doc = libxml2.parseMemory(xml,len(xml))
# create RML (apply XSL to XML data)
result = style.applyStylesheet(doc, None)
# save result to string
xml = style.saveResultToString(result)
style.freeStylesheet()
doc.freeDoc()
result.freeDoc()
return xml return xml
def create_pdf(self, rml, localcontext = None, logo=None, title=None): def create_pdf(self, rml, localcontext = None, logo=None, title=None):

View File

@ -121,8 +121,7 @@ class document(object):
#TODO: test this #TODO: test this
if value == '' and 'default' in attrs: if value == '' and 'default' in attrs:
value = attrs['default'] value = attrs['default']
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
parent.append(el)
el.text = tounicode(value) el.text = tounicode(value)
#TODO: test this #TODO: test this
for key, value in attrs.iteritems(): for key, value in attrs.iteritems():
@ -154,31 +153,27 @@ class document(object):
fp.write(dt) fp.write(dt)
i = str(len(self.bin_datas)) i = str(len(self.bin_datas))
self.bin_datas[i] = fp self.bin_datas[i] = fp
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
el.text = i el.text = i
parent.append(el)
elif attrs['type']=='data': elif attrs['type']=='data':
#TODO: test this #TODO: test this
txt = self.datas.get('form', {}).get(attrs['name'], '') txt = self.datas.get('form', {}).get(attrs['name'], '')
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
el.text = txt el.text = txt
parent.append(el)
elif attrs['type']=='function': elif attrs['type']=='function':
if attrs['name'] in self.func: if attrs['name'] in self.func:
txt = self.func[attrs['name']](node) txt = self.func[attrs['name']](node)
else: else:
txt = print_fnc.print_fnc(attrs['name'], node) txt = print_fnc.print_fnc(attrs['name'], node)
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
el.text = txt el.text = txt
parent.append(el)
elif attrs['type']=='eval': elif attrs['type']=='eval':
value = self.eval(browser, attrs['expr']) value = self.eval(browser, attrs['expr'])
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
el.text = str(value) el.text = str(value)
parent.append(el)
elif attrs['type']=='fields': elif attrs['type']=='fields':
fields = attrs['name'].split(',') fields = attrs['name'].split(',')
@ -196,8 +191,7 @@ class document(object):
v_list = [vals[k] for k in keys] v_list = [vals[k] for k in keys]
for v in v_list: for v in v_list:
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
parent.append(el)
for el_cld in node: for el_cld in node:
self.parse_node(el_cld, el, v) self.parse_node(el_cld, el, v)
@ -231,8 +225,7 @@ class document(object):
def parse_result_tree(node, parent, datas): def parse_result_tree(node, parent, datas):
if not node.tag == etree.Comment: if not node.tag == etree.Comment:
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
parent.append(el)
atr = self.node_attrs_get(node) atr = self.node_attrs_get(node)
if 'value' in atr: if 'value' in atr:
if not isinstance(datas[atr['value']], (str, unicode)): if not isinstance(datas[atr['value']], (str, unicode)):
@ -256,8 +249,7 @@ class document(object):
else: else:
v_list = value v_list = value
for v in v_list: for v in v_list:
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
parent.append(el)
for el_cld in node: for el_cld in node:
self.parse_node(el_cld, el, v) self.parse_node(el_cld, el, v)
else: else:
@ -266,8 +258,7 @@ class document(object):
if node.tag == parent.tag: if node.tag == parent.tag:
el = parent el = parent
else: else:
el = etree.Element(node.tag) el = etree.SubElement(parent, node.tag)
parent.append(el)
for el_cld in node: for el_cld in node:
self.parse_node(el_cld,el, browser) self.parse_node(el_cld,el, browser)
def xml_get(self): def xml_get(self):

View File

@ -25,8 +25,6 @@ import tools
from report import render from report import render
from lxml import etree from lxml import etree
import libxml2
import libxslt
import time, os import time, os
@ -77,21 +75,18 @@ class report_printscreen_list(report_int):
def _create_table(self, uid, ids, fields, fields_order, results, context, title=''): def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
pageSize=[297.0,210.0] pageSize=[297.0,210.0]
impl = minidom.getDOMImplementation()
new_doc = etree.Element("report") new_doc = etree.Element("report")
config = etree.Element("config") config = etree.SubElement(new_doc, 'config')
# build header # build header
def _append_node(name, text): def _append_node(name, text):
n = etree.Element(name) n = etree.SubElement(config, name)
n.text = text n.text = text
config.append(n)
_append_node('date', time.strftime('%d/%m/%Y')) _append_node('date', time.strftime('%d/%m/%Y'))
_append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize)) _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
_append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,)) _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
_append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,)) _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
_append_node('report-header', title) _append_node('report-header', title)
l = [] l = []
@ -110,17 +105,15 @@ class report_printscreen_list(report_int):
s = fields[fields_order[pos]].get('size', 56) / 28 + 1 s = fields[fields_order[pos]].get('size', 56) / 28 + 1
l[pos] = strmax * s / t l[pos] = strmax * s / t
_append_node('tableSize', ','.join(map(str,l)) ) _append_node('tableSize', ','.join(map(str,l)) )
new_doc.append(config)
header=etree.Element("header")
header = etree.SubElement(new_doc, 'header')
for f in fields_order: for f in fields_order:
field = etree.Element("field") field = etree.SubElement(header, 'field')
field.text = fields[f]['string'] or '' field.text = fields[f]['string'] or ''
header.append(field)
new_doc.append(header) lines = etree.SubElement(new_doc, 'lines')
lines = etree.Element("lines")
for line in results: for line in results:
node_line = etree.Element("row") node_line = etree.SubElement(lines, 'row')
for f in fields_order: for f in fields_order:
if fields[f]['type']=='many2one' and line[f]: if fields[f]['type']=='many2one' and line[f]:
line[f] = line[f][1] line[f] = line[f][1]
@ -129,21 +122,17 @@ class report_printscreen_list(report_int):
if fields[f]['type'] == 'float': if fields[f]['type'] == 'float':
precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2 precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
line[f]=round(line[f],precision) line[f]=round(line[f],precision)
col = etree.Element("col") col = etree.SubElement(node_line, 'col', tree='no')
col.set('tree','no')
if line[f] != None: if line[f] != None:
col.text = tools.ustr(line[f] or '') col.text = tools.ustr(line[f] or '')
else: else:
col.text = '/' 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')) transform = etree.XSLT(
style = libxslt.parseStylesheetDoc(styledoc) etree.parse(os.path.join(tools.config['root_path'],
doc = libxml2.parseDoc(new_doc.toxml()) 'addons/base/report/custom_new.xsl')))
rml_obj = style.applyStylesheet(doc, None) rml = etree.tostring(transform(new_doc))
rml = style.saveResultToString(rml_obj)
self.obj = render.rml(rml, self.title) self.obj = render.rml(rml, self.title)
self.obj.render() self.obj.render()
return True return True

View File

@ -24,8 +24,6 @@ import pooler
import tools import tools
from lxml import etree from lxml import etree
from report import render from report import render
import libxml2
import libxslt
import locale import locale
import time, os import time, os
@ -37,14 +35,9 @@ class report_printscreen_list(report_int):
def _parse_node(self, root_node): def _parse_node(self, root_node):
result = [] result = []
for node in root_node.getchildren(): for node in root_node:
if node.tag == 'field': if node.tag == 'field':
attrsa = node.attrib result.append(node.get('name'))
attrs = {}
if not attrsa is None:
for key,val in attrsa.items():
attrs[key] = val
result.append(attrs['name'])
else: else:
result.extend(self._parse_node(node)) result.extend(self._parse_node(node))
return result return result
@ -90,30 +83,28 @@ class report_printscreen_list(report_int):
def _create_table(self, uid, ids, fields, fields_order, results, context, title=''): def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
pageSize=[297.0, 210.0] pageSize=[297.0, 210.0]
new_doc = etree.Element("report")
config = etree.Element("config")
# build header new_doc = etree.Element("report")
config = etree.SubElement(new_doc, 'config')
def _append_node(name, text): def _append_node(name, text):
n = etree.Element(name) n = etree.SubElement(config, name)
n.text = text n.text = text
config.append(n)
#_append_node('date', time.strftime('%d/%m/%Y')) #_append_node('date', time.strftime('%d/%m/%Y'))
_append_node('date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y')))) _append_node('date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))))
_append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize)) _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
_append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,)) _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
_append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,)) _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
_append_node('report-header', title) _append_node('report-header', title)
l = [] l = []
t = 0 t = 0
rowcount=0; rowcount=0;
strmax = (pageSize[0]-40) * 2.8346 strmax = (pageSize[0]-40) * 2.8346
temp = [] temp = []
count = len(fields_order) count = len(fields_order)
for i in range(0,count): for i in range(0, count):
temp.append(0) temp.append(0)
ince = -1; ince = -1;
@ -135,24 +126,20 @@ class report_printscreen_list(report_int):
l[pos] = strmax * s / t l[pos] = strmax * s / t
_append_node('tableSize', ','.join(map(str,l)) ) _append_node('tableSize', ','.join(map(str,l)) )
new_doc.append(config)
header=etree.Element("header")
header = etree.SubElement(new_doc, 'header')
for f in fields_order: for f in fields_order:
field = etree.Element("field") field = etree.SubElement(header, 'field')
field.text = tools.ustr(fields[f]['string'] or '') field.text = tools.ustr(fields[f]['string'] or '')
header.append(field)
new_doc.append(header) lines = etree.SubElement(new_doc, 'lines')
lines = etree.Element("lines")
tsum = [] tsum = []
count = len(fields_order) count = len(fields_order)
for i in range(0,count): for i in range(0,count):
tsum.append(0) tsum.append(0)
for line in results: for line in results:
node_line = etree.Element("row") node_line = etree.SubElement(lines, 'row')
count = -1 count = -1
for f in fields_order: for f in fields_order:
float_flag = 0 float_flag = 0
@ -194,28 +181,19 @@ class report_printscreen_list(report_int):
new_d1 = d1.strftime(format) new_d1 = d1.strftime(format)
line[f] = new_d1 line[f] = new_d1
col = etree.Element("col") col = etree.SubElement(node_line, 'col', para='yes', tree='no')
col.set('para','yes')
col.set('tree','no')
if line[f] != None: if line[f] != None:
col.text = tools.ustr(line[f] or '') col.text = tools.ustr(line[f] or '')
if float_flag: if float_flag:
col.set('tree','float') col.set('tree','float')
if temp[count] == 1: if temp[count] == 1:
tsum[count] = float(tsum[count]) + float(line[f]); tsum[count] = float(tsum[count]) + float(line[f]);
else: else:
col.text = '/' col.text = '/'
node_line.append(col)
lines.append(node_line)
node_line = etree.Element("row")
lines.append(node_line)
node_line = etree.SubElement(lines, 'row')
for f in range(0,count+1): for f in range(0,count+1):
col = etree.Element("col") col = etree.SubElement(node_line, 'col', para='yes', tree='no')
col.set('para','yes')
col.set('tree','no')
if tsum[f] != None: if tsum[f] != None:
if tsum[f] >= 0.01 : if tsum[f] >= 0.01 :
prec = '%.' + str(tools.config['price_accuracy']) + 'f' prec = '%.' + str(tools.config['price_accuracy']) + 'f'
@ -230,16 +208,12 @@ class report_printscreen_list(report_int):
txt ='Total' txt ='Total'
col.text = tools.ustr(txt or '') col.text = tools.ustr(txt or '')
node_line.append(col)
lines.append(node_line) transform = etree.XSLT(
etree.parse(os.path.join(tools.config['root_path'],
'addons/base/report/custom_new.xsl')))
rml = etree.tostring(transform(new_doc))
new_doc.append(lines)
styledoc = libxml2.parseFile(os.path.join(tools.config['root_path'],'addons/base/report/custom_new.xsl'))
style = libxslt.parseStylesheetDoc(styledoc)
doc = libxml2.parseDoc(etree.tostring(new_doc))
rml_obj = style.applyStylesheet(doc, None)
rml = style.saveResultToString(rml_obj)
self.obj = render.rml(rml, title=self.title) self.obj = render.rml(rml, title=self.title)
self.obj.render() self.obj.render()
return True return True

View File

@ -74,7 +74,7 @@ class html2html(object):
return self._node return self._node
def url_modify(self,root): def url_modify(self,root):
for n in root.getchildren(): for n in root:
if (n.text.find('<a ')>=0 or n.text.find('&lt;a')>=0) and n.text.find('href')>=0 and n.text.find('style')<=0 : if (n.text.find('<a ')>=0 or n.text.find('&lt;a')>=0) and n.text.find('href')>=0 and n.text.find('style')<=0 :
node = (n.tag=='span' and n.getparent().tag=='u') and n.getparent().getparent() or ((n.tag=='span') and n.getparent()) or n node = (n.tag=='span' and n.getparent().tag=='u') and n.getparent().getparent() or ((n.tag=='span') and n.getparent()) or n
style = node.get('color') and "style='color:%s; text-decoration: none;'"%node.get('color') or '' style = node.get('color') and "style='color:%s; text-decoration: none;'"%node.get('color') or ''

View File

@ -103,12 +103,10 @@ class _flowable(object):
process(node,new_node) process(node,new_node)
if new_node.get('colWidths',False): if new_node.get('colWidths',False):
sizes = map(lambda x: utils.unit_get(x), new_node.get('colWidths').split(',')) sizes = map(lambda x: utils.unit_get(x), new_node.get('colWidths').split(','))
tr = etree.Element('tr') tr = etree.SubElement(new_node, 'tr')
for s in sizes: for s in sizes:
td = etree.Element('td') etree.SubElement(tr, 'td', width=str(s))
td.set("width", str(s))
tr.append(td)
new_node.append(tr)
return etree.tostring(new_node) return etree.tostring(new_node)
def _tag_para(self, node): def _tag_para(self, node):
@ -297,7 +295,7 @@ class _rml_template(object):
posx = int(utils.unit_get(tmpl.get('x1'))) posx = int(utils.unit_get(tmpl.get('x1')))
frames[(posy,posx,tmpl.get('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.get('width'))) frames[(posy,posx,tmpl.get('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.get('width')))
for tmpl in pt.findall('pageGraphics'): for tmpl in pt.findall('pageGraphics'):
for n in tmpl.getchildren(): for n in tmpl:
if n.tag == 'image': if n.tag == 'image':
self.data = rc + utils._process_text(self, n.text) self.data = rc + utils._process_text(self, n.text)
if n.tag in self._tags: if n.tag in self._tags:

View File

@ -87,7 +87,7 @@ class _rml_styles(object,):
def _table_style_get(self, style_node): def _table_style_get(self, style_node):
styles = [] styles = []
for node in style_node.getchildren(): for node in style_node:
start = utils.tuple_int_get(node, 'start', (0,0) ) start = utils.tuple_int_get(node, 'start', (0,0) )
stop = utils.tuple_int_get(node, 'stop', (-1,-1) ) stop = utils.tuple_int_get(node, 'stop', (-1,-1) )
if node.tag=='blockValign': if node.tag=='blockValign':
@ -185,7 +185,7 @@ class _rml_doc(object):
def _textual_image(self, node): def _textual_image(self, node):
rc = '' rc = ''
for n in node.getchildren(): for n in node:
rc +=( etree.tostring(n) or '') + n.tail rc +=( etree.tostring(n) or '') + n.tail
return base64.decodestring(node.tostring()) return base64.decodestring(node.tostring())
@ -776,7 +776,8 @@ class _rml_template(object):
frame.lastFrame = True frame.lastFrame = True
frames.append( frame ) frames.append( frame )
try : try :
gr = pt.findall('pageGraphics') or pt.getchildren()[1].findall('pageGraphics') gr = pt.findall('pageGraphics')\
or pt[1].findall('pageGraphics')
except : except :
gr='' gr=''
if len(gr): if len(gr):

View File

@ -55,7 +55,7 @@ def xml2str(s):
def _child_get(node, self=None, tagname=None): def _child_get(node, self=None, tagname=None):
for n in node: for n in node:
if self and self.localcontext and n.get('rml_loop', False): if self and self.localcontext and n.get('rml_loop'):
oldctx = self.localcontext oldctx = self.localcontext
for ctx in eval(n.get('rml_loop'),{}, self.localcontext): for ctx in eval(n.get('rml_loop'),{}, self.localcontext):
@ -79,12 +79,12 @@ def _child_get(node, self=None, tagname=None):
yield n yield n
self.localcontext = oldctx self.localcontext = oldctx
continue continue
if self and self.localcontext and n.get('rml_except', False): if self and self.localcontext and n.get('rml_except'):
try: try:
eval(n.get('rml_except'), {}, self.localcontext) eval(n.get('rml_except'), {}, self.localcontext)
except: except:
continue continue
if self and self.localcontext and n.get('rml_tag', False): if self and self.localcontext and n.get('rml_tag'):
try: try:
(tag,attr) = eval(n.get('rml_tag'),{}, self.localcontext) (tag,attr) = eval(n.get('rml_tag'),{}, self.localcontext)
n2 = copy.deepcopy(n) n2 = copy.deepcopy(n)
@ -122,10 +122,7 @@ def _process_text(self, txt):
return result return result
def text_get(node): def text_get(node):
rc = '' return ''.join([tools.ustr(n.text) for n in node])
for node in node.getchildren():
rc = rc + tools.ustr(node.text)
return rc
units = [ units = [
(re.compile('^(-?[0-9\.]+)\s*in$'), reportlab.lib.units.inch), (re.compile('^(-?[0-9\.]+)\s*in$'), reportlab.lib.units.inch),
@ -155,8 +152,7 @@ def unit_get(size):
def tuple_int_get(node, attr_name, default=None): def tuple_int_get(node, attr_name, default=None):
if not node.get(attr_name): if not node.get(attr_name):
return default return default
res = [int(x) for x in node.get(attr_name).split(',')] return map(int, node.get(attr_name).split(','))
return res
def bool_get(value): def bool_get(value):
return (str(value)=="1") or (value.lower()=='yes') return (str(value)=="1") or (value.lower()=='yes')

View File

@ -302,7 +302,7 @@ class rml_parse(object):
rml_head = rml_head.replace('<image','<!--image') rml_head = rml_head.replace('<image','<!--image')
rml_head = rml_head.replace('</image>','</image-->') rml_head = rml_head.replace('</image>','</image-->')
head_dom = etree.XML(rml_head) head_dom = etree.XML(rml_head)
for tag in head_dom.getchildren(): for tag in head_dom:
found = rml_dom.find('.//'+tag.tag) found = rml_dom.find('.//'+tag.tag)
if found is not None and len(found): if found is not None and len(found):
if tag.get('position'): if tag.get('position'):
@ -466,13 +466,14 @@ class report_sxw(report_rml, preprocess.report):
for pe in elements: for pe in elements:
if pe.get(rml_parser.localcontext['name_space']["meta"]+"name"): if pe.get(rml_parser.localcontext['name_space']["meta"]+"name"):
if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 3": if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 3":
pe.getchildren()[0].text=data['id'] pe[0].text=data['id']
if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 4": if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 4":
pe.getchildren()[0].text=data['model'] pe[0].text=data['model']
meta = etree.tostring(rml_dom_meta) meta = etree.tostring(rml_dom_meta, encoding='utf-8',
xml_declaration=True)
rml_dom = etree.XML(rml) rml_dom = etree.XML(rml)
body = rml_dom.getchildren()[-1] body = rml_dom[-1]
elements = [] elements = []
key1 = rml_parser.localcontext['name_space']["text"]+"p" key1 = rml_parser.localcontext['name_space']["text"]+"p"
key2 = rml_parser.localcontext['name_space']["text"]+"drop-down" key2 = rml_parser.localcontext['name_space']["text"]+"drop-down"
@ -486,7 +487,7 @@ class report_sxw(report_rml, preprocess.report):
pp=de.getparent() pp=de.getparent()
if de.text or de.tail: if de.text or de.tail:
pe.text = de.text or de.tail pe.text = de.text or de.tail
for cnd in de.getchildren(): for cnd in de:
if cnd.text or cnd.tail: if cnd.text or cnd.tail:
if pe.text: if pe.text:
pe.text += cnd.text or cnd.tail pe.text += cnd.text or cnd.tail
@ -512,12 +513,11 @@ class report_sxw(report_rml, preprocess.report):
rml_dom = self.preprocess_rml(rml_dom,report_type) rml_dom = self.preprocess_rml(rml_dom,report_type)
create_doc = self.generators[report_type] create_doc = self.generators[report_type]
odt = etree.tostring(create_doc(rml_dom, rml_parser.localcontext)) odt = etree.tostring(create_doc(rml_dom, rml_parser.localcontext),
encoding='utf-8', xml_declaration=True)
sxw_z = zipfile.ZipFile(sxw_io, mode='a') sxw_z = zipfile.ZipFile(sxw_io, mode='a')
sxw_z.writestr('content.xml', "<?xml version='1.0' encoding='UTF-8'?>" + \ sxw_z.writestr('content.xml', odt)
odt) sxw_z.writestr('meta.xml', meta)
sxw_z.writestr('meta.xml', "<?xml version='1.0' encoding='UTF-8'?>" + \
meta)
if report_xml.header: if report_xml.header:
#Add corporate header/footer #Add corporate header/footer
@ -532,9 +532,9 @@ class report_sxw(report_rml, preprocess.report):
odt = create_doc(rml_dom,rml_parser.localcontext) odt = create_doc(rml_dom,rml_parser.localcontext)
if report_xml.header: if report_xml.header:
rml_parser._add_header(odt) rml_parser._add_header(odt)
odt = etree.tostring(odt) odt = etree.tostring(odt, encoding='utf-8',
sxw_z.writestr('styles.xml',"<?xml version='1.0' encoding='UTF-8'?>" + \ xml_declaration=True)
odt) sxw_z.writestr('styles.xml', odt)
sxw_z.close() sxw_z.close()
final_op = sxw_io.getvalue() final_op = sxw_io.getvalue()
sxw_io.close() sxw_io.close()

View File

@ -211,7 +211,8 @@ class configmanager(object):
else: else:
rcfilepath = os.path.expanduser('~/.openerp_serverrc') rcfilepath = os.path.expanduser('~/.openerp_serverrc')
self.rcfile = fname or opt.config or os.environ.get('OPENERP_SERVER') or rcfilepath self.rcfile = os.path.abspath(
fname or opt.config or os.environ.get('OPENERP_SERVER') or rcfilepath)
self.load() self.load()

View File

@ -35,12 +35,6 @@ from config import config
import logging import logging
import sys import sys
try:
from lxml import etree
except:
sys.stderr.write("ERROR: pythonic binding for the libxml2 and libxslt libraries is missing\n")
sys.stderr.write("ERROR: Try to install python-lxml package\n")
sys.exit(2)
import pickle import pickle
@ -63,17 +57,16 @@ def _eval_xml(self,node, pool, cr, uid, idref, context=None):
if context is None: if context is None:
context = {} context = {}
if node.tag in ('field','value'): if node.tag in ('field','value'):
t = node.get('type','') or 'char' t = node.get('type','char')
f_model = node.get("model", '').encode('ascii') f_model = node.get('model', '').encode('ascii')
if len(node.get('search','')): if node.get('search'):
f_search = node.get("search",'').encode('utf-8') f_search = node.get("search",'').encode('utf-8')
f_use = node.get("use",'').encode('ascii') f_use = node.get("use",'id').encode('ascii')
f_name = node.get("name",'').encode('utf-8') f_name = node.get("name",'').encode('utf-8')
if len(f_use)==0:
f_use = "id"
q = eval(f_search, idref) q = eval(f_search, idref)
ids = pool.get(f_model).search(cr, uid, q) ids = pool.get(f_model).search(cr, uid, q)
if f_use<>'id': if f_use != 'id':
ids = map(lambda x: x[f_use], pool.get(f_model).read(cr, uid, ids, [f_use])) ids = map(lambda x: x[f_use], pool.get(f_model).read(cr, uid, ids, [f_use]))
_cols = pool.get(f_model)._columns _cols = pool.get(f_model)._columns
if (f_name in _cols) and _cols[f_name]._type=='many2many': if (f_name in _cols) and _cols[f_name]._type=='many2many':
@ -85,7 +78,7 @@ def _eval_xml(self,node, pool, cr, uid, idref, context=None):
f_val = f_val[0] f_val = f_val[0]
return f_val return f_val
a_eval = node.get('eval','') a_eval = node.get('eval','')
if len(a_eval): if a_eval:
import time import time
from mx import DateTime from mx import DateTime
idref2 = idref.copy() idref2 = idref.copy()
@ -118,52 +111,53 @@ def _eval_xml(self,node, pool, cr, uid, idref, context=None):
if not id in idref: if not id in idref:
idref[id]=self.id_get(cr, False, id) idref[id]=self.id_get(cr, False, id)
return s % idref return s % idref
txt = '<?xml version="1.0"?>\n'+_process("".join([etree.tostring(i).encode("utf8") for i in node.getchildren()]), idref) return '<?xml version="1.0"?>\n'\
return txt +_process("".join([etree.tostring(n, encoding='utf-8')
for n in node]),
idref)
if t in ('char', 'int', 'float'): if t in ('char', 'int', 'float'):
d = node.text d = node.text
if t == 'int': if t == 'int':
d = d.strip() d = d.strip()
if d=='None': if d == 'None':
return None return None
else: else:
d=int(d.strip()) return int(d.strip())
elif t=='float': elif t == 'float':
d=float(d.strip()) return float(d.strip())
return d return d
elif t in ('list','tuple'): elif t in ('list','tuple'):
res=[] res=[]
for n in [i for i in node.getchildren() if (i.tag=='value')]: for n in node.findall('./value'):
res.append(_eval_xml(self,n,pool,cr,uid,idref)) res.append(_eval_xml(self,n,pool,cr,uid,idref))
if t=='tuple': if t=='tuple':
return tuple(res) return tuple(res)
return res return res
elif node.tag == "getitem": elif node.tag == "getitem":
for n in [i for i in node.getchildren()]: for n in node:
res=_eval_xml(self,n,pool,cr,uid,idref) res=_eval_xml(self,n,pool,cr,uid,idref)
if not res: if not res:
raise LookupError raise LookupError
elif node.get('type','') in ("int", "list"): elif node.get('type') in ("int", "list"):
return res[int(node.get('index',''))] return res[int(node.get('index'))]
else: else:
return res[node.get('index','').encode("utf8")] return res[node.get('index','').encode("utf8")]
elif node.tag == "function": elif node.tag == "function":
args = [] args = []
a_eval = node.get('eval','') a_eval = node.get('eval','')
if len(a_eval): if a_eval:
idref['ref'] = lambda x: self.id_get(cr, False, x) idref['ref'] = lambda x: self.id_get(cr, False, x)
args = eval(a_eval, idref) args = eval(a_eval, idref)
for n in [i for i in node.getchildren()]: for n in node:
return_val = _eval_xml(self,n, pool, cr, uid, idref, context) return_val = _eval_xml(self,n, pool, cr, uid, idref, context)
if return_val != None: if return_val is not None:
args.append(return_val) args.append(return_val)
model = pool.get(node.get('model','')) model = pool.get(node.get('model',''))
method = node.get('name','') method = node.get('name','')
res = getattr(model, method)(cr, uid, *args) res = getattr(model, method)(cr, uid, *args)
return res return res
elif node.tag == "test": elif node.tag == "test":
d = node.text return node.text
return d
escape_re = re.compile(r'(?<!\\)/') escape_re = re.compile(r'(?<!\\)/')
def escape(x): def escape(x):
@ -220,14 +214,14 @@ class xml_import(object):
context = {} context = {}
node_context = node.get("context",'').encode('utf8') node_context = node.get("context",'').encode('utf8')
if len(node_context): if node_context:
context.update(eval(node_context, eval_dict)) context.update(eval(node_context, eval_dict))
return context return context
def get_uid(self, cr, uid, data_node, node): def get_uid(self, cr, uid, data_node, node):
node_uid = node.get('uid','') or (len(data_node) and data_node.get('uid','')) node_uid = node.get('uid','') or (len(data_node) and data_node.get('uid',''))
if len(node_uid): if node_uid:
return self.id_get(cr, None, node_uid) return self.id_get(cr, None, node_uid)
return uid return uid
@ -250,18 +244,17 @@ form: module.record_id""" % (xml_id,)
d_search = rec.get("search",'') d_search = rec.get("search",'')
d_id = rec.get("id",'') d_id = rec.get("id",'')
ids = [] ids = []
if len(d_search): if d_search:
ids = self.pool.get(d_model).search(cr,self.uid,eval(d_search)) ids = self.pool.get(d_model).search(cr,self.uid,eval(d_search))
if len(d_id): if d_id:
try: try:
ids.append(self.id_get(cr, d_model, d_id)) ids.append(self.id_get(cr, d_model, d_id))
except: except:
# d_id cannot be found. doesn't matter in this case # d_id cannot be found. doesn't matter in this case
pass pass
if len(ids): if ids:
self.pool.get(d_model).unlink(cr, self.uid, ids) self.pool.get(d_model).unlink(cr, self.uid, ids)
self.pool.get('ir.model.data')._unlink(cr, self.uid, d_model, ids, direct=True) self.pool.get('ir.model.data')._unlink(cr, self.uid, d_model, ids, direct=True)
return False
def _tag_report(self, cr, rec, data_node=None): def _tag_report(self, cr, rec, data_node=None):
res = {} res = {}
@ -270,20 +263,19 @@ form: module.record_id""" % (xml_id,)
assert res[dest], "Attribute %s of report is empty !" % (f,) assert res[dest], "Attribute %s of report is empty !" % (f,)
for field,dest in (('rml','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment'),('attachment_use','attachment_use')): for field,dest in (('rml','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment'),('attachment_use','attachment_use')):
if rec.get(field): if rec.get(field):
res[dest] = rec.get(field,'').encode('utf8') res[dest] = rec.get(field).encode('utf8')
if rec.get('auto'): if rec.get('auto'):
res['auto'] = eval(rec.get('auto','')) res['auto'] = eval(rec.get('auto'))
if rec.get('sxw'): if rec.get('sxw'):
sxw_content = misc.file_open(rec.get('sxw','')).read() sxw_content = misc.file_open(rec.get('sxw')).read()
res['report_sxw_content'] = sxw_content res['report_sxw_content'] = sxw_content
if rec.get('header'): if rec.get('header'):
res['header'] = eval(rec.get('header','')) res['header'] = eval(rec.get('header'))
if rec.get('report_type'): if rec.get('report_type'):
res['report_type'] = rec.get('report_type','') res['report_type'] = rec.get('report_type')
res['multi'] = rec.get('multi','') and eval(rec.get('multi',''))
xml_id = rec.get('id','').encode('utf8')
res['multi'] = rec.get('multi') and eval(rec.get('multi'))
xml_id = rec.get('id','').encode('utf8')
self._test_xml_id(xml_id) self._test_xml_id(xml_id)
if rec.get('groups'): if rec.get('groups'):
@ -303,10 +295,10 @@ form: module.record_id""" % (xml_id,)
self.idref[xml_id] = int(id) self.idref[xml_id] = int(id)
if not rec.get('menu') or eval(rec.get('menu','')): if not rec.get('menu') or eval(rec.get('menu','')):
keyword = str(rec.get('keyword','') or 'client_print_multi') keyword = str(rec.get('keyword', 'client_print_multi'))
keys = [('action',keyword),('res_model',res['model'])] keys = [('action',keyword),('res_model',res['model'])]
value = 'ir.actions.report.xml,'+str(id) value = 'ir.actions.report.xml,'+str(id)
replace = rec.get("replace",'') or True replace = rec.get('replace', True)
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, res['name'], [res['model']], value, replace=replace, isobject=True, xml_id=xml_id) self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, res['name'], [res['model']], value, replace=replace, isobject=True, xml_id=xml_id)
return False return False
@ -316,7 +308,7 @@ form: module.record_id""" % (xml_id,)
context = self.get_context(data_node, rec, {'ref': _ref(self, cr)}) context = self.get_context(data_node, rec, {'ref': _ref(self, cr)})
uid = self.get_uid(cr, self.uid, data_node, rec) uid = self.get_uid(cr, self.uid, data_node, rec)
_eval_xml(self,rec, self.pool, cr, uid, self.idref, context=context) _eval_xml(self,rec, self.pool, cr, uid, self.idref, context=context)
return False return
def _tag_wizard(self, cr, rec, data_node=None): def _tag_wizard(self, cr, rec, data_node=None):
string = rec.get("string",'').encode('utf8') string = rec.get("string",'').encode('utf8')
@ -349,7 +341,6 @@ form: module.record_id""" % (xml_id,)
value = 'ir.actions.wizard,'+str(id) value = 'ir.actions.wizard,'+str(id)
replace = rec.get("replace",'') or True replace = rec.get("replace",'') or True
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id) self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id)
return False
def _tag_url(self, cr, rec, data_node=None): def _tag_url(self, cr, rec, data_node=None):
url = rec.get("string",'').encode('utf8') url = rec.get("string",'').encode('utf8')
@ -369,7 +360,6 @@ form: module.record_id""" % (xml_id,)
value = 'ir.actions.url,'+str(id) value = 'ir.actions.url,'+str(id)
replace = rec.get("replace",'') or True replace = rec.get("replace",'') or True
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=xml_id) self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, ["ir.actions.url"], value, replace=replace, isobject=True, xml_id=xml_id)
return False
def _tag_act_window(self, cr, rec, data_node=None): def _tag_act_window(self, cr, rec, data_node=None):
name = rec.get('name','').encode('utf-8') name = rec.get('name','').encode('utf-8')
@ -438,38 +428,37 @@ form: module.record_id""" % (xml_id,)
replace = rec.get('replace','') or True replace = rec.get('replace','') or True
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, xml_id, [src_model], value, replace=replace, isobject=True, xml_id=xml_id) self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, xml_id, [src_model], value, replace=replace, isobject=True, xml_id=xml_id)
# TODO add remove ir.model.data # TODO add remove ir.model.data
return False
def _tag_ir_set(self, cr, rec, data_node=None): def _tag_ir_set(self, cr, rec, data_node=None):
if not self.mode=='init': if self.mode != 'init':
return False return
res = {} res = {}
for field in [i for i in rec.getchildren() if (i.tag=="field")]: for field in rec.findall('./field'):
f_name = field.get("name",'').encode('utf-8') f_name = field.get("name",'').encode('utf-8')
f_val = _eval_xml(self,field,self.pool, cr, self.uid, self.idref) f_val = _eval_xml(self,field,self.pool, cr, self.uid, self.idref)
res[f_name] = f_val res[f_name] = f_val
self.pool.get('ir.model.data').ir_set(cr, self.uid, res['key'], res['key2'], res['name'], res['models'], res['value'], replace=res.get('replace',True), isobject=res.get('isobject', False), meta=res.get('meta',None)) self.pool.get('ir.model.data').ir_set(cr, self.uid, res['key'], res['key2'], res['name'], res['models'], res['value'], replace=res.get('replace',True), isobject=res.get('isobject', False), meta=res.get('meta',None))
return False
def _tag_workflow(self, cr, rec, data_node=None): def _tag_workflow(self, cr, rec, data_node=None):
if self.isnoupdate(data_node) and self.mode != 'init': if self.isnoupdate(data_node) and self.mode != 'init':
return return
model = str(rec.get('model','')) model = str(rec.get('model',''))
w_ref = rec.get('ref','') w_ref = rec.get('ref','')
if len(w_ref): if w_ref:
id = self.id_get(cr, model, w_ref) id = self.id_get(cr, model, w_ref)
else: else:
assert rec.getchildren(), 'You must define a child node if you dont give a ref' number_children = len(rec)
element_childs = [i for i in rec.getchildren()] assert number_children > 0,\
assert len(element_childs) == 1, 'Only one child node is accepted (%d given)' % len(rec.getchildren()) 'You must define a child node if you dont give a ref'
id = _eval_xml(self, element_childs[0], self.pool, cr, self.uid, self.idref) assert number_children == 1,\
'Only one child node is accepted (%d given)' % number_children
id = _eval_xml(self, rec[0], self.pool, cr, self.uid, self.idref)
uid = self.get_uid(cr, self.uid, data_node, rec) uid = self.get_uid(cr, self.uid, data_node, rec)
wf_service = netsvc.LocalService("workflow") wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, model, wf_service.trg_validate(uid, model,
id, id,
str(rec.get('action','')), cr) str(rec.get('action','')), cr)
return False
# #
# Support two types of notation: # Support two types of notation:
@ -509,7 +498,7 @@ form: module.record_id""" % (xml_id,)
menu_parent_id = self.id_get(cr, 'ir.ui.menu', rec.get('parent','')) menu_parent_id = self.id_get(cr, 'ir.ui.menu', rec.get('parent',''))
values = {'parent_id': menu_parent_id} values = {'parent_id': menu_parent_id}
if rec.get('name'): if rec.get('name'):
values['name'] = rec.get('name','') values['name'] = rec.get('name')
try: try:
res = [ self.id_get(cr, 'ir.ui.menu', rec.get('id','')) ] res = [ self.id_get(cr, 'ir.ui.menu', rec.get('id','')) ]
except: except:
@ -557,9 +546,10 @@ form: module.record_id""" % (xml_id,)
if (not values.get('name', False)) and resw: if (not values.get('name', False)) and resw:
values['name'] = resw[0] values['name'] = resw[0]
if rec.get('sequence'): if rec.get('sequence'):
values['sequence'] = int(rec.get('sequence','')) values['sequence'] = int(rec.get('sequence'))
if rec.get('icon'): if rec.get('icon'):
values['icon'] = str(rec.get('icon','')) values['icon'] = str(rec.get('icon'))
if rec.get('groups'): if rec.get('groups'):
g_names = rec.get('groups','').split(',') g_names = rec.get('groups','').split(',')
groups_value = [] groups_value = []
@ -581,7 +571,7 @@ form: module.record_id""" % (xml_id,)
self.idref[rec_id] = int(pid) self.idref[rec_id] = int(pid)
if rec.get('action') and pid: if rec.get('action') and pid:
a_action = rec.get('action','').encode('utf8') a_action = rec.get('action').encode('utf8')
a_type = rec.get('type','').encode('utf8') or 'act_window' a_type = rec.get('type','').encode('utf8') or 'act_window'
a_id = self.id_get(cr, 'ir.actions.%s' % a_type, a_action) a_id = self.id_get(cr, 'ir.actions.%s' % a_type, a_action)
action = "ir.actions.%s,%d" % (a_type, a_id) action = "ir.actions.%s,%d" % (a_type, a_id)
@ -601,7 +591,7 @@ form: module.record_id""" % (xml_id,)
rec_id = rec.get("id",'').encode('ascii') rec_id = rec.get("id",'').encode('ascii')
self._test_xml_id(rec_id) self._test_xml_id(rec_id)
rec_src = rec.get("search",'').encode('utf8') rec_src = rec.get("search",'').encode('utf8')
rec_src_count = rec.get("count",'') rec_src_count = rec.get("count")
severity = rec.get("severity",'').encode('ascii') or netsvc.LOG_ERROR severity = rec.get("severity",'').encode('ascii') or netsvc.LOG_ERROR
rec_string = rec.get("string",'').encode('utf8') or 'unknown' rec_string = rec.get("string",'').encode('utf8') or 'unknown'
@ -610,12 +600,12 @@ form: module.record_id""" % (xml_id,)
eval_dict = {'ref': _ref(self, cr)} eval_dict = {'ref': _ref(self, cr)}
context = self.get_context(data_node, rec, eval_dict) context = self.get_context(data_node, rec, eval_dict)
uid = self.get_uid(cr, self.uid, data_node, rec) uid = self.get_uid(cr, self.uid, data_node, rec)
if len(rec_id): if rec_id:
ids = [self.id_get(cr, rec_model, rec_id)] ids = [self.id_get(cr, rec_model, rec_id)]
elif len(rec_src): elif rec_src:
q = eval(rec_src, eval_dict) q = eval(rec_src, eval_dict)
ids = self.pool.get(rec_model).search(cr, uid, q, context=context) ids = self.pool.get(rec_model).search(cr, uid, q, context=context)
if len(rec_src_count): if rec_src_count:
count = int(rec_src_count) count = int(rec_src_count)
if len(ids) != count: if len(ids) != count:
self.assert_report.record_assertion(False, severity) self.assert_report.record_assertion(False, severity)
@ -631,8 +621,8 @@ form: module.record_id""" % (xml_id,)
raise Exception('Severe assertion failure') raise Exception('Severe assertion failure')
return return
assert ids != None, 'You must give either an id or a search criteria' assert ids is not None,\
'You must give either an id or a search criteria'
ref = _ref(self, cr) ref = _ref(self, cr)
for id in ids: for id in ids:
brrec = model.browse(cr, uid, id, context) brrec = model.browse(cr, uid, id, context)
@ -645,7 +635,7 @@ form: module.record_id""" % (xml_id,)
globals['floatEqual'] = self._assert_equals globals['floatEqual'] = self._assert_equals
globals['ref'] = ref globals['ref'] = ref
globals['_ref'] = ref globals['_ref'] = ref
for test in [i for i in rec.getchildren() if (i.tag=="test")]: for test in rec.findall('./test'):
f_expr = test.get("expr",'').encode('utf-8') f_expr = test.get("expr",'').encode('utf-8')
expected_value = _eval_xml(self, test, self.pool, cr, uid, self.idref, context=context) or True expected_value = _eval_xml(self, test, self.pool, cr, uid, self.idref, context=context) or True
expression_value = eval(f_expr, globals) expression_value = eval(f_expr, globals)
@ -700,7 +690,7 @@ form: module.record_id""" % (xml_id,)
# otherwise it is skipped # otherwise it is skipped
return None return None
res = {} res = {}
for field in [i for i in rec.getchildren() if (i.tag == "field")]: for field in rec.findall('./field'):
#TODO: most of this code is duplicated above (in _eval_xml)... #TODO: most of this code is duplicated above (in _eval_xml)...
f_name = field.get("name",'').encode('utf-8') f_name = field.get("name",'').encode('utf-8')
f_ref = field.get("ref",'').encode('ascii') f_ref = field.get("ref",'').encode('ascii')
@ -711,7 +701,7 @@ form: module.record_id""" % (xml_id,)
f_use = field.get("use",'').encode('ascii') or 'id' f_use = field.get("use",'').encode('ascii') or 'id'
f_val = False f_val = False
if len(f_search): if f_search:
q = eval(f_search, self.idref) q = eval(f_search, self.idref)
field = [] field = []
assert f_model, 'Define an attribute model="..." in your .XML file !' assert f_model, 'Define an attribute model="..." in your .XML file !'
@ -727,7 +717,7 @@ form: module.record_id""" % (xml_id,)
# otherwise (we are probably in a many2one field), # otherwise (we are probably in a many2one field),
# take the first element of the search # take the first element of the search
f_val = s[0][f_use] f_val = s[0][f_use]
elif len(f_ref): elif f_ref:
if f_ref=="null": if f_ref=="null":
f_val = False f_val = False
else: else:
@ -755,9 +745,7 @@ form: module.record_id""" % (xml_id,)
result = self.pool.get('ir.model.data')._get_id(cr, self.uid, mod, id_str) result = self.pool.get('ir.model.data')._get_id(cr, self.uid, mod, id_str)
return int(self.pool.get('ir.model.data').read(cr, self.uid, [result], ['res_id'])[0]['res_id']) return int(self.pool.get('ir.model.data').read(cr, self.uid, [result], ['res_id'])[0]['res_id'])
def parse(self, xmlstr): def parse(self, de):
de = etree.XML(xmlstr)
if not de.tag in ['terp', 'openerp']: if not de.tag in ['terp', 'openerp']:
self.logger.notifyChannel("init", netsvc.LOG_ERROR, "Mismatch xml format" ) self.logger.notifyChannel("init", netsvc.LOG_ERROR, "Mismatch xml format" )
raise Exception( "Mismatch xml format: only terp or openerp as root tag" ) raise Exception( "Mismatch xml format: only terp or openerp as root tag" )
@ -765,8 +753,8 @@ form: module.record_id""" % (xml_id,)
if de.tag == 'terp': if de.tag == 'terp':
self.logger.notifyChannel("init", netsvc.LOG_WARNING, "The tag <terp/> is deprecated, use <openerp/>") self.logger.notifyChannel("init", netsvc.LOG_WARNING, "The tag <terp/> is deprecated, use <openerp/>")
for n in [i for i in de.getchildren() if (i.tag=="data")]: for n in de.findall('./data'):
for rec in n.getchildren(): for rec in n:
if rec.tag in self._tags: if rec.tag in self._tags:
try: try:
self._tags[rec.tag](self.cr, rec, n) self._tags[rec.tag](self.cr, rec, n)
@ -861,12 +849,9 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
# xml import/export # xml import/export
# #
def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=False, report=None): def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=False, report=None):
xmlstr = xmlfile.read()
xmlfile.seek(0)
relaxng_doc = etree.parse(file(os.path.join( config['root_path'], 'import_xml.rng' )))
relaxng = etree.RelaxNG(relaxng_doc)
doc = etree.parse(xmlfile) doc = etree.parse(xmlfile)
relaxng = etree.RelaxNG(
etree.parse(os.path.join(config['root_path'],'import_xml.rng' )))
try: try:
relaxng.assert_(doc) relaxng.assert_(doc)
except Exception, e: except Exception, e:
@ -878,8 +863,7 @@ def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=Fa
if idref is None: if idref is None:
idref={} idref={}
obj = xml_import(cr, module, idref, mode, report=report, noupdate=noupdate) obj = xml_import(cr, module, idref, mode, report=report, noupdate=noupdate)
obj.parse(xmlstr) obj.parse(doc.getroot())
del obj
return True return True
def convert_xml_export(res): def convert_xml_export(res):

View File

@ -375,9 +375,9 @@ def trans_export(lang, modules, buffer, format, dbname=None):
def trans_parse_xsl(de): def trans_parse_xsl(de):
res = [] res = []
for n in [i for i in de.getchildren()]: for n in de:
if n.get("t"): if n.get("t"):
for m in [j for j in n.getchildren() if j.text]: for m in [j for j in n if j.text]:
l = m.text.strip().replace('\n',' ') l = m.text.strip().replace('\n',' ')
if len(l): if len(l):
res.append(l.encode("utf8")) res.append(l.encode("utf8"))
@ -386,8 +386,8 @@ def trans_parse_xsl(de):
def trans_parse_rml(de): def trans_parse_rml(de):
res = [] res = []
for n in [i for i in de.getchildren()]: for n in de:
for m in [j for j in n.getchildren() if j.text]: for m in [j for j in n if j.text]:
string_list = [s.replace('\n', ' ').strip() for s in re.split('\[\[.+?\]\]', m.text)] string_list = [s.replace('\n', ' ').strip() for s in re.split('\[\[.+?\]\]', m.text)]
for s in string_list: for s in string_list:
if s: if s:
@ -398,14 +398,10 @@ def trans_parse_rml(de):
def trans_parse_view(de): def trans_parse_view(de):
res = [] res = []
if de.get("string"): if de.get("string"):
s = de.get('string') res.append(de.get('string').encode("utf8"))
if s:
res.append(s.encode("utf8"))
if de.get("sum"): if de.get("sum"):
s = de.get('sum') res.append(de.get('sum').encode("utf8"))
if s: for n in de:
res.append(s.encode("utf8"))
for n in [i for i in de.getchildren()]:
res.extend(trans_parse_view(n)) res.extend(trans_parse_view(n))
return res return res

View File

@ -53,7 +53,7 @@ class interface(netsvc.Service):
trans = translate(cr, self.wiz_name+','+state, 'wizard_view', lang, node.get('string').encode('utf8')) trans = translate(cr, self.wiz_name+','+state, 'wizard_view', lang, node.get('string').encode('utf8'))
if trans: if trans:
node.set('string', trans) node.set('string', trans)
for n in node.getchildren(): for n in node:
self.translate_view(cr, n, state, lang) self.translate_view(cr, n, state, lang)
def execute_cr(self, cr, uid, data, state='init', context=None): def execute_cr(self, cr, uid, data, state='init', context=None):

View File

@ -54,8 +54,6 @@ py_short_version = '%s.%s' % sys.version_info[:2]
required_modules = [ required_modules = [
('psycopg2', 'PostgreSQL module'), ('psycopg2', 'PostgreSQL module'),
('xml', 'XML Tools for python'), ('xml', 'XML Tools for python'),
('libxml2', 'libxml2 python bindings'),
('libxslt', 'libxslt python bindings'),
('reportlab', 'reportlab module'), ('reportlab', 'reportlab module'),
('pychart', 'pychart module'), ('pychart', 'pychart module'),
('pydot', 'pydot module'), ('pydot', 'pydot module'),