import openerp
import openerp.release
import openerp.workflow
+from yaml_import import convert_yaml_import
import assertion_report
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
-from lxml import etree
+from lxml import etree, builder
import misc
from config import config
from translate import _
'Could not eval(%s) for %s in %s', a_eval, node.get('name'), context)
raise
def _process(s, idref):
- m = re.findall('[^%]%\((.*?)\)[ds]', s)
- for id in m:
+ matches = re.finditer('[^%]%\((.*?)\)[ds]', s)
+ done = []
+ for m in matches:
+ found = m.group()[1:]
+ if found in done:
+ continue
+ done.append(found)
+ id = m.groups()[0]
if not id in idref:
- idref[id]=self.id_get(cr, id)
- return s % idref
+ idref[id] = self.id_get(cr, id)
+ s = s.replace(found, str(idref[id]))
+
+ s = s.replace('%%', '%') # Quite wierd but it's for (somewhat) backward compatibility sake
+
+ return s
+
if t == 'xml':
_fix_multiple_roots(node)
return '<?xml version="1.0"?>\n'\
if t == 'html':
return _process("".join([etree.tostring(n, encoding='utf-8')
for n in node]), idref)
- if t in ('char', 'int', 'float'):
- d = node.text
- if t == 'int':
- d = d.strip()
- if d == 'None':
- return None
- else:
- return int(d.strip())
- elif t == 'float':
- return float(d.strip())
- return d
- elif t in ('list','tuple'):
+
+ data = node.text
+ if node.get('file'):
+ with openerp.tools.file_open(node.get('file'), 'rb') as f:
+ data = f.read()
+
+ if t == 'file':
+ from ..modules import module
+ path = data.strip()
+ if not module.get_module_resource(self.module, path):
+ raise IOError("No such file or directory: '%s' in %s" % (
+ path, self.module))
+ return '%s,%s' % (self.module, path)
+
+ if t == 'char':
+ return data
+
+ if t == 'base64':
+ return data.encode('base64')
+
+ if t == 'int':
+ d = data.strip()
+ if d == 'None':
+ return None
+ return int(d)
+
+ if t == 'float':
+ return float(data.strip())
+
+ if t in ('list','tuple'):
res=[]
- for n in node.findall('./value'):
+ for n in node.iterchildren(tag='value'):
res.append(_eval_xml(self,n,pool,cr,uid,idref))
if t=='tuple':
return tuple(res)
"Verify that this is a window action or add a type argument." % (a_action,)
action_type,action_mode,action_name,view_id,target = rrres
if view_id:
- cr.execute('SELECT arch FROM ir_ui_view WHERE id=%s', (int(view_id),))
- arch, = cr.fetchone()
- action_mode = etree.fromstring(arch.encode('utf8')).tag
+ view_arch = self.pool['ir.ui.view'].read(cr, 1, [view_id], ['arch'])
+ action_mode = etree.fromstring(view_arch[0]['arch'].encode('utf8')).tag
cr.execute('SELECT view_mode FROM ir_act_window_view WHERE act_window_id=%s ORDER BY sequence LIMIT 1', (int(a_id),))
if cr.rowcount:
action_mode, = cr.fetchone()
cr.commit()
return rec_model, id
+ def _tag_template(self, cr, el, data_node=None):
+ # This helper transforms a <template> element into a <record> and forwards it
+ tpl_id = el.get('id', el.get('t-name', '')).encode('ascii')
+ module = self.module
+ if '.' in tpl_id:
+ module, tpl_id = tpl_id.split('.', 1)
+ # set the full template name for qweb <module>.<id>
+ if not (el.get('inherit_id') or el.get('inherit_option_id')):
+ el.set('t-name', '%s.%s' % (module, tpl_id))
+ el.tag = 't'
+ else:
+ el.tag = 'data'
+ el.attrib.pop('id', None)
+
+ record_attrs = {
+ 'id': tpl_id,
+ 'model': 'ir.ui.view',
+ }
+ for att in ['forcecreate', 'context', 'priority']:
+ if att in el.keys():
+ record_attrs[att] = el.attrib.pop(att)
+
+ Field = builder.E.field
+ name = el.get('name', tpl_id)
+
+ record = etree.Element('record', attrib=record_attrs)
+ record.append(Field(name, name='name'))
+ record.append(Field("qweb", name='type'))
+ record.append(Field(el, name="arch", type="xml"))
+ for field_name in ('inherit_id','inherit_option_id'):
+ value = el.attrib.pop(field_name, None)
+ if value: record.append(Field(name=field_name, ref=value))
+ if el.attrib.pop('page', None) == 'True':
+ record.append(Field(name="page", eval="True"))
+
+ return self._tag_record(cr, record, data_node)
+
def id_get(self, cr, id_str):
if id_str in self.idref:
return self.idref[id_str]
self._tags = {
'menuitem': self._tag_menuitem,
'record': self._tag_record,
+ 'template': self._tag_template,
'assert': self._tag_assert,
'report': self._tag_report,
'wizard': self._tag_wizard,
'url': self._tag_url
}
+def convert_file(cr, module, filename, idref, mode='update', noupdate=False, kind=None, report=None):
+ pathname = os.path.join(module, filename)
+ fp = misc.file_open(pathname)
+ ext = os.path.splitext(filename)[1].lower()
+ try:
+ if ext == '.csv':
+ convert_csv_import(cr, module, pathname, fp.read(), idref, mode, noupdate)
+ elif ext == '.sql':
+ convert_sql_import(cr, fp)
+ elif ext == '.yml':
+ convert_yaml_import(cr, module, fp, kind, idref, mode, noupdate, report)
+ elif ext == '.xml':
+ convert_xml_import(cr, module, fp, idref, mode, noupdate, report)
+ elif ext == '.js':
+ pass # .js files are valid but ignored here.
+ else:
+ _logger.warning("Can't load unknown file type %s.", filename)
+ finally:
+ fp.close()
+
+def convert_sql_import(cr, fp):
+ queries = fp.read().split(';')
+ for query in queries:
+ new_query = ' '.join(query.split())
+ if new_query:
+ cr.execute(new_query)
+
def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
noupdate=False):
'''Import csv file :