Merge commit 'origin/master' into mdv-gpl3-py26
Conflicts: bin/report/interface.py bin/report/printscreen/ps_list.py bin/report/render/__init__.py bin/report/render/rml.py bin/report/render/rml2pdf/trml2pdf.py bin/sql_db.py bzr revid: p_christ@hol.gr-20090506201813-qb71ec85xr08obb1
This commit is contained in:
commit
3814e4dc73
|
@ -322,6 +322,7 @@ def upgrade_graph(graph, cr, module_list, force=None):
|
|||
raise
|
||||
if info.get('installable', True):
|
||||
packages.append((module, info.get('depends', []), info))
|
||||
|
||||
|
||||
dependencies = dict([(p, deps) for p, deps, data in packages])
|
||||
current, later = set([p for p, dep, data in packages]), set()
|
||||
|
@ -672,7 +673,8 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
pool = pooler.get_pool(cr.dbname)
|
||||
try:
|
||||
report = tools.assertion_report()
|
||||
STATES_TO_LOAD = ['installed', 'to upgrade']
|
||||
# NOTE: Try to also load the modules that have been marked as uninstallable previously...
|
||||
STATES_TO_LOAD = ['installed', 'to upgrade', 'uninstallable']
|
||||
graph = create_graph(cr, ['base'], force)
|
||||
has_updates = False
|
||||
if update_module:
|
||||
|
|
|
@ -145,6 +145,7 @@ CREATE TABLE res_users (
|
|||
context_tz varchar(64) default null,
|
||||
signature text,
|
||||
-- action_id int references ir_act_window on delete set null,
|
||||
context_lang varchar(64) default '',
|
||||
action_id int,
|
||||
primary key(id)
|
||||
);
|
||||
|
|
|
@ -121,6 +121,7 @@ class report_xml(osv.osv):
|
|||
('sxw', 'sxw'),
|
||||
('txt', 'txt'),
|
||||
('odt', 'odt'),
|
||||
('html2html','Html from html'),
|
||||
], string='Type', required=True),
|
||||
'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'),
|
||||
'attachment': fields.char('Save As Attachment Prefix', size=128, help='This is the filename of the attachment used to store the printing result. Keep empty to not save the printed reports. You can use a python expression with the object and time variables.'),
|
||||
|
@ -519,14 +520,15 @@ class actions_server(osv.osv):
|
|||
result = self.pool.get(action.action_id.type).read(cr, uid, action.action_id.id, context=context)
|
||||
return result
|
||||
|
||||
if action.state=='python':
|
||||
if action.state=='code':
|
||||
localdict = {
|
||||
'self': self.pool.get(action.model_id.model),
|
||||
'context': context,
|
||||
'time': time,
|
||||
'ids': ids,
|
||||
'cr': cr,
|
||||
'uid': uid
|
||||
'uid': uid,
|
||||
'obj':obj
|
||||
}
|
||||
exec action.code in localdict
|
||||
if 'action' in localdict:
|
||||
|
|
|
@ -178,8 +178,8 @@ class maintenance_contract_wizard(osv.osv_memory):
|
|||
|
||||
is_ok = contract_info['status'] in ('partial', 'full')
|
||||
if is_ok:
|
||||
module_ids = []
|
||||
if contract_info['modules_with_contract']:
|
||||
module_ids = []
|
||||
for name, version in contract_info['modules_with_contract']:
|
||||
contract_module = self.pool.get('maintenance.contract.module')
|
||||
res = contract_module.search(cr, uid, [('name', '=', name),('version', '=', version)])
|
||||
|
|
|
@ -244,7 +244,7 @@ class module(osv.osv):
|
|||
m.state not in ('uninstalled','uninstallable','to remove')''', (module.name,))
|
||||
res = cr.fetchall()
|
||||
if res:
|
||||
raise orm.except_orm(_('Error'), _('Some installed modules depends on the module you plan to desinstall :\n %s') % '\n'.join(map(lambda x: '\t%s: %s' % (x[0], x[1]), res)))
|
||||
raise orm.except_orm(_('Error'), _('Some installed modules depend on the module you plan to Uninstall :\n %s') % '\n'.join(map(lambda x: '\t%s: %s' % (x[0], x[1]), res)))
|
||||
self.write(cr, uid, ids, {'state': 'to remove'})
|
||||
return True
|
||||
|
||||
|
|
|
@ -200,6 +200,28 @@
|
|||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="data">
|
||||
<rng:element name="data">
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
<rng:ref name="form"/>
|
||||
<rng:ref name="tree"/>
|
||||
<rng:ref name="field"/>
|
||||
<rng:ref name="label"/>
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="notebook"/>
|
||||
<rng:ref name="page"/>
|
||||
<rng:ref name="xpath"/>
|
||||
<rng:ref name="button"/>
|
||||
<rng:ref name="group"/>
|
||||
<rng:ref name="graph"/>
|
||||
<rng:element name="newline"><rng:empty/></rng:element>
|
||||
</rng:choice>
|
||||
</rng:zeroOrMore>
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
|
||||
<rng:define name="field">
|
||||
<rng:element name="field">
|
||||
<rng:attribute name="name" />
|
||||
|
@ -366,6 +388,7 @@
|
|||
<rng:ref name="notebook" />
|
||||
<rng:ref name="graph" />
|
||||
<rng:ref name="calendar" />
|
||||
<rng:ref name="data" />
|
||||
<rng:ref name="gantt" />
|
||||
<rng:ref name="xpath" />
|
||||
<rng:ref name="page" />
|
||||
|
|
|
@ -450,13 +450,11 @@ class one2many(_column):
|
|||
elif act[0] == 5:
|
||||
cr.execute('update '+_table+' set '+self._fields_id+'=null where '+self._fields_id+'=%s', (id,))
|
||||
elif act[0] == 6:
|
||||
if not act[2]:
|
||||
ids2 = [0]
|
||||
else:
|
||||
ids2 = act[2]
|
||||
cr.execute('update '+_table+' set '+self._fields_id+'=NULL where '+self._fields_id+'=%s and id not in ('+','.join(map(str, ids2))+')', (id,))
|
||||
if act[2]:
|
||||
cr.execute('update '+_table+' set '+self._fields_id+'=%s where id in ('+','.join(map(str, act[2]))+')', (id,))
|
||||
obj.write(cr, user, act[2], {self._fields_id:id}, context=context or {})
|
||||
ids2 = act[2] or [0]
|
||||
cr.execute('select id from '+_table+' where '+self._fields_id+'=%s and id not in ('+','.join(map(str, ids2))+')', (id,))
|
||||
ids3 = map(lambda x:x[0], cr.fetchall())
|
||||
obj.write(cr, user, ids3, {self._fields_id:False}, context=context or {})
|
||||
|
||||
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like'):
|
||||
return obj.pool.get(self._obj).name_search(cr, uid, value, self._domain, offset, limit)
|
||||
|
|
|
@ -811,13 +811,14 @@ class orm_template(object):
|
|||
attrs = {}
|
||||
try:
|
||||
if node.getAttribute('name') in self._columns:
|
||||
relation = self._columns[node.getAttribute('name')]._obj
|
||||
column = self._columns[node.getAttribute('name')]
|
||||
else:
|
||||
relation = self._inherit_fields[node.getAttribute('name')][2]._obj
|
||||
column = self._inherit_fields[node.getAttribute('name')][2]
|
||||
except:
|
||||
relation = False
|
||||
column = False
|
||||
|
||||
if relation:
|
||||
if column:
|
||||
relation = column._obj
|
||||
childs = False
|
||||
views = {}
|
||||
for f in node.childNodes:
|
||||
|
@ -832,9 +833,12 @@ class orm_template(object):
|
|||
}
|
||||
attrs = {'views': views}
|
||||
if node.hasAttribute('widget') and node.getAttribute('widget')=='selection':
|
||||
# We can not use the domain has it is defined according to the record !
|
||||
attrs['selection'] = self.pool.get(relation).name_search(cr, user, '', context=context)
|
||||
if not attrs.get('required',False):
|
||||
# We can not use the 'string' domain has it is defined according to the record !
|
||||
dom = None
|
||||
if column._domain and not isinstance(column._domain, (str, unicode)):
|
||||
dom = column._domain
|
||||
attrs['selection'] = self.pool.get(relation).name_search(cr, user, '', dom, context=context)
|
||||
if (node.hasAttribute('required') and not int(node.getAttribute('required'))) or not column.required:
|
||||
attrs['selection'].append((False,''))
|
||||
fields[node.getAttribute('name')] = attrs
|
||||
|
||||
|
@ -2322,7 +2326,7 @@ class orm(orm_template):
|
|||
|
||||
# It's the first node of the parent: position = parent_left+1
|
||||
if not position:
|
||||
if not vals[self._parent_name]:
|
||||
if not vals[self._parent_name]:
|
||||
position = 1
|
||||
else:
|
||||
cr.execute('select parent_left from '+self._table+' where id=%s', (vals[self._parent_name],))
|
||||
|
@ -2450,10 +2454,6 @@ class orm(orm_template):
|
|||
upd2.append(user)
|
||||
cr.execute('insert into "'+self._table+'" (id'+upd0+") values ("+str(id_new)+upd1+')', tuple(upd2))
|
||||
upd_todo.sort(lambda x, y: self._columns[x].priority-self._columns[y].priority)
|
||||
for field in upd_todo:
|
||||
self._columns[field].set(cr, self, id_new, field, vals[field], user, context)
|
||||
|
||||
self._validate(cr, user, [id_new], context)
|
||||
|
||||
if self._parent_store:
|
||||
if self.pool._init:
|
||||
|
@ -2478,6 +2478,9 @@ class orm(orm_template):
|
|||
cr.execute('update '+self._table+' set parent_left=parent_left+2 where parent_left>%s', (pleft,))
|
||||
cr.execute('update '+self._table+' set parent_right=parent_right+2 where parent_right>%s', (pleft,))
|
||||
cr.execute('update '+self._table+' set parent_left=%s,parent_right=%s where id=%s', (pleft+1,pleft+2,id_new))
|
||||
for field in upd_todo:
|
||||
self._columns[field].set(cr, self, id_new, field, vals[field], user, context)
|
||||
self._validate(cr, user, [id_new], context)
|
||||
|
||||
result = self._store_get_values(cr, user, [id_new], vals.keys(), context)
|
||||
for order, object, ids, fields in result:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -25,5 +25,48 @@ pageSize = {
|
|||
'A5': (148.5,105)
|
||||
}
|
||||
|
||||
odt_namespace = {
|
||||
"office":"{urn:oasis:names:tc:opendocument:xmlns:office:1.0}",
|
||||
"style":"{urn:oasis:names:tc:opendocument:xmlns:style:1.0}",
|
||||
"text":"{urn:oasis:names:tc:opendocument:xmlns:text:1.0}",
|
||||
"table":"{urn:oasis:names:tc:opendocument:xmlns:table:1.0}",
|
||||
"draw":"{urn:oasis:names:tc:opendocument:xmlns:drawing:1.0}",
|
||||
"fo":"{urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0}",
|
||||
"xlink":"{http://www.w3.org/1999/xlink}",
|
||||
"dc":"{http://purl.org/dc/elements/1.1/}",
|
||||
"meta":"{urn:oasis:names:tc:opendocument:xmlns:meta:1.0}",
|
||||
"number":"{urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0}",
|
||||
"svg":"{urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0}",
|
||||
"chart":"{urn:oasis:names:tc:opendocument:xmlns:chart:1.0}",
|
||||
"dr3d":"{urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0}",
|
||||
"math":"{http://www.w3.org/1998/Math/MathML}",
|
||||
"form":"{urn:oasis:names:tc:opendocument:xmlns:form:1.0}",
|
||||
"script":"{urn:oasis:names:tc:opendocument:xmlns:script:1.0}",
|
||||
"ooo":"{http://openoffice.org/2004/office}",
|
||||
"ooow":"{http://openoffice.org/2004/writer}",
|
||||
"oooc":"{http://openoffice.org/2004/calc}",
|
||||
"dom":"{http://www.w3.org/2001/xml-events}" }
|
||||
|
||||
sxw_namespace = {
|
||||
"office":"{http://openoffice.org/2000/office}",
|
||||
"style":"{http://openoffice.org/2000/style}",
|
||||
"text":"{http://openoffice.org/2000/text}",
|
||||
"table":"{http://openoffice.org/2000/table}",
|
||||
"draw":"{http://openoffice.org/2000/drawing}",
|
||||
"fo":"{http://www.w3.org/1999/XSL/Format}",
|
||||
"xlink":"{http://www.w3.org/1999/xlink}",
|
||||
"dc":"{http://purl.org/dc/elements/1.1/}",
|
||||
"meta":"{http://openoffice.org/2000/meta}",
|
||||
"number":"{http://openoffice.org/2000/datastyle}",
|
||||
"svg":"{http://www.w3.org/2000/svg}",
|
||||
"chart":"{http://openoffice.org/2000/chart}",
|
||||
"dr3d":"{http://openoffice.org/2000/dr3d}",
|
||||
"math":"{http://www.w3.org/1998/Math/MathML}",
|
||||
"form":"{http://openoffice.org/2000/form}",
|
||||
"script":"{http://openoffice.org/2000/script}",
|
||||
"ooo":"{http://openoffice.org/2004/office}",
|
||||
"ooow":"{http://openoffice.org/2004/writer}",
|
||||
"oooc":"{http://openoffice.org/2004/calc}",
|
||||
"dom":"{http://www.w3.org/2001/xml-events}"}
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -23,10 +23,9 @@
|
|||
import os
|
||||
import re
|
||||
|
||||
#Ged> Why do we use libxml2 here instead of xml.dom like in other places of the code?
|
||||
import libxml2
|
||||
import libxslt
|
||||
|
||||
from lxml import etree
|
||||
import netsvc
|
||||
import pooler
|
||||
|
||||
|
@ -84,6 +83,7 @@ class report_rml(report_int):
|
|||
'sxw': self.create_sxw,
|
||||
'txt': self.create_txt,
|
||||
'odt': self.create_odt,
|
||||
'html2html' : self.create_html2html,
|
||||
}
|
||||
|
||||
def create(self, cr, uid, ids, datas, context):
|
||||
|
@ -190,18 +190,18 @@ class report_rml(report_int):
|
|||
result.freeDoc()
|
||||
return xml
|
||||
|
||||
def create_pdf(self, xml, logo=None, title=None):
|
||||
def create_pdf(self, rml, localcontext = None, logo=None, title=None):
|
||||
if logo:
|
||||
self.bin_datas['logo'] = logo
|
||||
else:
|
||||
if 'logo' in self.bin_datas:
|
||||
del self.bin_datas['logo']
|
||||
obj = render.rml(xml, self.bin_datas, tools.config['root_path'],title)
|
||||
obj = render.rml(rml, localcontext, self.bin_datas, tools.config['root_path'],title)
|
||||
obj.render()
|
||||
return obj.get()
|
||||
|
||||
def create_html(self, xml, logo=None, title=None):
|
||||
obj = render.rml2html(xml, self.bin_datas)
|
||||
def create_html(self, rml, localcontext = None, logo=None, title=None):
|
||||
obj = render.rml2html(rml, localcontext, self.bin_datas)
|
||||
obj.render()
|
||||
return obj.get()
|
||||
|
||||
|
@ -210,15 +210,26 @@ class report_rml(report_int):
|
|||
obj.render()
|
||||
return obj.get().encode('utf-8')
|
||||
|
||||
def create_raw(self, xml, logo=None, title=None):
|
||||
return xml
|
||||
def create_html2html(self, rml, localcontext = None, logo=None, title=None):
|
||||
obj = render.html2html(rml, localcontext, self.bin_datas)
|
||||
obj.render()
|
||||
return obj.get()
|
||||
|
||||
def create_sxw(self, path, logo=None, title=None):
|
||||
return path
|
||||
|
||||
def create_odt(self, data, logo=None, title=None):
|
||||
return data
|
||||
|
||||
|
||||
def create_raw(self,rml, localcontext = None, logo=None, title=None):
|
||||
obj = render.odt2odt(etree.XML(rml),localcontext)
|
||||
obj.render()
|
||||
return etree.tostring(obj.get())
|
||||
|
||||
def create_sxw(self,rml,localcontext = None):
|
||||
obj = render.odt2odt(rml,localcontext)
|
||||
obj.render()
|
||||
return obj.get()
|
||||
|
||||
def create_odt(self,rml,localcontext = None):
|
||||
obj = render.odt2odt(rml,localcontext)
|
||||
obj.render()
|
||||
return obj.get()
|
||||
|
||||
from report_sxw import report_sxw
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
from lxml import etree
|
||||
import re
|
||||
rml_parents = ['tr','story','section']
|
||||
html_parents = ['tr','body','div']
|
||||
sxw_parents = ['{http://openoffice.org/2000/table}table-row','{http://openoffice.org/2000/office}body','{http://openoffice.org/2000/text}section']
|
||||
|
||||
class report(object):
|
||||
def preprocess_rml(self, root_node,type='pdf'):
|
||||
_regex1 = re.compile("\[\[(.*?)(repeatIn\(.*?\s*,\s*[\'\"].*?[\'\"]\s*(?:,\s*(.*?)\s*)?\s*\))(.*?)\]\]")
|
||||
_regex11= re.compile("\[\[(.*?)(repeatIn\(.*?\s*\(.*?\s*[\'\"].*?[\'\"]\s*\),[\'\"].*?[\'\"](?:,\s*(.*?)\s*)?\s*\))(.*?)\]\]")
|
||||
_regex2 = re.compile("\[\[(.*?)(removeParentNode\(\s*(?:['\"](.*?)['\"])\s*\))(.*?)\]\]")
|
||||
_regex3 = re.compile("\[\[\s*(.*?setTag\(\s*['\"](.*?)['\"]\s*,\s*['\"].*?['\"]\s*(?:,.*?)?\).*?)\s*\]\]")
|
||||
for node in root_node:
|
||||
if node.text:
|
||||
def _sub3(txt):
|
||||
n = node
|
||||
while n.tag != txt.group(2):
|
||||
n = n.getparent()
|
||||
n.set('rml_tag', txt.group(1))
|
||||
return "[[ '' ]]"
|
||||
def _sub2(txt):
|
||||
if txt.group(3):
|
||||
n = node
|
||||
try:
|
||||
while n.tag != txt.group(3):
|
||||
n = n.getparent()
|
||||
except:
|
||||
n = node
|
||||
else:
|
||||
n = node.getparent()
|
||||
n.set('rml_except', txt.group(0)[2:-2])
|
||||
return txt.group(0)
|
||||
def _sub1(txt):
|
||||
if len(txt.group(4)) > 1:
|
||||
return " "
|
||||
match = rml_parents
|
||||
if type in ['odt','sxw']:
|
||||
match = sxw_parents
|
||||
if type =='html2html':
|
||||
match = html_parents
|
||||
if txt.group(3):
|
||||
match = [txt.group(3)]
|
||||
n = node
|
||||
while n.tag not in match:
|
||||
n = n.getparent()
|
||||
n.set('rml_loop', txt.group(2))
|
||||
return '[['+txt.group(1)+"''"+txt.group(4)+']]'
|
||||
t = _regex1.sub(_sub1, node.text)
|
||||
if t == " ":
|
||||
t = _regex11.sub(_sub1, node.text)
|
||||
t = _regex3.sub(_sub3, t)
|
||||
node.text = _regex2.sub(_sub2, t)
|
||||
self.preprocess_rml(node,type)
|
||||
return root_node
|
||||
|
||||
if __name__=='__main__':
|
||||
node = etree.XML('''<story>
|
||||
<para>This is a test[[ setTag('para','xpre') ]]</para>
|
||||
<blockTable>
|
||||
<tr>
|
||||
<td><para>Row 1 [[ setTag('tr','tr',{'style':'TrLevel'+str(a['level']), 'paraStyle':('Level'+str(a['level']))}) ]] </para></td>
|
||||
<td>Row 2 [[ True and removeParentNode('td') ]] </td>
|
||||
</tr><tr>
|
||||
<td>Row 1 [[repeatIn(o.order_line,'o')]] </td>
|
||||
<td>Row 2</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<p>This isa test</p>
|
||||
</story>''')
|
||||
a = report()
|
||||
result = a.preprocess_rml(node)
|
||||
print etree.tostring(result)
|
||||
|
|
@ -262,7 +262,8 @@ class document(object):
|
|||
if not isinstance(datas[atr['value']], (str, unicode)):
|
||||
txt = self.doc.createTextNode(str(datas[atr['value']]))
|
||||
else:
|
||||
txt = self.doc.createTextNode(datas[atr['value']].decode('utf-8'))
|
||||
# txt = self.doc.createTextNode(datas[atr['value']].decode('utf-8'))
|
||||
txt = self.doc.createTextNode(datas[atr['value']])
|
||||
el.appendChild(txt)
|
||||
else:
|
||||
el_cld = node.firstChild
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -25,7 +25,7 @@ import pooler
|
|||
import tools
|
||||
|
||||
from report import render
|
||||
|
||||
from lxml import etree
|
||||
from xml.dom import minidom
|
||||
import libxml2
|
||||
import libxslt
|
||||
|
@ -38,20 +38,25 @@ class report_printscreen_list(report_int):
|
|||
|
||||
def _parse_node(self, root_node):
|
||||
result = []
|
||||
for node in root_node.childNodes:
|
||||
if node.localName == 'field':
|
||||
attrsa = node.attributes
|
||||
for node in root_node.getchildren():
|
||||
if node.tag == 'field':
|
||||
#attrsa = node.attributes
|
||||
attrsa = node.attrib
|
||||
print "typppppp",type(attrsa),dir(attrsa)
|
||||
attrs = {}
|
||||
if not attrsa is None:
|
||||
for i in range(attrsa.length):
|
||||
attrs[attrsa.item(i).localName] = attrsa.item(i).nodeValue
|
||||
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 = minidom.parseString(view)
|
||||
dom = etree.XML(view)
|
||||
return self._parse_node(dom)
|
||||
|
||||
def create(self, cr, uid, ids, datas, context=None):
|
||||
|
|
|
@ -23,10 +23,8 @@
|
|||
from report.interface import report_int
|
||||
import pooler
|
||||
import tools
|
||||
|
||||
from lxml import etree
|
||||
from report import render
|
||||
|
||||
from xml.dom import minidom
|
||||
import libxml2
|
||||
import libxslt
|
||||
|
||||
|
@ -38,20 +36,20 @@ class report_printscreen_list(report_int):
|
|||
|
||||
def _parse_node(self, root_node):
|
||||
result = []
|
||||
for node in root_node.childNodes:
|
||||
if node.localName == 'field':
|
||||
attrsa = node.attributes
|
||||
for node in root_node.getchildren():
|
||||
if node.tag == 'field':
|
||||
attrsa = node.attrib
|
||||
attrs = {}
|
||||
if not attrsa is None:
|
||||
for i in range(attrsa.length):
|
||||
attrs[attrsa.item(i).localName] = attrsa.item(i).nodeValue
|
||||
for key,val in attrsa.items():
|
||||
attrs[key] = val
|
||||
result.append(attrs['name'])
|
||||
else:
|
||||
result.extend(self._parse_node(node))
|
||||
return result
|
||||
|
||||
def _parse_string(self, view):
|
||||
dom = minidom.parseString(unicode(view, 'utf-8').encode('utf-8'))
|
||||
dom = etree.XML(unicode(view, 'utf-8').encode('utf-8'))
|
||||
return self._parse_node(dom)
|
||||
|
||||
def create(self, cr, uid, ids, datas, context=None):
|
||||
|
@ -79,18 +77,15 @@ class report_printscreen_list(report_int):
|
|||
|
||||
def _create_table(self, uid, ids, fields, fields_order, results, context, title=''):
|
||||
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))
|
||||
|
@ -126,19 +121,17 @@ class report_printscreen_list(report_int):
|
|||
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(fields[f]['string'] or '')
|
||||
field.appendChild(field_txt)
|
||||
header.appendChild(field)
|
||||
field = etree.Element("field")
|
||||
field.text = fields[f]['string'] or ''
|
||||
header.append(field)
|
||||
|
||||
new_doc.childNodes[0].appendChild(header)
|
||||
|
||||
lines = new_doc.createElement("lines")
|
||||
new_doc.append(header)
|
||||
lines = etree.Element("lines")
|
||||
|
||||
tsum = []
|
||||
count = len(fields_order)
|
||||
|
@ -147,7 +140,7 @@ class report_printscreen_list(report_int):
|
|||
|
||||
|
||||
for line in results:
|
||||
node_line = new_doc.createElement("row")
|
||||
node_line = etree.Element("row")
|
||||
count = -1
|
||||
for f in fields_order:
|
||||
|
||||
|
@ -169,49 +162,46 @@ class report_printscreen_list(report_int):
|
|||
precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
|
||||
line[f]='%.2f'%(line[f])
|
||||
|
||||
col = new_doc.createElement("col")
|
||||
col.setAttribute('para','yes')
|
||||
col.setAttribute('tree','no')
|
||||
col = etree.Element("col")
|
||||
col.set('para','yes')
|
||||
col.set('tree','no')
|
||||
if line[f] != None:
|
||||
txt = new_doc.createTextNode(tools.ustr(line[f] or ''))
|
||||
col.text = tools.ustr(line[f] or '')
|
||||
if temp[count] == 1:
|
||||
tsum[count] = float(tsum[count]) + float(line[f]);
|
||||
|
||||
else:
|
||||
txt = new_doc.createTextNode('/')
|
||||
col.appendChild(txt)
|
||||
node_line.appendChild(col)
|
||||
lines.appendChild(node_line)
|
||||
node_line = new_doc.createElement("row")
|
||||
lines.appendChild(node_line)
|
||||
node_line = new_doc.createElement("row")
|
||||
count = len(tsum)
|
||||
for f in range(0,count):
|
||||
col = new_doc.createElement("col")
|
||||
col.setAttribute('para','yes')
|
||||
col.setAttribute('tree','no')
|
||||
col.text = '/'
|
||||
node_line.append(col)
|
||||
lines.append(node_line)
|
||||
node_line = etree.Element("row")
|
||||
lines.append(node_line)
|
||||
|
||||
for f in range(0,count+1):
|
||||
col = etree.Element("col")
|
||||
col.set('para','yes')
|
||||
col.set('tree','no')
|
||||
if tsum[f] != None:
|
||||
if tsum[f] >= 0.01 :
|
||||
total = '%.2f'%(tsum[f])
|
||||
txt = new_doc.createTextNode(str(total or ''))
|
||||
txt = str(total or '')
|
||||
else :
|
||||
txt = new_doc.createTextNode(str(tsum[f] or ''))
|
||||
txt = str(tsum[f] or '')
|
||||
else:
|
||||
txt = new_doc.createTextNode('/')
|
||||
txt = '/'
|
||||
if f == 0:
|
||||
txt = new_doc.createTextNode('Total')
|
||||
txt ='Total'
|
||||
|
||||
col.appendChild(txt)
|
||||
node_line.appendChild(col)
|
||||
col.text = txt
|
||||
node_line.append(col)
|
||||
|
||||
lines.appendChild(node_line)
|
||||
lines.append(node_line)
|
||||
|
||||
|
||||
new_doc.childNodes[0].appendChild(lines)
|
||||
|
||||
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(new_doc.toxml(encoding='utf-8'))
|
||||
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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -21,8 +21,7 @@
|
|||
##############################################################################
|
||||
|
||||
from simple import simple
|
||||
from rml import rml, rml2html, rml2txt
|
||||
|
||||
from rml import rml, rml2html, rml2txt, odt2odt , html2html
|
||||
from render import render
|
||||
|
||||
try:
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from html2html import parseString
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from report.render.rml2pdf import utils
|
||||
from lxml import etree
|
||||
import copy
|
||||
import pooler
|
||||
|
||||
|
||||
class html2html(object):
|
||||
def __init__(self, html, localcontext):
|
||||
self.localcontext = localcontext
|
||||
self.etree = html
|
||||
self._node = None
|
||||
|
||||
|
||||
def render(self):
|
||||
def process_text(node,new_node):
|
||||
if new_node.tag in ['story','tr','section']:
|
||||
new_node.attrib.clear()
|
||||
for child in utils._child_get(node, self):
|
||||
new_child = copy.deepcopy(child)
|
||||
new_node.append(new_child)
|
||||
if len(child):
|
||||
for n in new_child:
|
||||
new_child.remove(n)
|
||||
process_text(child, new_child)
|
||||
else:
|
||||
if new_child.tag=='img' and new_child.get('name'):
|
||||
src = utils._process_text(self, new_child.get('name'))
|
||||
if src :
|
||||
new_child.set('src','data:image/gif;base64,%s'%src)
|
||||
new_child.text = utils._process_text(self, child.text)
|
||||
self._node = copy.deepcopy(self.etree)
|
||||
for n in self._node:
|
||||
self._node.remove(n)
|
||||
process_text(self.etree, self._node)
|
||||
return self._node
|
||||
|
||||
def parseString(node, localcontext = {}):
|
||||
r = html2html(node, localcontext)
|
||||
return r.render()
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from odt2odt import parseNode
|
|
@ -0,0 +1,67 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from report.render.rml2pdf import utils
|
||||
from lxml import etree
|
||||
import copy
|
||||
|
||||
|
||||
class odt2odt(object):
|
||||
def __init__(self, odt, localcontext):
|
||||
self.localcontext = localcontext
|
||||
self.etree = odt
|
||||
self._node = None
|
||||
|
||||
|
||||
def render(self):
|
||||
def process_text(node,new_node):
|
||||
if new_node.tag in ['story','tr','section']:
|
||||
new_node.attrib.clear()
|
||||
for child in utils._child_get(node, self):
|
||||
new_child = copy.deepcopy(child)
|
||||
new_node.append(new_child)
|
||||
if len(child):
|
||||
for n in new_child:
|
||||
new_child.remove(n)
|
||||
process_text(child, new_child)
|
||||
else:
|
||||
new_child.text = utils._process_text(self, child.text)
|
||||
self._node = copy.deepcopy(self.etree)
|
||||
for n in self._node:
|
||||
self._node.remove(n)
|
||||
process_text(self.etree, self._node)
|
||||
return self._node
|
||||
|
||||
def parseNode(node, localcontext = {}):
|
||||
body = node.getchildren()[-1]
|
||||
elements = body.findall(localcontext['name_space']["text"]+"p")
|
||||
for pe in elements:
|
||||
e = pe.findall(localcontext['name_space']["text"]+"drop-down")
|
||||
for de in e:
|
||||
pp=de.getparent()
|
||||
for cnd in de.getchildren():
|
||||
if cnd.text:
|
||||
pe.append(cnd)
|
||||
pp.remove(de)
|
||||
r = odt2odt(node, localcontext)
|
||||
return r.render()
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -24,26 +24,32 @@ import render
|
|||
import rml2pdf
|
||||
import rml2html as htmlizer
|
||||
import rml2txt as txtizer
|
||||
import odt2odt as odt
|
||||
import html2html as html
|
||||
|
||||
|
||||
class rml(render.render):
|
||||
def __init__(self, xml, datas={}, path='.',title=None):
|
||||
def __init__(self, rml, localcontext = None, datas={}, path='.', title=None):
|
||||
render.render.__init__(self, datas)
|
||||
self.xml = xml
|
||||
self.localcontext = localcontext
|
||||
self.rml = rml
|
||||
self.output_type = 'pdf'
|
||||
self.path = path
|
||||
self.title=title
|
||||
|
||||
|
||||
def _render(self):
|
||||
return rml2pdf.parseString(self.xml, images=self.bin_datas, path=self.path,title=self.title)
|
||||
return rml2pdf.parseNode(self.rml, self.localcontext, images=self.bin_datas, path=self.path,title=self.title)
|
||||
|
||||
class rml2html(render.render):
|
||||
def __init__(self, xml, datas={}):
|
||||
def __init__(self, rml,localcontext = None, datas = {}):
|
||||
super(rml2html, self).__init__(datas)
|
||||
self.xml = xml
|
||||
self.rml = rml
|
||||
self.localcontext = localcontext
|
||||
self.output_type = 'html'
|
||||
|
||||
def _render(self):
|
||||
return htmlizer.parseString(self.xml)
|
||||
return htmlizer.parseString(self.rml,self.localcontext)
|
||||
|
||||
class rml2txt(render.render):
|
||||
def __init__(self, xml, datas={}):
|
||||
|
@ -54,5 +60,26 @@ class rml2txt(render.render):
|
|||
def _render(self):
|
||||
return txtizer.parseString(self.xml)
|
||||
|
||||
class odt2odt(render.render):
|
||||
def __init__(self, rml, localcontext = None, datas = {}):
|
||||
render.render.__init__(self, datas)
|
||||
self.rml_dom = rml
|
||||
self.localcontext = localcontext
|
||||
self.output_type = 'odt'
|
||||
|
||||
|
||||
def _render(self):
|
||||
return odt.parseNode(self.rml_dom,self.localcontext)
|
||||
|
||||
class html2html(render.render):
|
||||
def __init__(self, rml, localcontext = None, datas = {}):
|
||||
render.render.__init__(self, datas)
|
||||
self.rml_dom = rml
|
||||
self.localcontext = localcontext
|
||||
self.output_type = 'html'
|
||||
|
||||
def _render(self):
|
||||
return html.parseString(self.rml_dom,self.localcontext)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -38,17 +38,18 @@
|
|||
|
||||
import sys
|
||||
import cStringIO
|
||||
import xml.dom.minidom
|
||||
from lxml import etree
|
||||
import copy
|
||||
|
||||
import utils
|
||||
from report.render.rml2pdf import utils
|
||||
|
||||
class _flowable(object):
|
||||
def __init__(self, template, doc):
|
||||
def __init__(self, template, doc, localcontext = None):
|
||||
self._tags = {
|
||||
'title': self._tag_title,
|
||||
'spacer': self._tag_spacer,
|
||||
'para': self._tag_para,
|
||||
'section':self._section,
|
||||
'nextFrame': self._tag_next_frame,
|
||||
'blockTable': self._tag_table,
|
||||
'pageBreak': self._tag_page_break,
|
||||
|
@ -56,6 +57,8 @@ class _flowable(object):
|
|||
}
|
||||
self.template = template
|
||||
self.doc = doc
|
||||
self.localcontext = localcontext
|
||||
self._cache = {}
|
||||
|
||||
def _tag_page_break(self, node):
|
||||
return '<br/>'*3
|
||||
|
@ -70,43 +73,72 @@ class _flowable(object):
|
|||
return result
|
||||
|
||||
def _tag_title(self, node):
|
||||
node.tagName='h1'
|
||||
return node.toxml()
|
||||
node.tag='h1'
|
||||
return etree.tostring(node)
|
||||
|
||||
def _tag_spacer(self, node):
|
||||
length = 1+int(utils.unit_get(node.getAttribute('length')))/35
|
||||
length = 1+int(utils.unit_get(node.get('length')))/35
|
||||
return "<br/>"*length
|
||||
|
||||
def _tag_table(self, node):
|
||||
node.tagName='table'
|
||||
if node.hasAttribute('colWidths'):
|
||||
sizes = map(lambda x: utils.unit_get(x), node.getAttribute('colWidths').split(','))
|
||||
tr = self.doc.createElement('tr')
|
||||
new_node = copy.deepcopy(node)
|
||||
for child in new_node:
|
||||
new_node.remove(child)
|
||||
new_node.tag = 'table'
|
||||
def process(node,new_node):
|
||||
for child in utils._child_get(node,self):
|
||||
new_child = copy.deepcopy(child)
|
||||
new_node.append(new_child)
|
||||
if len(child):
|
||||
for n in new_child:
|
||||
new_child.remove(n)
|
||||
process(child, new_child)
|
||||
else:
|
||||
new_child.text = utils._process_text(self, child.text)
|
||||
new_child.tag = 'p'
|
||||
try:
|
||||
if new_child.get('style').find('terp_tblheader')!= -1:
|
||||
new_node.tag = 'th'
|
||||
except:
|
||||
pass
|
||||
process(node,new_node)
|
||||
if new_node.get('colWidths',False):
|
||||
sizes = map(lambda x: utils.unit_get(x), new_node.get('colWidths').split(','))
|
||||
tr = etree.Element('tr')
|
||||
for s in sizes:
|
||||
td = self.doc.createElement('td')
|
||||
td.setAttribute("width", str(s))
|
||||
tr.appendChild(td)
|
||||
node.appendChild(tr)
|
||||
return node.toxml()
|
||||
td = etree.Element('td')
|
||||
td.set("width", str(s))
|
||||
tr.append(td)
|
||||
new_node.append(tr)
|
||||
return etree.tostring(new_node)
|
||||
|
||||
def _tag_para(self, node):
|
||||
node.tagName='p'
|
||||
if node.hasAttribute('style'):
|
||||
node.setAttribute('class', node.getAttribute('style'))
|
||||
return node.toxml()
|
||||
new_node = copy.deepcopy(node)
|
||||
new_node.tag = 'p'
|
||||
if new_node.attrib.get('style',False):
|
||||
new_node.set('class', new_node.get('style'))
|
||||
new_node.text = utils._process_text(self, node.text)
|
||||
return etree.tostring(new_node)
|
||||
|
||||
def _section(self, node):
|
||||
result = ''
|
||||
for child in utils._child_get(node, self):
|
||||
if child.tag in self._tags:
|
||||
result += self._tags[child.tag](child)
|
||||
return result
|
||||
|
||||
def render(self, node):
|
||||
result = self.template.start()
|
||||
result += self.template.frame_start()
|
||||
for n in node.childNodes:
|
||||
if n.nodeType==node.ELEMENT_NODE:
|
||||
if n.localName in self._tags:
|
||||
result += self._tags[n.localName](n)
|
||||
else:
|
||||
pass
|
||||
#print 'tag', n.localName, 'not yet implemented!'
|
||||
for n in utils._child_get(node, self):
|
||||
if n.tag in self._tags:
|
||||
result += self._tags[n.tag](n)
|
||||
else:
|
||||
pass
|
||||
result += self.template.frame_stop()
|
||||
result += self.template.end()
|
||||
return result.encode('utf-8').replace('"',"\'").replace('°','°')
|
||||
|
||||
class _rml_tmpl_tag(object):
|
||||
def __init__(self, *args):
|
||||
pass
|
||||
|
@ -132,21 +164,22 @@ class _rml_tmpl_frame(_rml_tmpl_tag):
|
|||
def tag_mergeable(self):
|
||||
return False
|
||||
|
||||
# An awfull workaround since I don't really understand the semantic behind merge.
|
||||
def merge(self, frame):
|
||||
pass
|
||||
|
||||
class _rml_tmpl_draw_string(_rml_tmpl_tag):
|
||||
def __init__(self, node, style):
|
||||
self.posx = utils.unit_get(node.getAttribute('x'))
|
||||
self.posy = utils.unit_get(node.getAttribute('y'))
|
||||
def __init__(self, node, style,localcontext = {}):
|
||||
self.localcontext = localcontext
|
||||
self.posx = utils.unit_get(node.get('x'))
|
||||
self.posy = utils.unit_get(node.get('y'))
|
||||
|
||||
aligns = {
|
||||
'drawString': 'left',
|
||||
'drawRightString': 'right',
|
||||
'drawCentredString': 'center'
|
||||
}
|
||||
align = aligns[node.localName]
|
||||
self.pos = [(self.posx, self.posy, align, utils.text_get(node), style.get('td'), style.font_size_get('td'))]
|
||||
align = aligns[node.tag]
|
||||
self.pos = [(self.posx, self.posy, align, utils._process_text(self, node.text), style.get('td'), style.font_size_get('td'))]
|
||||
|
||||
def tag_start(self):
|
||||
self.pos.sort()
|
||||
|
@ -171,8 +204,9 @@ class _rml_tmpl_draw_string(_rml_tmpl_tag):
|
|||
self.pos+=ds.pos
|
||||
|
||||
class _rml_tmpl_draw_lines(_rml_tmpl_tag):
|
||||
def __init__(self, node, style):
|
||||
coord = [utils.unit_get(x) for x in utils.text_get(node).split(' ')]
|
||||
def __init__(self, node, style, localcontext = {}):
|
||||
self.localcontext = localcontext
|
||||
coord = [utils.unit_get(x) for x in utils._process_text(self, node.text).split(' ')]
|
||||
self.ok = False
|
||||
self.posx = coord[0]
|
||||
self.posy = coord[1]
|
||||
|
@ -188,20 +222,20 @@ class _rml_tmpl_draw_lines(_rml_tmpl_tag):
|
|||
return ''
|
||||
|
||||
class _rml_stylesheet(object):
|
||||
def __init__(self, stylesheet, doc):
|
||||
def __init__(self, localcontext, stylesheet, doc):
|
||||
self.doc = doc
|
||||
self.localcontext = localcontext
|
||||
self.attrs = {}
|
||||
self._tags = {
|
||||
'fontSize': lambda x: ('font-size',str(utils.unit_get(x))+'px'),
|
||||
'fontSize': lambda x: ('font-size',str(utils.unit_get(x)+5.0)+'px'),
|
||||
'alignment': lambda x: ('text-align',str(x))
|
||||
}
|
||||
result = ''
|
||||
for ps in stylesheet.getElementsByTagName('paraStyle'):
|
||||
for ps in stylesheet.findall('paraStyle'):
|
||||
attr = {}
|
||||
attrs = ps.attributes
|
||||
for i in range(attrs.length):
|
||||
name = attrs.item(i).localName
|
||||
attr[name] = ps.getAttribute(name)
|
||||
attrs = ps.attrib
|
||||
for key, val in attrs.items():
|
||||
attr[key] = val
|
||||
attrs = []
|
||||
for a in attr:
|
||||
if a in self._tags:
|
||||
|
@ -217,13 +251,13 @@ class _rml_draw_style(object):
|
|||
def __init__(self):
|
||||
self.style = {}
|
||||
self._styles = {
|
||||
'fill': lambda x: {'td': {'color':x.getAttribute('color')}},
|
||||
'setFont': lambda x: {'td': {'font-size':x.getAttribute('size')+'px'}},
|
||||
'stroke': lambda x: {'hr': {'color':x.getAttribute('color')}},
|
||||
'fill': lambda x: {'td': {'color':x.get('color')}},
|
||||
'setFont': lambda x: {'td': {'font-size':x.get('size')+'px'}},
|
||||
'stroke': lambda x: {'hr': {'color':x.get('color')}},
|
||||
}
|
||||
def update(self, node):
|
||||
if node.localName in self._styles:
|
||||
result = self._styles[node.localName](node)
|
||||
if node.tag in self._styles:
|
||||
result = self._styles[node.tag](node)
|
||||
for key in result:
|
||||
if key in self.style:
|
||||
self.style[key].update(result[key])
|
||||
|
@ -239,8 +273,9 @@ class _rml_draw_style(object):
|
|||
return ';'.join(['%s:%s' % (x[0],x[1]) for x in self.style[tag].items()])
|
||||
|
||||
class _rml_template(object):
|
||||
def __init__(self, template):
|
||||
def __init__(self, template, localcontext=None):
|
||||
self.frame_pos = -1
|
||||
self.localcontext = localcontext
|
||||
self.frames = []
|
||||
self.template_order = []
|
||||
self.page_template = {}
|
||||
|
@ -252,20 +287,23 @@ class _rml_template(object):
|
|||
'lines': _rml_tmpl_draw_lines
|
||||
}
|
||||
self.style = _rml_draw_style()
|
||||
for pt in template.getElementsByTagName('pageTemplate'):
|
||||
rc = 'data:image/png;base64,'
|
||||
self.data = ''
|
||||
for pt in template.findall('pageTemplate'):
|
||||
frames = {}
|
||||
id = pt.getAttribute('id')
|
||||
id = pt.get('id')
|
||||
self.template_order.append(id)
|
||||
for tmpl in pt.getElementsByTagName('frame'):
|
||||
posy = int(utils.unit_get(tmpl.getAttribute('y1'))) #+utils.unit_get(tmpl.getAttribute('height')))
|
||||
posx = int(utils.unit_get(tmpl.getAttribute('x1')))
|
||||
frames[(posy,posx,tmpl.getAttribute('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.getAttribute('width')))
|
||||
for tmpl in template.getElementsByTagName('pageGraphics'):
|
||||
for n in tmpl.childNodes:
|
||||
if n.nodeType==n.ELEMENT_NODE:
|
||||
if n.localName in self._tags:
|
||||
t = self._tags[n.localName](n, self.style)
|
||||
frames[(t.posy,t.posx,n.localName)] = t
|
||||
for tmpl in pt.findall('frame'):
|
||||
posy = int(utils.unit_get(tmpl.get('y1')))
|
||||
posx = int(utils.unit_get(tmpl.get('x1')))
|
||||
frames[(posy,posx,tmpl.get('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.get('width')))
|
||||
for tmpl in pt.findall('pageGraphics'):
|
||||
for n in tmpl.getchildren():
|
||||
if n.tag == 'image':
|
||||
self.data = rc + utils._process_text(self, n.text)
|
||||
if n.tag in self._tags:
|
||||
t = self._tags[n.tag](n, self.style,self.localcontext)
|
||||
frames[(t.posy,t.posx,n.tag)] = t
|
||||
else:
|
||||
self.style.update(n)
|
||||
keys = frames.keys()
|
||||
|
@ -318,7 +356,7 @@ class _rml_template(object):
|
|||
|
||||
def start(self):
|
||||
return ''
|
||||
|
||||
|
||||
def end(self):
|
||||
result = ''
|
||||
while not self.loop:
|
||||
|
@ -327,9 +365,10 @@ class _rml_template(object):
|
|||
return result
|
||||
|
||||
class _rml_doc(object):
|
||||
def __init__(self, data):
|
||||
self.dom = xml.dom.minidom.parseString(data)
|
||||
self.filename = self.dom.documentElement.getAttribute('filename')
|
||||
def __init__(self, data, localcontext):
|
||||
self.dom = etree.XML(data)
|
||||
self.localcontext = localcontext
|
||||
self.filename = self.dom.get('filename')
|
||||
self.result = ''
|
||||
|
||||
def render(self, out):
|
||||
|
@ -341,28 +380,28 @@ class _rml_doc(object):
|
|||
p {margin:0px; font-size:12px;}
|
||||
td {font-size:14px;}
|
||||
'''
|
||||
style = self.dom.documentElement.getElementsByTagName('stylesheet')[0]
|
||||
s = _rml_stylesheet(style, self.dom)
|
||||
style = self.dom.findall('stylesheet')[0]
|
||||
s = _rml_stylesheet(self.localcontext, style, self.dom)
|
||||
self.result += s.render()
|
||||
self.result+='''
|
||||
</style>
|
||||
'''
|
||||
|
||||
|
||||
# f = _flowable(template, self.dom)
|
||||
list_story =[]
|
||||
storys= self.dom.documentElement.getElementsByTagName('story')
|
||||
for story in storys :
|
||||
template = _rml_template(self.dom.documentElement.getElementsByTagName('template')[0])
|
||||
f = _flowable(template, self.dom)
|
||||
for story in utils._child_get(self.dom, self, 'story'):
|
||||
template = _rml_template(self.dom.findall('template')[0], self.localcontext)
|
||||
f = _flowable(template, self.dom, localcontext = self.localcontext)
|
||||
story_text = f.render(story)
|
||||
list_story.append(story_text)
|
||||
del f
|
||||
if template.data:
|
||||
tag = '''<img src = '%s' width=80 height=72/>'''%(template.data)
|
||||
else:
|
||||
tag = ''
|
||||
self.result +='''
|
||||
<script type="text/javascript">
|
||||
|
||||
var indexer = 0;
|
||||
var aryTest = %s ;
|
||||
var aryTest = %s ;
|
||||
function nextData()
|
||||
{
|
||||
if(indexer < aryTest.length -1)
|
||||
|
@ -378,22 +417,23 @@ class _rml_doc(object):
|
|||
indexer -= 1;
|
||||
document.getElementById("tiny_data").innerHTML=aryTest[indexer];
|
||||
}
|
||||
}
|
||||
</script>
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
%s
|
||||
<div id="tiny_data">
|
||||
%s
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<input type="button" value="next" onclick="nextData();">
|
||||
<input type="button" value="prev" onclick="prevData();">
|
||||
|
||||
</body></html>'''%(list_story,list_story[0])
|
||||
|
||||
</body></html>'''%(list_story,tag,list_story[0])
|
||||
out.write( self.result)
|
||||
|
||||
def parseString(data, fout=None):
|
||||
r = _rml_doc(data)
|
||||
def parseString(data,localcontext = {}, fout=None):
|
||||
r = _rml_doc(data, localcontext)
|
||||
if fout:
|
||||
fp = file(fout,'wb')
|
||||
r.render(fp)
|
||||
|
@ -404,7 +444,7 @@ def parseString(data, fout=None):
|
|||
r.render(fp)
|
||||
return fp.getvalue()
|
||||
|
||||
def trml2pdf_help():
|
||||
def rml2html_help():
|
||||
print 'Usage: rml2html input.rml >output.html'
|
||||
print 'Render the standard input (RML) and output an HTML file'
|
||||
sys.exit(0)
|
||||
|
@ -412,7 +452,7 @@ def trml2pdf_help():
|
|||
if __name__=="__main__":
|
||||
if len(sys.argv)>1:
|
||||
if sys.argv[1]=='--help':
|
||||
trml2pdf_help()
|
||||
rml2html_help()
|
||||
print parseString(file(sys.argv[1], 'r').read()),
|
||||
else:
|
||||
print 'Usage: trml2pdf input.rml >output.pdf'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -24,16 +24,9 @@ import re
|
|||
import reportlab
|
||||
import reportlab.lib.units
|
||||
|
||||
def text_get(node):
|
||||
rc = ''
|
||||
for node in node.childNodes:
|
||||
if node.nodeType == node.TEXT_NODE:
|
||||
rc = rc + node.data
|
||||
return rc
|
||||
|
||||
units = [
|
||||
(re.compile('^(-?[0-9\.]+)\s*in$'), reportlab.lib.units.inch),
|
||||
(re.compile('^(-?[0-9\.]+)\s*cm$'), reportlab.lib.units.cm),
|
||||
(re.compile('^(-?[0-9\.]+)\s*cm$'), reportlab.lib.units.cm),
|
||||
(re.compile('^(-?[0-9\.]+)\s*mm$'), reportlab.lib.units.mm),
|
||||
(re.compile('^(-?[0-9\.]+)\s*px$'), 0.7),
|
||||
(re.compile('^(-?[0-9\.]+)\s*$'), 1)
|
||||
|
@ -48,9 +41,9 @@ def unit_get(size):
|
|||
return False
|
||||
|
||||
def tuple_int_get(node, attr_name, default=None):
|
||||
if not node.hasAttribute(attr_name):
|
||||
if not node.get(attr_name):
|
||||
return default
|
||||
res = [int(x) for x in node.getAttribute(attr_name).split(',')]
|
||||
res = [int(x) for x in node.get(attr_name).split(',')]
|
||||
return res
|
||||
|
||||
def bool_get(value):
|
||||
|
@ -59,16 +52,16 @@ def bool_get(value):
|
|||
def attr_get(node, attrs, dict={}):
|
||||
res = {}
|
||||
for name in attrs:
|
||||
if node.hasAttribute(name):
|
||||
res[name] = unit_get(node.getAttribute(name))
|
||||
if node.get(name):
|
||||
res[name] = unit_get(node.get(name))
|
||||
for key in dict:
|
||||
if node.hasAttribute(key):
|
||||
if node.get(key):
|
||||
if dict[key]=='str':
|
||||
res[key] = str(node.getAttribute(key))
|
||||
res[key] = str(node.get(key))
|
||||
elif dict[key]=='bool':
|
||||
res[key] = bool_get(node.getAttribute(key))
|
||||
res[key] = bool_get(node.get(key))
|
||||
elif dict[key]=='int':
|
||||
res[key] = int(node.getAttribute(key))
|
||||
res[key] = int(node.get(key))
|
||||
return res
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -20,24 +20,5 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
# trml2pdf - An RML to PDF converter
|
||||
# Copyright (C) 2003, Fabien Pinckaers, UCL, FSA
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
from trml2pdf import parseString
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
from trml2pdf import parseString, parseNode
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -29,6 +29,8 @@ regex_t = re.compile('\(([0-9\.]*),([0-9\.]*),([0-9\.]*)\)')
|
|||
regex_h = re.compile('#([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])')
|
||||
|
||||
def get(col_str):
|
||||
if col_str == None:
|
||||
col_str = ''
|
||||
global allcols
|
||||
if col_str in allcols.keys():
|
||||
return allcols[col_str]
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||
# $Id$
|
||||
#
|
||||
|
@ -39,12 +39,68 @@
|
|||
|
||||
import re
|
||||
import reportlab
|
||||
from lxml import etree
|
||||
|
||||
_regex = re.compile('\[\[(.+?)\]\]')
|
||||
|
||||
def _child_get(node, self=None, tagname=None):
|
||||
for n in node:
|
||||
if self and self.localcontext and n.get('rml_loop', False):
|
||||
oldctx = self.localcontext
|
||||
for ctx in eval(n.get('rml_loop'),{}, self.localcontext):
|
||||
self.localcontext.update(ctx)
|
||||
if (tagname is None) or (n.tag==tagname):
|
||||
if n.get('rml_except', False):
|
||||
try:
|
||||
eval(n.get('rml_except'), {}, self.localcontext)
|
||||
except:
|
||||
continue
|
||||
if n.get('rml_tag'):
|
||||
try:
|
||||
(tag,attr) = eval(n.get('rml_tag'),{}, self.localcontext)
|
||||
n2 = copy.copy(n)
|
||||
n2.tag = tag
|
||||
n2.attrib.update(attr)
|
||||
yield n2
|
||||
except:
|
||||
yield n
|
||||
else:
|
||||
yield n
|
||||
self.localcontext = oldctx
|
||||
continue
|
||||
if self and self.localcontext and n.get('rml_except', False):
|
||||
try:
|
||||
eval(n.get('rml_except'), {}, self.localcontext)
|
||||
except:
|
||||
continue
|
||||
if (tagname is None) or (n.tag==tagname):
|
||||
yield n
|
||||
|
||||
def _process_text(self, txt):
|
||||
if not self.localcontext:
|
||||
return txt
|
||||
if not txt:
|
||||
return ''
|
||||
result = ''
|
||||
sps = _regex.split(txt)
|
||||
while sps:
|
||||
# This is a simple text to translate
|
||||
result += self.localcontext.get('translate', lambda x:x)(sps.pop(0))
|
||||
if sps:
|
||||
try:
|
||||
txt2 = eval(sps.pop(0),self.localcontext)
|
||||
except:
|
||||
txt2 = ''
|
||||
if type(txt2) == type(0) or type(txt2) == type(0.0):
|
||||
txt2 = str(txt2)
|
||||
if type(txt2)==type('') or type(txt2)==type(u''):
|
||||
result += txt2
|
||||
return result
|
||||
|
||||
def text_get(node):
|
||||
rc = ''
|
||||
for node in node.childNodes:
|
||||
if node.nodeType == node.TEXT_NODE:
|
||||
rc = rc + node.data
|
||||
for node in node.getchildren():
|
||||
rc = rc + node.text
|
||||
return rc
|
||||
|
||||
units = [
|
||||
|
@ -56,16 +112,17 @@ units = [
|
|||
|
||||
def unit_get(size):
|
||||
global units
|
||||
for unit in units:
|
||||
res = unit[0].search(size, 0)
|
||||
if res:
|
||||
return unit[1]*float(res.group(1))
|
||||
if size:
|
||||
for unit in units:
|
||||
res = unit[0].search(size, 0)
|
||||
if res:
|
||||
return unit[1]*float(res.group(1))
|
||||
return False
|
||||
|
||||
def tuple_int_get(node, attr_name, default=None):
|
||||
if not node.hasAttribute(attr_name):
|
||||
if not node.get(attr_name):
|
||||
return default
|
||||
res = [int(x) for x in node.getAttribute(attr_name).split(',')]
|
||||
res = [int(x) for x in node.get(attr_name).split(',')]
|
||||
return res
|
||||
|
||||
def bool_get(value):
|
||||
|
@ -74,19 +131,18 @@ def bool_get(value):
|
|||
def attr_get(node, attrs, dict={}):
|
||||
res = {}
|
||||
for name in attrs:
|
||||
if node.hasAttribute(name):
|
||||
res[name] = unit_get(node.getAttribute(name))
|
||||
if node.get(name):
|
||||
res[name] = unit_get(node.get(name))
|
||||
for key in dict:
|
||||
if node.hasAttribute(key):
|
||||
if node.get(key):
|
||||
if dict[key]=='str':
|
||||
res[key] = str(node.getAttribute(key))
|
||||
res[key] = str(node.get(key))
|
||||
elif dict[key]=='bool':
|
||||
res[key] = bool_get(node.getAttribute(key))
|
||||
res[key] = bool_get(node.get(key))
|
||||
elif dict[key]=='int':
|
||||
res[key] = int(node.getAttribute(key))
|
||||
res[key] = int(node.get(key))
|
||||
elif dict[key]=='unit':
|
||||
res[key] = unit_get(node.getAttribute(key))
|
||||
res[key] = unit_get(node.get(key))
|
||||
return res
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -20,23 +20,26 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from interface import report_rml
|
||||
from lxml import etree
|
||||
import StringIO
|
||||
import cStringIO
|
||||
import base64
|
||||
import copy
|
||||
import ir
|
||||
import locale
|
||||
import mx.DateTime
|
||||
import netsvc
|
||||
import os
|
||||
import osv
|
||||
import pooler
|
||||
import re
|
||||
import time
|
||||
from interface import report_rml
|
||||
import preprocess
|
||||
import ir
|
||||
import netsvc
|
||||
import osv
|
||||
import pooler
|
||||
import tools
|
||||
import warnings
|
||||
import xml.dom.minidom
|
||||
import zipfile
|
||||
import common
|
||||
|
||||
DT_FORMAT = '%Y-%m-%d'
|
||||
DHM_FORMAT = '%Y-%m-%d %H:%M:%S'
|
||||
|
@ -58,15 +61,21 @@ sxw_parents = {
|
|||
'section': 0,
|
||||
}
|
||||
|
||||
html_parents = {
|
||||
'tr' : 1,
|
||||
'body' : 0,
|
||||
'div' : 0
|
||||
}
|
||||
sxw_tag = "p"
|
||||
|
||||
rml2sxw = {
|
||||
'para': 'p',
|
||||
}
|
||||
|
||||
|
||||
|
||||
class _format(object):
|
||||
def set_value(self, cr, uid, name, object, field, lang_obj):
|
||||
#super(_date_format, self).__init__(self)
|
||||
self.object = object
|
||||
self._field = field
|
||||
self.name = name
|
||||
|
@ -82,10 +91,7 @@ class _float_format(float, _format):
|
|||
digits = 2
|
||||
if hasattr(self,'_field') and hasattr(self._field, 'digits') and self._field.digits:
|
||||
digits = self._field.digits[1]
|
||||
if self.lang_obj:
|
||||
return self.lang_obj.format('%.' + str(digits) + 'f', self.name, True)
|
||||
else:
|
||||
return str(self.name)
|
||||
return self.lang_obj.format('%.' + str(digits) + 'f', self.name, True)
|
||||
return self.val
|
||||
|
||||
class _int_format(int, _format):
|
||||
|
@ -95,13 +101,9 @@ class _int_format(int, _format):
|
|||
|
||||
def __str__(self):
|
||||
if hasattr(self,'lang_obj'):
|
||||
if self.lang_obj:
|
||||
return self.lang_obj.format('%.d', self.name, True)
|
||||
else:
|
||||
return str(self.name)
|
||||
return self.lang_obj.format('%.d', self.name, True)
|
||||
return self.val
|
||||
|
||||
|
||||
class _date_format(str, _format):
|
||||
def __init__(self,value):
|
||||
super(_date_format, self).__init__()
|
||||
|
@ -111,10 +113,7 @@ class _date_format(str, _format):
|
|||
if self.val:
|
||||
if hasattr(self,'name') and (self.name):
|
||||
date = mx.DateTime.strptime(self.name,DT_FORMAT)
|
||||
if self.lang_obj:
|
||||
return date.strftime(self.lang_obj.date_format)
|
||||
else:
|
||||
return date.strftime('%m/%d/%Y')
|
||||
return date.strftime(self.lang_obj.date_format)
|
||||
return self.val
|
||||
|
||||
class _dttime_format(str, _format):
|
||||
|
@ -126,10 +125,7 @@ class _dttime_format(str, _format):
|
|||
if self.val:
|
||||
if hasattr(self,'name') and self.name:
|
||||
datetime = mx.DateTime.strptime(self.name,DHM_FORMAT)
|
||||
if self.lang_obj:
|
||||
return datetime.strftime(self.lang_obj.date_format+ " " + self.lang_obj.time_format)
|
||||
else:
|
||||
return datetime.strftime('%m/%d/%Y %H:%M:%S')
|
||||
return datetime.strftime(self.lang_obj.date_format+ " " + self.lang_obj.time_format)
|
||||
return self.val
|
||||
|
||||
|
||||
|
@ -155,31 +151,6 @@ class browse_record_list(list):
|
|||
def __str__(self):
|
||||
return "browse_record_list("+str(len(self))+")"
|
||||
|
||||
def repeatIn(self, name):
|
||||
warnings.warn('Use repeatIn(object_list, \'variable\')', DeprecationWarning)
|
||||
node = self.context['_node']
|
||||
parents = self.context.get('parents', rml_parents)
|
||||
node.data = ''
|
||||
while True:
|
||||
if not node.parentNode:
|
||||
break
|
||||
node = node.parentNode
|
||||
if node.nodeType == node.ELEMENT_NODE and node.localName in parents:
|
||||
break
|
||||
parent_node = node
|
||||
if not len(self):
|
||||
return None
|
||||
nodes = [(0,node)]
|
||||
for i in range(1,len(self)):
|
||||
newnode = parent_node.cloneNode(1)
|
||||
n = parent_node.parentNode
|
||||
n.insertBefore(newnode, parent_node)
|
||||
nodes.append((i,newnode))
|
||||
for i,node in nodes:
|
||||
self.context[name] = self[i]
|
||||
self.context['_self']._parse_node(node)
|
||||
return None
|
||||
|
||||
class rml_parse(object):
|
||||
def __init__(self, cr, uid, name, parents=rml_parents, tag=rml_tag, context=None):
|
||||
if not context:
|
||||
|
@ -187,7 +158,7 @@ class rml_parse(object):
|
|||
self.cr = cr
|
||||
self.uid = uid
|
||||
self.pool = pooler.get_pool(cr.dbname)
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, fields_process=_fields_process)
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid)
|
||||
self.localcontext = {
|
||||
'user': user,
|
||||
'company': user.company_id,
|
||||
|
@ -199,69 +170,57 @@ class rml_parse(object):
|
|||
'formatLang': self.formatLang,
|
||||
'logo' : user.company_id.logo,
|
||||
'lang' : user.company_id.partner_id.lang,
|
||||
'translate' : self._translate,
|
||||
'setHtmlImage' : self.set_html_image
|
||||
}
|
||||
self.localcontext.update(context)
|
||||
self.rml_header = user.company_id.rml_header
|
||||
self.rml_header2 = user.company_id.rml_header2
|
||||
self.logo = user.company_id.logo
|
||||
self.name = name
|
||||
self._regex = re.compile('\[\[(.+?)\]\]')
|
||||
self._transl_regex = re.compile('(\[\[.+?\]\])')
|
||||
self._node = None
|
||||
self.parents = parents
|
||||
self.tag = tag
|
||||
self._lang_cache = {}
|
||||
# self.already = {}
|
||||
self.lang_dict = {}
|
||||
self.default_lang = {}
|
||||
self.lang_dict_called = False
|
||||
self._transl_regex = re.compile('(\[\[.+?\]\])')
|
||||
|
||||
def setTag(self, oldtag, newtag, attrs=None):
|
||||
if not attrs:
|
||||
attrs={}
|
||||
node = self._find_parent(self._node, [oldtag])
|
||||
if node:
|
||||
node.tagName = newtag
|
||||
for key, val in attrs.items():
|
||||
node.setAttribute(key, val)
|
||||
return None
|
||||
return newtag, attrs
|
||||
|
||||
def format(self, text, oldtag=None):
|
||||
if not oldtag:
|
||||
oldtag = self.tag
|
||||
self._node.data = ''
|
||||
node = self._find_parent(self._node, [oldtag])
|
||||
ns = None
|
||||
if node:
|
||||
pp = node.parentNode
|
||||
ns = node.nextSibling
|
||||
pp.removeChild(node)
|
||||
self._node = pp
|
||||
|
||||
lst = tools.ustr(text).split('\n')
|
||||
if not (text and lst):
|
||||
return None
|
||||
nodes = []
|
||||
for i in range(len(lst)):
|
||||
newnode = node.cloneNode(1)
|
||||
newnode.tagName=rml_tag
|
||||
newnode.childNodes[0].data = lst[i]
|
||||
if ns:
|
||||
pp.insertBefore(newnode, ns)
|
||||
else:
|
||||
pp.appendChild(newnode)
|
||||
nodes.append((i, newnode))
|
||||
return text
|
||||
|
||||
def removeParentNode(self, tag=None):
|
||||
if not tag:
|
||||
tag = self.tag
|
||||
if self.tag == sxw_tag and rml2sxw.get(tag, False):
|
||||
tag = rml2sxw[tag]
|
||||
node = self._find_parent(self._node, [tag])
|
||||
if node:
|
||||
parentNode = node.parentNode
|
||||
parentNode.removeChild(node)
|
||||
self._node = parentNode
|
||||
raise Exception('Skip')
|
||||
|
||||
def set_html_image(self,attach_id):
|
||||
try :
|
||||
att_id = int(attach_id)
|
||||
print att_id
|
||||
attachment = self.pool.get('ir.attachment').browse(self.cr,self.uid,att_id)
|
||||
print attachment
|
||||
print attachment.datas
|
||||
return attachment.datas
|
||||
except :
|
||||
return ''
|
||||
|
||||
def setLang(self, lang):
|
||||
if not lang or self.default_lang.has_key(lang):
|
||||
if not lang:
|
||||
key = 'en_US'
|
||||
self.lang_dict_called = False
|
||||
self.localcontext['lang'] = lang
|
||||
elif self.default_lang.has_key(lang):
|
||||
key = lang
|
||||
if self.default_lang.get(key,False):
|
||||
self.lang_dict = self.default_lang.get(key,False).copy()
|
||||
self.lang_dict_called = True
|
||||
return True
|
||||
self.localcontext['lang'] = lang
|
||||
self.lang_dict_called = False
|
||||
for obj in self.objects:
|
||||
obj._context['lang'] = lang
|
||||
for table in obj._cache:
|
||||
|
@ -275,232 +234,102 @@ class rml_parse(object):
|
|||
else:
|
||||
obj._cache[table][id] = {'id': id}
|
||||
|
||||
def _get_lang_dict(self):
|
||||
pool_lang = self.pool.get('res.lang')
|
||||
lang = self.localcontext.get('lang', 'en_US') or 'en_US'
|
||||
lang_ids = pool_lang.search(self.cr,self.uid,[('code','=',lang)])[0]
|
||||
lang_obj = pool_lang.browse(self.cr,self.uid,lang_ids)
|
||||
self.lang_dict.update({'lang_obj':lang_obj,'date_format':lang_obj.date_format,'time_format':lang_obj.time_format})
|
||||
self.default_lang[lang] = self.lang_dict.copy()
|
||||
return True
|
||||
|
||||
def formatLang(self, value, digits=2, date=False,date_time=False, grouping=True, monetary=False, currency=None):
|
||||
if isinstance(value, (str, unicode)) and not value:
|
||||
return ''
|
||||
pool_lang = self.pool.get('res.lang')
|
||||
lang = self.localcontext.get('lang', 'en_US') or 'en_US'
|
||||
lids = pool_lang.search(self.cr,self.uid,[('code','=',lang)])
|
||||
if not lids: return str(value)
|
||||
lang_obj = pool_lang.browse(self.cr,self.uid,lids[0])
|
||||
if not self.lang_dict_called:
|
||||
self._get_lang_dict()
|
||||
self.lang_dict_called = True
|
||||
|
||||
if date or date_time:
|
||||
if not str(value):
|
||||
return ''
|
||||
date_format = lang_obj.date_format
|
||||
date_format = self.lang_dict['date_format']
|
||||
parse_format = DT_FORMAT
|
||||
if date_time:
|
||||
date_format = lang_obj.date_format + " " + lang_obj.time_format
|
||||
parse_format = date_format
|
||||
date_format = date_format + " " + self.lang_dict['time_format']
|
||||
parse_format = DHM_FORMAT
|
||||
|
||||
# filtering time.strftime('%Y-%m-%d')
|
||||
if type(value) == type(''):
|
||||
parse_format = DHM_FORMAT
|
||||
if (not date_time):
|
||||
return value
|
||||
return str(value)
|
||||
|
||||
if not isinstance(value, time.struct_time):
|
||||
# assume string, parse it
|
||||
# if len(str(value)) == 10:
|
||||
# # length of date like 2001-01-01 is ten
|
||||
# # assume format '%Y-%m-%d'
|
||||
# date = mx.DateTime.strptime(value,DT_FORMAT)
|
||||
# else:
|
||||
# # assume format '%Y-%m-%d %H:%M:%S'
|
||||
# value = str(value)[:19]
|
||||
# date = mx.DateTime.strptime(str(value),DHM_FORMAT)
|
||||
date = mx.DateTime.strptime(str(value),parse_format)
|
||||
try:
|
||||
date = mx.DateTime.strptime(str(value),parse_format)
|
||||
except:# sometimes it takes converted values into value, so we dont need conversion.
|
||||
return str(value)
|
||||
else:
|
||||
date = mx.DateTime.DateTime(*(value.timetuple()[:6]))
|
||||
return date.strftime(date_format)
|
||||
return lang_obj.format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
|
||||
return self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
|
||||
|
||||
def repeatIn(self, lst, name, nodes_parent=False):
|
||||
self._node.data = ''
|
||||
node = self._find_parent(self._node, nodes_parent or self.parents)
|
||||
def repeatIn(self, lst, name,nodes_parent=False):
|
||||
ret_lst = []
|
||||
for id in lst:
|
||||
ret_lst.append({name:id})
|
||||
return ret_lst
|
||||
|
||||
pp = node.parentNode
|
||||
ns = node.nextSibling
|
||||
pp.removeChild(node)
|
||||
self._node = pp
|
||||
|
||||
if not len(lst):
|
||||
return None
|
||||
nodes = []
|
||||
for i in range(len(lst)):
|
||||
newnode = node.cloneNode(1)
|
||||
if ns:
|
||||
pp.insertBefore(newnode, ns)
|
||||
else:
|
||||
pp.appendChild(newnode)
|
||||
nodes.append((i, newnode))
|
||||
for i, node in nodes:
|
||||
self.node_context[node] = {name: lst[i]}
|
||||
return None
|
||||
|
||||
def _eval(self, expr):
|
||||
try:
|
||||
res = eval(expr, self.localcontext)
|
||||
if (res is None) or (res=='') or (res is False):
|
||||
res = ''
|
||||
except Exception,e:
|
||||
import traceback, sys
|
||||
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
|
||||
netsvc.Logger().notifyChannel('report', netsvc.LOG_ERROR,
|
||||
'report %s:\n%s\n%s\nexpr: %s' % (self.name, tb_s, str(e),
|
||||
expr.encode('utf-8')))
|
||||
res = ''
|
||||
return res
|
||||
|
||||
def _find_parent(self, node, parents):
|
||||
while True:
|
||||
if not node.parentNode:
|
||||
return False
|
||||
node = node.parentNode
|
||||
if node.nodeType == node.ELEMENT_NODE and node.localName in parents:
|
||||
break
|
||||
return node
|
||||
|
||||
def _parse_text(self, text, level=None):
|
||||
if not level:
|
||||
level=[]
|
||||
res = self._regex.findall(text)
|
||||
todo = []
|
||||
# translate the text
|
||||
# the "split [[]] if not match [[]]" is not very nice, but I
|
||||
# don't see how I could do it better...
|
||||
# what I'd like to do is a re.sub(NOT pattern, func, string)
|
||||
# but I don't know how to do that...
|
||||
# translate the RML file
|
||||
if 'lang' in self.localcontext:
|
||||
lang = self.localcontext['lang']
|
||||
if lang and text and not text.isspace():
|
||||
transl_obj = self.pool.get('ir.translation')
|
||||
piece_list = self._transl_regex.split(text)
|
||||
for pn in range(len(piece_list)):
|
||||
if not self._transl_regex.match(piece_list[pn]):
|
||||
source_string = piece_list[pn].replace('\n', ' ').strip()
|
||||
if len(source_string):
|
||||
translated_string = transl_obj._get_source(self.cr, self.uid, self.name, 'rml', lang, source_string)
|
||||
if translated_string:
|
||||
piece_list[pn] = piece_list[pn].replace(source_string, translated_string)
|
||||
text = ''.join(piece_list)
|
||||
for key in res:
|
||||
newtext = self._eval(key)
|
||||
for i in range(len(level)):
|
||||
if isinstance(newtext, list):
|
||||
newtext = newtext[level[i]]
|
||||
if isinstance(newtext, list):
|
||||
todo.append((key, newtext))
|
||||
else:
|
||||
# if there are two [[]] blocks the same, it will replace both
|
||||
# but it's ok because it should evaluate to the same thing
|
||||
# anyway
|
||||
newtext = tools.ustr(newtext)
|
||||
text = text.replace('[['+key+']]', newtext)
|
||||
self._node.data = text
|
||||
if len(todo):
|
||||
for key, newtext in todo:
|
||||
parent_node = self._find_parent(self._node, parents)
|
||||
assert parents.get(parent_node.localName, False), 'No parent node found !'
|
||||
nodes = [parent_node]
|
||||
for i in range(len(newtext) - 1):
|
||||
newnode = parent_node.cloneNode(1)
|
||||
if parents.get(parent_node.localName, False):
|
||||
n = parent_node.parentNode
|
||||
parent_node.parentNode.insertAfter(newnode, parent_node)
|
||||
nodes.append(newnode)
|
||||
return False
|
||||
def _translate(self,text):
|
||||
lang = self.localcontext['lang']
|
||||
if lang and text and not text.isspace():
|
||||
transl_obj = self.pool.get('ir.translation')
|
||||
piece_list = self._transl_regex.split(text)
|
||||
for pn in range(len(piece_list)):
|
||||
if not self._transl_regex.match(piece_list[pn]):
|
||||
source_string = piece_list[pn].replace('\n', ' ').strip()
|
||||
if len(source_string):
|
||||
translated_string = transl_obj._get_source(self.cr, self.uid, self.name, 'rml', lang, source_string)
|
||||
if translated_string:
|
||||
piece_list[pn] = piece_list[pn].replace(source_string, translated_string)
|
||||
text = ''.join(piece_list)
|
||||
return text
|
||||
|
||||
def _parse_node(self):
|
||||
level = []
|
||||
while True:
|
||||
if self._node.nodeType==self._node.ELEMENT_NODE:
|
||||
if self._node.hasAttribute('expr'):
|
||||
newattrs = self._eval(self._node.getAttribute('expr'))
|
||||
for key,val in newattrs.items():
|
||||
self._node.setAttribute(key,val)
|
||||
|
||||
if self._node.hasChildNodes():
|
||||
self._node = self._node.firstChild
|
||||
elif self._node.nextSibling:
|
||||
self._node = self._node.nextSibling
|
||||
else:
|
||||
while self._node and not self._node.nextSibling:
|
||||
self._node = self._node.parentNode
|
||||
if not self._node:
|
||||
break
|
||||
self._node = self._node.nextSibling
|
||||
if self._node in self.node_context:
|
||||
self.localcontext.update(self.node_context[self._node])
|
||||
if self._node.nodeType in (self._node.CDATA_SECTION_NODE, self._node.TEXT_NODE):
|
||||
# if self._node in self.already:
|
||||
# self.already[self._node] += 1
|
||||
# print "second pass!", self.already[self._node], '---%s---' % self._node.data
|
||||
# else:
|
||||
# self.already[self._node] = 0
|
||||
self._parse_text(self._node.data, level)
|
||||
return True
|
||||
|
||||
def _find_node(self, node, localname):
|
||||
if node.localName==localname:
|
||||
return node
|
||||
for tag in node.childNodes:
|
||||
if tag.nodeType==tag.ELEMENT_NODE:
|
||||
found = self._find_node(tag, localname)
|
||||
if found:
|
||||
return found
|
||||
return False
|
||||
|
||||
def _add_header(self, node, header=1):
|
||||
def _add_header(self, rml_dom, header=1):
|
||||
if header==2:
|
||||
rml_head = self.rml_header2
|
||||
else:
|
||||
rml_head = self.rml_header
|
||||
|
||||
# Refactor this patch, to use the minidom interface
|
||||
if self.logo and (rml_head.find('company.logo')<0 or rml_head.find('<image')<0) and rml_head.find('<!--image')<0:
|
||||
rml_head = rml_head.replace('<pageGraphics>','''<pageGraphics> <image x="10" y="26cm" height="70" width="90" >[[company.logo]] </image> ''')
|
||||
if not self.logo and rml_head.find('company.logo')>=0:
|
||||
rml_head = rml_head.replace('<image','<!--image')
|
||||
rml_head = rml_head.replace('</image>','</image-->')
|
||||
|
||||
head_dom = xml.dom.minidom.parseString(rml_head.encode('utf-8'))
|
||||
#for frame in head_dom.getElementsByTagName('frame'):
|
||||
# frame.parentNode.removeChild(frame)
|
||||
node2 = head_dom.documentElement
|
||||
for tag in node2.childNodes:
|
||||
if tag.nodeType==tag.ELEMENT_NODE:
|
||||
found = self._find_node(node, tag.localName)
|
||||
# rml_frames = found.getElementsByTagName('frame')
|
||||
if found:
|
||||
if tag.hasAttribute('position') and (tag.getAttribute('position')=='inside'):
|
||||
found.appendChild(tag)
|
||||
else:
|
||||
found.parentNode.replaceChild(tag, found)
|
||||
# for frame in rml_frames:
|
||||
# tag.appendChild(frame)
|
||||
head_dom = etree.XML(rml_head)
|
||||
for tag in head_dom.getchildren():
|
||||
found = rml_dom.find('.//'+tag.tag)
|
||||
if found:
|
||||
if tag.get('position'):
|
||||
found.append(tag)
|
||||
else :
|
||||
found.getparent().replace(found,tag)
|
||||
return True
|
||||
|
||||
def preprocess(self, objects, data, ids):
|
||||
def set_context(self, objects, data, ids, report_type = None):
|
||||
self.localcontext['data'] = data
|
||||
self.localcontext['objects'] = objects
|
||||
self.datas = data
|
||||
self.ids = ids
|
||||
self.objects = objects
|
||||
if report_type:
|
||||
if report_type=='odt' :
|
||||
self.localcontext.update({'name_space' :common.odt_namespace})
|
||||
else:
|
||||
self.localcontext.update({'name_space' :common.sxw_namespace})
|
||||
|
||||
def _parse(self, rml_dom, objects, data, header=0):
|
||||
self.node_context = {}
|
||||
self.dom = rml_dom
|
||||
self._node = self.dom.documentElement
|
||||
if header:
|
||||
self._add_header(self._node, header)
|
||||
self._parse_node()
|
||||
res = self.dom.documentElement.toxml('utf-8')
|
||||
return res
|
||||
|
||||
class report_sxw(report_rml):
|
||||
def __init__(self, name, table, rml, parser=rml_parse, header=True, store=False):
|
||||
class report_sxw(report_rml, preprocess.report):
|
||||
def __init__(self, name, table, rml=False, parser=rml_parse, header=True, store=False):
|
||||
report_rml.__init__(self, name, table, rml, '')
|
||||
self.name = name
|
||||
self.parser = parser
|
||||
|
@ -509,30 +338,17 @@ class report_sxw(report_rml):
|
|||
|
||||
def getObjects(self, cr, uid, ids, context):
|
||||
table_obj = pooler.get_pool(cr.dbname).get(self.table)
|
||||
return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context,
|
||||
fields_process=_fields_process)
|
||||
return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context, fields_process=_fields_process)
|
||||
|
||||
def create(self, cr, uid, ids, data, context=None):
|
||||
if not context:
|
||||
context={}
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
ir_obj = pool.get('ir.actions.report.xml')
|
||||
report_xml_ids = ir_obj.search(cr, uid,
|
||||
[('report_name', '=', self.name[7:])], context=context)
|
||||
|
||||
if report_xml_ids:
|
||||
report_xml = ir_obj.browse(cr, uid, report_xml_ids[0],
|
||||
context=context)
|
||||
attach = report_xml.attachment
|
||||
report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context)
|
||||
else:
|
||||
ir_menu_report_obj = pool.get('ir.ui.menu')
|
||||
report_menu_ids = ir_menu_report_obj.search(cr, uid,
|
||||
[('id', 'in', ids)], context=context)
|
||||
title = ''
|
||||
if report_menu_ids:
|
||||
report_name = ir_menu_report_obj.browse(cr, uid, report_menu_ids[0],
|
||||
context=context)
|
||||
title = report_name.name
|
||||
rml = tools.file_open(self.tmpl, subdir=None).read()
|
||||
report_type= data.get('report_type', 'pdf')
|
||||
class a(object):
|
||||
|
@ -540,8 +356,28 @@ class report_sxw(report_rml):
|
|||
for key,arg in argv.items():
|
||||
setattr(self, key, arg)
|
||||
report_xml = a(title=title, report_type=report_type, report_rml_content=rml, name=title, attachment=False, header=self.header)
|
||||
attach = False
|
||||
report_type = report_xml.report_type
|
||||
if report_type in ['sxw','odt']:
|
||||
fnct = self.create_source_odt
|
||||
elif report_type in ['pdf','raw','html']:
|
||||
fnct = self.create_source_pdf
|
||||
elif report_type=='html2html':
|
||||
fnct = self.create_source_html2html
|
||||
else:
|
||||
raise 'Unknown Report Type'
|
||||
return fnct(cr, uid, ids, data, report_xml, context)
|
||||
|
||||
def create_source_odt(self, cr, uid, ids, data, report_xml, context=None):
|
||||
return self.create_single_odt(cr, uid, ids, data, report_xml, context or {})
|
||||
|
||||
def create_source_html2html(self, cr, uid, ids, data, report_xml, context=None):
|
||||
return self.create_single_html2html(cr, uid, ids, data, report_xml, context or {})
|
||||
|
||||
def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None):
|
||||
if not context:
|
||||
context={}
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
attach = report_xml.attachment
|
||||
if attach:
|
||||
objs = self.getObjects(cr, uid, ids, context)
|
||||
results = []
|
||||
|
@ -557,7 +393,7 @@ class report_sxw(report_rml):
|
|||
d = base64.decodestring(brow_rec.datas)
|
||||
results.append((d,'pdf'))
|
||||
continue
|
||||
result = self.create_single(cr, uid, [obj.id], data, report_xml, context)
|
||||
result = self.create_single_pdf(cr, uid, [obj.id], data, report_xml, context)
|
||||
try:
|
||||
if aname:
|
||||
name = aname+'.'+result[1]
|
||||
|
@ -578,7 +414,6 @@ class report_sxw(report_rml):
|
|||
if results:
|
||||
if results[0][1]=='pdf':
|
||||
from pyPdf import PdfFileWriter, PdfFileReader
|
||||
import cStringIO
|
||||
output = PdfFileWriter()
|
||||
for r in results:
|
||||
reader = PdfFileReader(cStringIO.StringIO(r[0]))
|
||||
|
@ -587,95 +422,102 @@ class report_sxw(report_rml):
|
|||
s = cStringIO.StringIO()
|
||||
output.write(s)
|
||||
return s.getvalue(), results[0][1]
|
||||
return self.create_single(cr, uid, ids, data, report_xml, context)
|
||||
return self.create_single_pdf(cr, uid, ids, data, report_xml, context)
|
||||
|
||||
def create_single(self, cr, uid, ids, data, report_xml, context={}):
|
||||
def create_single_pdf(self, cr, uid, ids, data, report_xml, context={}):
|
||||
logo = None
|
||||
context = context.copy()
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
want_header = self.header
|
||||
title = report_xml.name
|
||||
attach = report_xml.attachment
|
||||
report_type = report_xml.report_type
|
||||
want_header = report_xml.header
|
||||
rml = report_xml.report_rml_content
|
||||
rml_parser = self.parser(cr, uid, self.name2, context)
|
||||
objs = self.getObjects(cr, uid, ids, context)
|
||||
rml_parser.set_context(objs, data, ids, report_xml.report_type)
|
||||
processed_rml = self.preprocess_rml(etree.XML(rml),report_xml.report_type)
|
||||
if report_xml.header:
|
||||
rml_parser._add_header(processed_rml)
|
||||
if rml_parser.logo:
|
||||
logo = base64.decodestring(rml_parser.logo)
|
||||
create_doc = self.generators[report_xml.report_type]
|
||||
pdf = create_doc(etree.tostring(processed_rml),rml_parser.localcontext,logo,title.encode('utf8'))
|
||||
return (pdf, report_xml.report_type)
|
||||
|
||||
if report_type in ['sxw','odt']:
|
||||
context['parents'] = sxw_parents
|
||||
sxw_io = StringIO.StringIO(report_xml.report_sxw_content)
|
||||
sxw_z = zipfile.ZipFile(sxw_io, mode='r')
|
||||
rml = sxw_z.read('content.xml')
|
||||
meta = sxw_z.read('meta.xml')
|
||||
sxw_z.close()
|
||||
def create_single_odt(self, cr, uid, ids, data, report_xml, context={}):
|
||||
context = context.copy()
|
||||
report_type = report_xml.report_type
|
||||
context['parents'] = sxw_parents
|
||||
sxw_io = StringIO.StringIO(report_xml.report_sxw_content)
|
||||
sxw_z = zipfile.ZipFile(sxw_io, mode='r')
|
||||
rml = sxw_z.read('content.xml')
|
||||
meta = sxw_z.read('meta.xml')
|
||||
sxw_z.close()
|
||||
|
||||
rml_parser = self.parser(cr, uid, self.name2, context)
|
||||
rml_parser.parents = sxw_parents
|
||||
rml_parser.tag = sxw_tag
|
||||
objs = self.getObjects(cr, uid, ids, context)
|
||||
rml_parser.set_context(objs, data, ids,report_xml.report_type)
|
||||
|
||||
rml_dom_meta = node = etree.XML(meta)
|
||||
elements = node.findall(rml_parser.localcontext['name_space']["meta"]+"user-defined")
|
||||
for pe in elements:
|
||||
if pe.get(rml_parser.localcontext['name_space']["meta"]+"name"):
|
||||
if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 3":
|
||||
pe.getchildren()[0].text=data['id']
|
||||
if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 4":
|
||||
pe.getchildren()[0].text=data['model']
|
||||
meta = etree.tostring(rml_dom_meta)
|
||||
|
||||
rml_dom = etree.XML(rml)
|
||||
rml_dom = self.preprocess_rml(rml_dom,report_type)
|
||||
create_doc = self.generators[report_type]
|
||||
odt = etree.tostring(create_doc(rml_dom, rml_parser.localcontext))
|
||||
|
||||
sxw_z = zipfile.ZipFile(sxw_io, mode='a')
|
||||
sxw_z.writestr('content.xml', "<?xml version='1.0' encoding='UTF-8'?>" + \
|
||||
odt)
|
||||
sxw_z.writestr('meta.xml', "<?xml version='1.0' encoding='UTF-8'?>" + \
|
||||
meta)
|
||||
|
||||
if report_xml.header:
|
||||
#Add corporate header/footer
|
||||
rml = tools.file_open(os.path.join('base', 'report', 'corporate_%s_header.xml' % report_type)).read()
|
||||
rml_parser = self.parser(cr, uid, self.name2, context)
|
||||
rml_parser.parents = sxw_parents
|
||||
rml_parser.tag = sxw_tag
|
||||
objs = self.getObjects(cr, uid, ids, context)
|
||||
rml_parser.preprocess(objs, data, ids)
|
||||
rml_dom = xml.dom.minidom.parseString(rml)
|
||||
rml_parser.set_context(objs, data, ids, report_xml.report_type)
|
||||
rml_dom = self.preprocess_rml(etree.XML(rml),report_type)
|
||||
create_doc = self.generators[report_type]
|
||||
odt = create_doc(rml_dom,rml_parser.localcontext)
|
||||
if report_xml.header:
|
||||
rml_parser._add_header(odt)
|
||||
odt = etree.tostring(odt)
|
||||
sxw_z.writestr('styles.xml',"<?xml version='1.0' encoding='UTF-8'?>" + \
|
||||
odt)
|
||||
sxw_z.close()
|
||||
final_op = sxw_io.getvalue()
|
||||
sxw_io.close()
|
||||
return (final_op, report_type)
|
||||
|
||||
def create_single_html2html(self, cr, uid, ids, data, report_xml, context={}):
|
||||
context = context.copy()
|
||||
report_type = 'html'
|
||||
context['parents'] = html_parents
|
||||
|
||||
node = rml_dom.documentElement
|
||||
rml = report_xml.report_rml_content
|
||||
|
||||
elements = node.getElementsByTagName("text:p")
|
||||
rml_parser = self.parser(cr, uid, self.name2, context)
|
||||
rml_parser.parents = html_parents
|
||||
rml_parser.tag = sxw_tag
|
||||
objs = self.getObjects(cr, uid, ids, context)
|
||||
rml_parser.set_context(objs, data, ids, report_type)
|
||||
|
||||
for pe in elements:
|
||||
e = pe.getElementsByTagName("text:drop-down")
|
||||
for de in e:
|
||||
pp=de.parentNode
|
||||
for cnd in de.childNodes:
|
||||
if cnd.nodeType in (cnd.CDATA_SECTION_NODE, cnd.TEXT_NODE):
|
||||
pe.appendChild(cnd)
|
||||
pp.removeChild(de)
|
||||
rml_dom = etree.HTML(rml)
|
||||
rml_dom = self.preprocess_rml(rml_dom,'html2html')
|
||||
create_doc = self.generators['html2html']
|
||||
html = etree.tostring(create_doc(rml_dom, rml_parser.localcontext))
|
||||
|
||||
# Add Information : Resource ID and Model
|
||||
rml_dom_meta = xml.dom.minidom.parseString(meta)
|
||||
node = rml_dom_meta.documentElement
|
||||
elements = node.getElementsByTagName("meta:user-defined")
|
||||
for pe in elements:
|
||||
if pe.hasAttribute("meta:name"):
|
||||
if pe.getAttribute("meta:name") == "Info 3":
|
||||
pe.childNodes[0].data=data['id']
|
||||
if pe.getAttribute("meta:name") == "Info 4":
|
||||
pe.childNodes[0].data=data['model']
|
||||
meta = rml_dom_meta.documentElement.toxml('utf-8')
|
||||
return (html, report_type)
|
||||
|
||||
|
||||
rml2 = rml_parser._parse(rml_dom, objs, data, header=want_header)
|
||||
sxw_z = zipfile.ZipFile(sxw_io, mode='a')
|
||||
sxw_z.writestr('content.xml', "<?xml version='1.0' encoding='UTF-8'?>" + \
|
||||
rml2)
|
||||
sxw_z.writestr('meta.xml', "<?xml version='1.0' encoding='UTF-8'?>" + \
|
||||
meta)
|
||||
|
||||
if want_header:
|
||||
#Add corporate header/footer
|
||||
if report_type in ('odt', 'sxw'):
|
||||
rml = tools.file_open(os.path.join('base', 'report', 'corporate_%s_header.xml' % report_type)).read()
|
||||
rml_parser = self.parser(cr, uid, self.name2, context)
|
||||
rml_parser.parents = sxw_parents
|
||||
rml_parser.tag = sxw_tag
|
||||
objs = self.getObjects(cr, uid, ids, context)
|
||||
rml_parser.preprocess(objs, data, ids)
|
||||
rml_dom = xml.dom.minidom.parseString(rml)
|
||||
rml2 = rml_parser._parse(rml_dom, objs, data, header=want_header)
|
||||
sxw_z.writestr('styles.xml',"<?xml version='1.0' encoding='UTF-8'?>" + \
|
||||
rml2)
|
||||
sxw_z.close()
|
||||
rml2 = sxw_io.getvalue()
|
||||
sxw_io.close()
|
||||
else:
|
||||
rml = report_xml.report_rml_content
|
||||
context['parents'] = rml_parents
|
||||
rml_parser = self.parser(cr, uid, self.name2, context)
|
||||
rml_parser.parents = rml_parents
|
||||
rml_parser.tag = rml_tag
|
||||
objs = self.getObjects(cr, uid, ids, context)
|
||||
rml_parser.preprocess(objs, data, ids)
|
||||
rml_dom = xml.dom.minidom.parseString(rml)
|
||||
rml2 = rml_parser._parse(rml_dom, objs, data, header=want_header)
|
||||
if rml_parser.logo:
|
||||
logo = base64.decodestring(rml_parser.logo)
|
||||
|
||||
create_doc = self.generators[report_type]
|
||||
pdf = create_doc(rml2, logo, title.encode('utf8'))
|
||||
|
||||
return (pdf, report_type)
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ class db(netsvc.Service):
|
|||
security.check_super(password)
|
||||
logger = netsvc.Logger()
|
||||
|
||||
cmd = ['pg_dump', '--format=c']
|
||||
cmd = ['pg_dump', '--format=c', '--no-owner']
|
||||
if tools.config['db_user']:
|
||||
cmd.append('--username=' + tools.config['db_user'])
|
||||
if tools.config['db_host']:
|
||||
|
@ -210,7 +210,7 @@ class db(netsvc.Service):
|
|||
cr.close()
|
||||
sql_db.close_db('template1')
|
||||
|
||||
cmd = ['pg_restore']
|
||||
cmd = ['pg_restore', '--no-owner']
|
||||
if tools.config['db_user']:
|
||||
cmd.append('--username=' + tools.config['db_user'])
|
||||
if tools.config['db_host']:
|
||||
|
|
|
@ -73,7 +73,7 @@ class Cursor(object):
|
|||
|
||||
@wraps(f)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if not '_obj' in self.__dict__:
|
||||
if self.__closed:
|
||||
raise psycopg2.ProgrammingError('Unable to use the cursor after having closed it')
|
||||
return f(self, *args, **kwargs)
|
||||
return wrapper
|
||||
|
@ -83,6 +83,7 @@ class Cursor(object):
|
|||
self._serialized = serialized
|
||||
self._cnx = pool.getconn()
|
||||
self._obj = self._cnx.cursor(cursor_factory=psycopg1cursor)
|
||||
self.__closed = False
|
||||
self.autocommit(False)
|
||||
self.dbname = pool.dbname
|
||||
|
||||
|
@ -91,7 +92,7 @@ class Cursor(object):
|
|||
self.__caller = tuple(stack()[2][1:3])
|
||||
|
||||
def __del__(self):
|
||||
if '_obj' in self.__dict__ :
|
||||
if not self.__closed:
|
||||
if tools.config['log_level'] in (netsvc.LOG_DEBUG, netsvc.LOG_DEBUG_RPC):
|
||||
# Oops. 'self' has not been closed explicitly.
|
||||
# The cursor will be deleted by the garbage collector,
|
||||
|
@ -117,6 +118,7 @@ class Cursor(object):
|
|||
now = mdt.now()
|
||||
|
||||
try:
|
||||
params = params or None
|
||||
res = self._obj.execute(query, params)
|
||||
except psycopg2.ProgrammingError, pe:
|
||||
logger= netsvc.Logger()
|
||||
|
@ -173,6 +175,7 @@ class Cursor(object):
|
|||
# collected as fast as they should). The problem is probably due in
|
||||
# part because browse records keep a reference to the cursor.
|
||||
del self._obj
|
||||
self.__closed = True
|
||||
self._pool.putconn(self._cnx)
|
||||
|
||||
@check
|
||||
|
|
|
@ -37,6 +37,9 @@ class remote_contract(object):
|
|||
except:
|
||||
raise RemoteContractException("Unable to contact the migration server")
|
||||
|
||||
if not self.__userid:
|
||||
raise RemoteContractException("Unable to contact the migration server")
|
||||
|
||||
self.__rpc = xmlrpclib.ServerProxy(self.__server + 'object')
|
||||
|
||||
|
||||
|
|
|
@ -388,8 +388,8 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non
|
|||
)
|
||||
s.quit()
|
||||
except Exception, e:
|
||||
import logging
|
||||
logging.getLogger().error(str(e))
|
||||
import netsvc
|
||||
netsvc.Logger().notifyChannel('email_send', netsvc.LOG_ERROR, e)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ class interface(netsvc.Service):
|
|||
|
||||
# translate arch
|
||||
if not isinstance(arch, UpdateableStr):
|
||||
doc = dom.minidom.parseString(arch)
|
||||
doc = dom.minidom.parseString(arch.encode('utf8'))
|
||||
self.translate_view(cr, doc, state, lang)
|
||||
arch = doc.toxml()
|
||||
|
||||
|
|
Loading…
Reference in New Issue