[FIX] recursive calls
bzr revid: fp@tinyerp.com-20091019182609-bkowmclnyfon4jeo
This commit is contained in:
commit
012fd8d624
|
@ -27,6 +27,9 @@ import tools
|
|||
import pooler
|
||||
from osv import fields,osv
|
||||
|
||||
def str2tuple(s):
|
||||
return eval('tuple(%s)' % s)
|
||||
|
||||
_intervalTypes = {
|
||||
'work_days': lambda interval: DateTime.RelativeDateTime(days=interval),
|
||||
'days': lambda interval: DateTime.RelativeDateTime(days=interval),
|
||||
|
@ -65,25 +68,39 @@ class ir_cron(osv.osv, netsvc.Agent):
|
|||
'doall' : lambda *a: 1
|
||||
}
|
||||
|
||||
def _check_args(self, cr, uid, ids, context=None):
|
||||
try:
|
||||
for this in self.browse(cr, uid, ids, context):
|
||||
str2tuple(this.args)
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints= [
|
||||
(_check_args, 'Invalid arguments', ['args']),
|
||||
]
|
||||
|
||||
def _callback(self, cr, uid, model, func, args):
|
||||
args = (args or []) and eval(args)
|
||||
m=self.pool.get(model)
|
||||
args = str2tuple(args)
|
||||
m = self.pool.get(model)
|
||||
if m and hasattr(m, func):
|
||||
f = getattr(m, func)
|
||||
f(cr, uid, *args)
|
||||
try:
|
||||
f(cr, uid, *args)
|
||||
except Exception, e:
|
||||
self._logger.notifyChannel('timers', netsvc.LOG_ERROR, "Job call of self.pool.get('%s').%s(cr, uid, *%r) failed" % (model, func, args))
|
||||
self._logger.notifyChannel('timers', netsvc.LOG_ERROR, tools.exception_to_unicode(e))
|
||||
|
||||
|
||||
def _poolJobs(self, db_name, check=False):
|
||||
try:
|
||||
db, pool = pooler.get_db_and_pool(db_name)
|
||||
except:
|
||||
return False
|
||||
if pool._init:
|
||||
# retry in a few minutes
|
||||
next_call = 600
|
||||
else:
|
||||
now = DateTime.now()
|
||||
try:
|
||||
cr = db.cursor()
|
||||
try:
|
||||
cr = db.cursor()
|
||||
if not pool._init:
|
||||
now = DateTime.now()
|
||||
cr.execute('select * from ir_cron where numbercall<>0 and active and nextcall<=now() order by priority')
|
||||
for job in cr.dictfetchall():
|
||||
nextcall = DateTime.strptime(job['nextcall'], '%Y-%m-%d %H:%M:%S')
|
||||
|
@ -103,24 +120,22 @@ class ir_cron(osv.osv, netsvc.Agent):
|
|||
addsql = ', active=False'
|
||||
cr.execute("update ir_cron set nextcall=%s, numbercall=%s"+addsql+" where id=%s", (nextcall.strftime('%Y-%m-%d %H:%M:%S'), numbercall, job['id']))
|
||||
cr.commit()
|
||||
finally:
|
||||
cr.commit()
|
||||
cr.close()
|
||||
|
||||
#
|
||||
# Can be improved to do at the min(min(nextcalls), time()+next_call)
|
||||
# But is this an improvement ?
|
||||
#
|
||||
cr = db.cursor()
|
||||
cr.execute('select min(nextcall) as min_next_call from ir_cron where numbercall<>0 and active and nextcall>=now()')
|
||||
next_call = cr.dictfetchone()['min_next_call']
|
||||
cr.close()
|
||||
if next_call:
|
||||
next_call = time.mktime(time.strptime(next_call, '%Y-%m-%d %H:%M:%S'))
|
||||
else:
|
||||
next_call = int(time.time()) + 3600 # if do not find active cron job from database, it will run again after 1 day
|
||||
if not check:
|
||||
self.setAlarm(self._poolJobs, next_call, db_name, db_name)
|
||||
|
||||
cr.execute('select min(nextcall) as min_next_call from ir_cron where numbercall<>0 and active and nextcall>=now()')
|
||||
next_call = cr.dictfetchone()['min_next_call']
|
||||
if next_call:
|
||||
next_call = time.mktime(time.strptime(next_call, '%Y-%m-%d %H:%M:%S'))
|
||||
else:
|
||||
next_call = int(time.time()) + 3600 # if do not find active cron job from database, it will run again after 1 day
|
||||
|
||||
if not check:
|
||||
self.setAlarm(self._poolJobs, next_call, db_name, db_name)
|
||||
|
||||
finally:
|
||||
cr.commit()
|
||||
cr.close()
|
||||
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
res = super(ir_cron, self).create(cr, uid, vals, context=context)
|
||||
|
|
|
@ -446,10 +446,11 @@ class ir_model_data(osv.osv):
|
|||
id = False
|
||||
return id
|
||||
|
||||
def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False):
|
||||
def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False, context=None):
|
||||
warning = True
|
||||
model_obj = self.pool.get(model)
|
||||
context = {}
|
||||
if not context:
|
||||
context = {}
|
||||
if xml_id and ('.' in xml_id):
|
||||
assert len(xml_id.split('.'))==2, _('"%s" contains too many dots. XML ids should not contain dots ! These are used to refer to other modules data, as in module.reference_id') % (xml_id)
|
||||
warning = False
|
||||
|
@ -472,12 +473,12 @@ class ir_model_data(osv.osv):
|
|||
res_id,action_id = res_id2,action_id2
|
||||
|
||||
if action_id and res_id:
|
||||
model_obj.write(cr, uid, [res_id], values)
|
||||
model_obj.write(cr, uid, [res_id], values, context=context)
|
||||
self.write(cr, uid, [action_id], {
|
||||
'date_update': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
})
|
||||
},context=context)
|
||||
elif res_id:
|
||||
model_obj.write(cr, uid, [res_id], values)
|
||||
model_obj.write(cr, uid, [res_id], values, context=context)
|
||||
if xml_id:
|
||||
self.create(cr, uid, {
|
||||
'name': xml_id,
|
||||
|
@ -485,21 +486,21 @@ class ir_model_data(osv.osv):
|
|||
'module':module,
|
||||
'res_id':res_id,
|
||||
'noupdate': noupdate,
|
||||
})
|
||||
},context=context)
|
||||
if model_obj._inherits:
|
||||
for table in model_obj._inherits:
|
||||
inherit_id = model_obj.browse(cr, uid,
|
||||
res_id)[model_obj._inherits[table]]
|
||||
res_id,context=context)[model_obj._inherits[table]]
|
||||
self.create(cr, uid, {
|
||||
'name': xml_id + '_' + table.replace('.', '_'),
|
||||
'model': table,
|
||||
'module': module,
|
||||
'res_id': inherit_id,
|
||||
'noupdate': noupdate,
|
||||
})
|
||||
},context=context)
|
||||
else:
|
||||
if mode=='init' or (mode=='update' and xml_id):
|
||||
res_id = model_obj.create(cr, uid, values)
|
||||
res_id = model_obj.create(cr, uid, values, context=context)
|
||||
if xml_id:
|
||||
self.create(cr, uid, {
|
||||
'name': xml_id,
|
||||
|
@ -507,18 +508,18 @@ class ir_model_data(osv.osv):
|
|||
'module': module,
|
||||
'res_id': res_id,
|
||||
'noupdate': noupdate
|
||||
})
|
||||
},context=context)
|
||||
if model_obj._inherits:
|
||||
for table in model_obj._inherits:
|
||||
inherit_id = model_obj.browse(cr, uid,
|
||||
res_id)[model_obj._inherits[table]]
|
||||
res_id,context=context)[model_obj._inherits[table]]
|
||||
self.create(cr, uid, {
|
||||
'name': xml_id + '_' + table.replace('.', '_'),
|
||||
'model': table,
|
||||
'module': module,
|
||||
'res_id': inherit_id,
|
||||
'noupdate': noupdate,
|
||||
})
|
||||
},context=context)
|
||||
if xml_id:
|
||||
if res_id:
|
||||
self.loads[(module, xml_id)] = (model, res_id)
|
||||
|
|
|
@ -25,7 +25,7 @@ from report import report_sxw
|
|||
|
||||
class ir_module_reference_print(report_sxw.rml_parse):
|
||||
def __init__(self, cr, uid, name, context):
|
||||
super(ir_module_reference_print, self).__init__(cr, uid, name, context)
|
||||
super(ir_module_reference_print, self).__init__(cr, uid, name, context=context)
|
||||
self.localcontext.update({
|
||||
'time': time,
|
||||
'findobj': self._object_find,
|
||||
|
|
|
@ -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$
|
||||
#
|
||||
|
@ -37,24 +37,36 @@ waittime = 10
|
|||
wait_count = 0
|
||||
wait_limit = 12
|
||||
|
||||
def start_server(root_path, port, addons_path):
|
||||
os.system('python2.5 %sopenerp-server.py --pidfile=openerp.pid --port=%s --no-netrpc --addons-path=%s' %(root_path, str(port), addons_path))
|
||||
def to_decode(s):
|
||||
try:
|
||||
return s.encode('utf-8')
|
||||
except UnicodeError:
|
||||
try:
|
||||
return s.encode('latin')
|
||||
except UnicodeError:
|
||||
try:
|
||||
return s.decode('ascii')
|
||||
except UnicodeError:
|
||||
return s
|
||||
|
||||
def start_server(root_path, port, addons_path):
|
||||
os.system('python2.5 %sopenerp-server.py --pidfile=openerp.pid --port=%s --no-netrpc --addons-path=%s' %(root_path, str(port), addons_path))
|
||||
def clean():
|
||||
if os.path.isfile('openerp.pid'):
|
||||
ps = open('openerp.pid')
|
||||
ps = open('openerp.pid')
|
||||
if ps:
|
||||
pid = int(ps.read())
|
||||
ps.close()
|
||||
if pid:
|
||||
ps.close()
|
||||
if pid:
|
||||
os.kill(pid,9)
|
||||
|
||||
def execute(connector, method, *args):
|
||||
global wait_count
|
||||
global wait_count
|
||||
res = False
|
||||
try:
|
||||
try:
|
||||
res = getattr(connector,method)(*args)
|
||||
except socket.error,e:
|
||||
if e.args[0] == 111:
|
||||
except socket.error,e:
|
||||
if e.args[0] == 111:
|
||||
if wait_count > wait_limit:
|
||||
print "Server is taking too long to start, it has exceeded the maximum limit of %d seconds."%(wait_limit)
|
||||
clean()
|
||||
|
@ -66,23 +78,23 @@ def execute(connector, method, *args):
|
|||
else:
|
||||
raise e
|
||||
wait_count = 0
|
||||
return res
|
||||
return res
|
||||
|
||||
def login(uri, dbname, user, pwd):
|
||||
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/common')
|
||||
uid = execute(conn,'login',dbname, user, pwd)
|
||||
uid = execute(conn,'login',dbname, user, pwd)
|
||||
return uid
|
||||
|
||||
def import_translate(uri, user, pwd, dbname, translate_in):
|
||||
uid = login(uri, dbname, user, pwd)
|
||||
if uid:
|
||||
def import_translate(uri, user, pwd, dbname, translate_in):
|
||||
uid = login(uri, dbname, user, pwd)
|
||||
if uid:
|
||||
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
|
||||
wiz_id = execute(conn,'create',dbname, uid, pwd, 'module.lang.import')
|
||||
for trans_in in translate_in:
|
||||
lang,ext = os.path.splitext(trans_in.split('/')[-1])
|
||||
state = 'init'
|
||||
lang,ext = os.path.splitext(trans_in.split('/')[-1])
|
||||
state = 'init'
|
||||
datas = {'form':{}}
|
||||
while state!='end':
|
||||
while state!='end':
|
||||
res = execute(conn,'execute',dbname, uid, pwd, wiz_id, datas, state, {})
|
||||
if 'datas' in res:
|
||||
datas['form'].update( res['datas'].get('form',{}) )
|
||||
|
@ -98,47 +110,51 @@ def import_translate(uri, user, pwd, dbname, translate_in):
|
|||
})
|
||||
trans_obj.close()
|
||||
elif res['type']=='action':
|
||||
state = res['state']
|
||||
|
||||
|
||||
def check_quality(uri, user, pwd, dbname, modules):
|
||||
state = res['state']
|
||||
|
||||
|
||||
def check_quality(uri, user, pwd, dbname, modules, quality_logs):
|
||||
uid = login(uri, dbname, user, pwd)
|
||||
quality_logs += 'quality-logs'
|
||||
if uid:
|
||||
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object')
|
||||
final = {}
|
||||
for module in modules:
|
||||
final = {}
|
||||
for module in modules:
|
||||
qualityresult = {}
|
||||
test_detail = {}
|
||||
test_detail = {}
|
||||
quality_result = execute(conn,'execute', dbname, uid, pwd,'module.quality.check','check_quality',module)
|
||||
detail_html = ''
|
||||
html = '''<html><html><html><html><body><a name="TOP"></a>'''
|
||||
html +="<h1> Module : %s </h1>"%(quality_result['name'])
|
||||
html += "<h2> Final score : %s</h2>"%(quality_result['final_score'])
|
||||
html = '''<html><body><a name="TOP"></a>'''
|
||||
html +="<h1> Module: %s </h1>"%(quality_result['name'])
|
||||
html += "<h2> Final score: %s</h2>"%(quality_result['final_score'])
|
||||
html += "<div id='tabs'>"
|
||||
html += "<ul>"
|
||||
for x,y,detail in quality_result['check_detail_ids']:
|
||||
for x,y,detail in quality_result['check_detail_ids']:
|
||||
test = detail.get('name')
|
||||
msg = detail.get('message','')
|
||||
score = round(float(detail.get('score',0)),2)
|
||||
html += "<li><a href=\"#%s\">%s</a></li>"%(test.replace(' ','-'),test)
|
||||
if test == 'Unit Test':
|
||||
if not detail.get('detail',''):
|
||||
detail['detail'] = '''<html><body><b>%s</b></body></html>'''%(detail.get('summary',''))
|
||||
detail_html +="<div id=\"%s\"><h3>%s (Score : %s)</h3>%s</div>"%(test.replace(' ','-'),test,score,detail.get('detail',''))
|
||||
detail_html +='''<div id=\"%s\"><h3>%s (Score : %s)</h3><font color=red><h5>%s</h5></font>%s</div>'''%(test.replace(' ', '-'), test, score, msg, detail.get('detail', ''))
|
||||
test_detail[test] = (score,msg,detail.get('detail',''))
|
||||
html += "</ul>%s</body></html></html></html></html></html>"%(detail_html)
|
||||
html += "</div>"
|
||||
final[quality_result['name']] = (quality_result['final_score'],html,test_detail)
|
||||
html += "</ul>"
|
||||
html += "%s"%(detail_html)
|
||||
html += "</div></body></html>"
|
||||
if not os.path.isdir(quality_logs):
|
||||
os.mkdir(quality_logs)
|
||||
fp = open('%s/%s.html'%(quality_logs,module),'wb')
|
||||
fp.write(to_decode(html))
|
||||
fp.close()
|
||||
#final[quality_result['name']] = (quality_result['final_score'],html,test_detail)
|
||||
|
||||
fp = open('quality_log.pck','wb')
|
||||
pck_obj = pickle.dump(final,fp)
|
||||
fp.close()
|
||||
print "LOG PATH%s"%(os.path.realpath('quality_log.pck'))
|
||||
return final
|
||||
#fp = open('quality_log.pck','wb')
|
||||
#pck_obj = pickle.dump(final,fp)
|
||||
#fp.close()
|
||||
#print "LOG PATH%s"%(os.path.realpath('quality_log.pck'))
|
||||
return True
|
||||
else:
|
||||
print 'Login Failed...'
|
||||
print 'Login Failed...'
|
||||
clean()
|
||||
sys.exit(1)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
|
@ -157,25 +173,25 @@ def create_db(uri, dbname, user='admin', pwd='admin', lang='en_US'):
|
|||
login_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/common')
|
||||
db_list = execute(conn, 'list')
|
||||
if dbname not in db_list:
|
||||
id = execute(conn,'create',admin_passwd, dbname, True, lang)
|
||||
id = execute(conn,'create',admin_passwd, dbname, True, lang)
|
||||
wait(id,uri)
|
||||
uid = login_conn.login(dbname, user, pwd)
|
||||
uid = login_conn.login(dbname, user, pwd)
|
||||
|
||||
wiz_id = execute(wiz_conn,'create', dbname, uid, user, 'base_setup.base_setup')
|
||||
|
||||
state = 'init'
|
||||
datas = {'form':{}}
|
||||
|
||||
while state!='config':
|
||||
while state!='config':
|
||||
res = execute(wiz_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
|
||||
if state=='init':
|
||||
datas['form'].update( res['datas'] )
|
||||
if res['type']=='form':
|
||||
for field in res['fields'].keys():
|
||||
for field in res['fields'].keys():
|
||||
datas['form'][field] = datas['form'].get(field,False)
|
||||
state = res['state'][-1][0]
|
||||
datas['form'].update({
|
||||
'profile': -1
|
||||
'profile': -1
|
||||
})
|
||||
elif res['type']=='state':
|
||||
state = res['state']
|
||||
|
@ -187,71 +203,71 @@ def drop_db(uri, dbname):
|
|||
conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/db')
|
||||
db_list = execute(conn,'list')
|
||||
if dbname in db_list:
|
||||
execute(conn, 'drop', admin_passwd, dbname)
|
||||
execute(conn, 'drop', admin_passwd, dbname)
|
||||
return True
|
||||
|
||||
|
||||
def make_links(uri, uid, dbname, source, destination, module, user, pwd):
|
||||
if module in ('base','quality_integration_server'):
|
||||
return True
|
||||
if not os.path.islink(destination + '/' + module):
|
||||
if not os.path.isdir(destination + '/' + module):
|
||||
return True
|
||||
if not os.path.islink(destination + '/' + module):
|
||||
if not os.path.isdir(destination + '/' + module):
|
||||
for path in source:
|
||||
if os.path.isdir(path + '/' + module):
|
||||
os.symlink(path + '/' + module, destination + '/' + module)
|
||||
obj_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object')
|
||||
execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'update_list')
|
||||
module_ids = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'search', [('name','=',module)])
|
||||
if len(module_ids):
|
||||
if len(module_ids):
|
||||
data = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'read', module_ids[0],['name','dependencies_id'])
|
||||
dep_datas = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module.dependency', 'read', data['dependencies_id'],['name'])
|
||||
for dep_data in dep_datas:
|
||||
for dep_data in dep_datas:
|
||||
make_links(uri, uid, dbname, source, destination, dep_data['name'], user, pwd)
|
||||
return True
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
def install_module(uri, dbname, modules, addons='', extra_addons='', user='admin', pwd='admin'):
|
||||
uid = login(uri, dbname, user, pwd)
|
||||
if extra_addons:
|
||||
extra_addons = extra_addons.split(',')
|
||||
if uid:
|
||||
if uid:
|
||||
if addons and extra_addons:
|
||||
for module in modules:
|
||||
make_links(uri, uid, dbname, extra_addons, addons, module, user, pwd)
|
||||
for module in modules:
|
||||
make_links(uri, uid, dbname, extra_addons, addons, module, user, pwd)
|
||||
|
||||
obj_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object')
|
||||
wizard_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
|
||||
module_ids = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'search', [('name','in',modules)])
|
||||
execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'button_install', module_ids)
|
||||
execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'button_install', module_ids)
|
||||
wiz_id = execute(wizard_conn, 'create', dbname, uid, pwd, 'module.upgrade.simple')
|
||||
state = 'init'
|
||||
datas = {}
|
||||
#while state!='menu':
|
||||
while state!='end':
|
||||
res = execute(wizard_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
|
||||
while state!='end':
|
||||
res = execute(wizard_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
|
||||
if state == 'init':
|
||||
state = 'start'
|
||||
elif state == 'start':
|
||||
state = 'end'
|
||||
state = 'end'
|
||||
return True
|
||||
|
||||
def upgrade_module(uri, dbname, modules, user='admin', pwd='admin'):
|
||||
uid = login(uri, dbname, user, pwd)
|
||||
if uid:
|
||||
if uid:
|
||||
obj_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object')
|
||||
wizard_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
|
||||
module_ids = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'search', [('name','in',modules)])
|
||||
execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'button_upgrade', module_ids)
|
||||
wizard_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/wizard')
|
||||
module_ids = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'search', [('name','in',modules)])
|
||||
execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'button_upgrade', module_ids)
|
||||
wiz_id = execute(wizard_conn, 'create', dbname, uid, pwd, 'module.upgrade.simple')
|
||||
state = 'init'
|
||||
datas = {}
|
||||
#while state!='menu':
|
||||
while state!='end':
|
||||
res = execute(wizard_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
|
||||
while state!='end':
|
||||
res = execute(wizard_conn, 'execute', dbname, uid, pwd, wiz_id, datas, state, {})
|
||||
if state == 'init':
|
||||
state = 'start'
|
||||
elif state == 'start':
|
||||
state = 'end'
|
||||
|
||||
state = 'end'
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@ -264,20 +280,21 @@ Basic Commands:
|
|||
start-server Start Server
|
||||
create-db Create new database
|
||||
drop-db Drop database
|
||||
install-module Install module
|
||||
install-module Install module
|
||||
upgrade-module Upgrade module
|
||||
install-translation Install translation file
|
||||
check-quality Calculate quality and dump quality result into quality_log.pck using pickle
|
||||
"""
|
||||
parser = optparse.OptionParser(usage)
|
||||
parser = optparse.OptionParser(usage)
|
||||
parser.add_option("--modules", dest="modules",
|
||||
help="specify modules to install or check quality")
|
||||
parser.add_option("--addons-path", dest="addons_path", help="specify the addons path")
|
||||
parser.add_option("--quality-logs", dest="quality_logs", help="specify the path of quality logs files which has to stores")
|
||||
parser.add_option("--root-path", dest="root_path", help="specify the root path")
|
||||
parser.add_option("-p", "--port", dest="port", help="specify the TCP port", type="int")
|
||||
parser.add_option("-d", "--database", dest="db_name", help="specify the database name")
|
||||
parser.add_option("--login", dest="login", help="specify the User Login")
|
||||
parser.add_option("--password", dest="pwd", help="specify the User Password")
|
||||
parser.add_option("-d", "--database", dest="db_name", help="specify the database name")
|
||||
parser.add_option("--login", dest="login", help="specify the User Login")
|
||||
parser.add_option("--password", dest="pwd", help="specify the User Password")
|
||||
parser.add_option("--translate-in", dest="translate_in",
|
||||
help="specify .po files to import translation terms")
|
||||
parser.add_option("--extra-addons", dest="extra_addons",
|
||||
|
@ -288,7 +305,7 @@ if len(args) != 1:
|
|||
parser.error("incorrect number of arguments")
|
||||
command = args[0]
|
||||
if command not in ('start-server','create-db','drop-db','install-module','upgrade-module','check-quality','install-translation'):
|
||||
parser.error("incorrect command")
|
||||
parser.error("incorrect command")
|
||||
|
||||
def die(cond, msg):
|
||||
if cond:
|
||||
|
@ -303,9 +320,10 @@ die(opt.translate_in and (not opt.db_name),
|
|||
|
||||
options = {
|
||||
'addons-path' : opt.addons_path or 'addons',
|
||||
'quality-logs' : opt.quality_logs or '',
|
||||
'root-path' : opt.root_path or '',
|
||||
'translate-in': [],
|
||||
'port' : opt.port or 8069,
|
||||
'port' : opt.port or 8069,
|
||||
'database': opt.db_name or 'terp',
|
||||
'modules' : opt.modules or [],
|
||||
'login' : opt.login or 'admin',
|
||||
|
@ -316,33 +334,33 @@ options = {
|
|||
options['modules'] = opt.modules and map(lambda m: m.strip(), opt.modules.split(',')) or []
|
||||
# Hint:i18n-import=purchase:ar_AR.po+sale:fr_FR.po,nl_BE.po
|
||||
if opt.translate_in:
|
||||
translate = opt.translate_in
|
||||
for module_name,po_files in map(lambda x:tuple(x.split(':')),translate.split('+')):
|
||||
for po_file in po_files.split(','):
|
||||
translate = opt.translate_in
|
||||
for module_name,po_files in map(lambda x:tuple(x.split(':')),translate.split('+')):
|
||||
for po_file in po_files.split(','):
|
||||
po_link = '%s/%s/i18n/%s'%(options['addons-path'], module_name, po_file)
|
||||
options['translate-in'].append(po_link)
|
||||
|
||||
options['translate-in'].append(po_link)
|
||||
|
||||
uri = 'http://localhost:' + str(options['port'])
|
||||
|
||||
server_thread = threading.Thread(target=start_server,
|
||||
args=(options['root-path'], options['port'], options['addons-path']))
|
||||
try:
|
||||
server_thread.start()
|
||||
if command == 'create-db':
|
||||
try:
|
||||
server_thread.start()
|
||||
if command == 'create-db':
|
||||
create_db(uri, options['database'], options['login'], options['pwd'])
|
||||
if command == 'drop-db':
|
||||
if command == 'drop-db':
|
||||
drop_db(uri, options['database'])
|
||||
if command == 'install-module':
|
||||
if command == 'install-module':
|
||||
install_module(uri, options['database'], options['modules'],options['addons-path'],options['extra-addons'],options['login'], options['pwd'])
|
||||
if command == 'upgrade-module':
|
||||
if command == 'upgrade-module':
|
||||
upgrade_module(uri, options['database'], options['modules'], options['login'], options['pwd'])
|
||||
if command == 'check-quality':
|
||||
check_quality(uri, options['login'], options['pwd'], options['database'], options['modules'])
|
||||
if command == 'install-translation':
|
||||
check_quality(uri, options['login'], options['pwd'], options['database'], options['modules'], options['quality-logs'])
|
||||
if command == 'install-translation':
|
||||
import_translate(uri, options['login'], options['pwd'], options['database'], options['translate-in'])
|
||||
clean()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
except xmlrpclib.Fault, e:
|
||||
print e.faultString
|
||||
clean()
|
||||
|
@ -351,7 +369,7 @@ except Exception, e:
|
|||
print e
|
||||
clean()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -44,17 +44,20 @@ class expression(object):
|
|||
and (((not internal) and element[1] in OPS) \
|
||||
or (internal and element[1] in INTERNAL_OPS))
|
||||
|
||||
def __execute_recursive_in(self, cr, s, f, w, ids):
|
||||
def __execute_recursive_in(self, cr, s, f, w, ids, op, type):
|
||||
res = []
|
||||
if not ids:
|
||||
return []
|
||||
if op not in ('<','>','=','>=','<=','not in'):
|
||||
op = 'in'
|
||||
for i in range(0, len(ids), cr.IN_MAX):
|
||||
subids = ids[i:i+cr.IN_MAX]
|
||||
cr.execute('SELECT "%s"' \
|
||||
' FROM "%s"' \
|
||||
' WHERE "%s" in (%s)' % (s, f, w, ','.join(['%s']*len(subids))),
|
||||
' FROM "%s"' \
|
||||
' WHERE "%s" %s (%s)' % (s, f, w, op, ','.join(['%s']*len(subids))),
|
||||
subids)
|
||||
res += [r[0] for r in cr.fetchall() if r[0]]
|
||||
return res + (res and self.__execute_recursive_in(cr, s, f, w, res) or [])
|
||||
|
||||
return res + (res and self.__execute_recursive_in(cr, s, f, w, res, op, type) or [])
|
||||
|
||||
def __init__(self, exp):
|
||||
# check if the expression is valid
|
||||
|
@ -101,7 +104,6 @@ class expression(object):
|
|||
if self._is_operator(e) or e == self.__DUMMY_LEAF:
|
||||
continue
|
||||
left, operator, right = e
|
||||
|
||||
working_table = table
|
||||
main_table = table
|
||||
fargs = left.split('.', 1)
|
||||
|
@ -154,14 +156,32 @@ class expression(object):
|
|||
|
||||
|
||||
elif field._type == 'one2many':
|
||||
if isinstance(right, basestring):
|
||||
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, limit=None)]
|
||||
else:
|
||||
ids2 = list(right)
|
||||
if not ids2:
|
||||
self.__exp[i] = ('id', '=', '0')
|
||||
else:
|
||||
self.__exp[i] = ('id', 'in', self.__execute_recursive_in(cr, field._fields_id, field_obj._table, 'id', ids2))
|
||||
call_null = True
|
||||
|
||||
if right:
|
||||
if isinstance(right, basestring):
|
||||
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, limit=None)]
|
||||
operator = 'in'
|
||||
else:
|
||||
if not isinstance(right,list):
|
||||
ids2 = [right]
|
||||
else:
|
||||
ids2 = right
|
||||
if not ids2:
|
||||
call_null = True
|
||||
operator = 'in' # operator changed because ids are directly related to main object
|
||||
else:
|
||||
call_null = False
|
||||
o2m_op = 'in'
|
||||
if operator in ['not like','not ilike','not in','<>','!=']:
|
||||
o2m_op = 'not in'
|
||||
self.__exp[i] = ('id', o2m_op, self.__execute_recursive_in(cr, field._fields_id, field_obj._table, 'id', ids2, operator, field._type))
|
||||
|
||||
if call_null:
|
||||
o2m_op = 'not in'
|
||||
if operator in ['not like','not ilike','not in','<>','!=']:
|
||||
o2m_op = 'in'
|
||||
self.__exp[i] = ('id', o2m_op, self.__execute_recursive_in(cr, field._fields_id, field_obj._table, 'id', [], operator, field._type) or [0])
|
||||
|
||||
elif field._type == 'many2many':
|
||||
#FIXME
|
||||
|
@ -174,17 +194,38 @@ class expression(object):
|
|||
def _rec_convert(ids):
|
||||
if field_obj == table:
|
||||
return ids
|
||||
return self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, ids)
|
||||
return self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, ids, operator, field._type)
|
||||
|
||||
dom = _rec_get(ids2, field_obj)
|
||||
ids2 = field_obj.search(cr, uid, dom, context=context)
|
||||
self.__exp[i] = ('id', 'in', _rec_convert(ids2))
|
||||
else:
|
||||
if isinstance(right, basestring):
|
||||
res_ids = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator)]
|
||||
else:
|
||||
res_ids = list(right)
|
||||
self.__exp[i] = ('id', 'in', self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, res_ids) or [0])
|
||||
call_null_m2m = True
|
||||
if right:
|
||||
if isinstance(right, basestring):
|
||||
res_ids = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator)]
|
||||
operator = 'in'
|
||||
else:
|
||||
if not isinstance(right, list):
|
||||
res_ids = [right]
|
||||
else:
|
||||
res_ids = right
|
||||
if not res_ids:
|
||||
call_null_m2m = True
|
||||
operator = 'in' # operator changed because ids are directly related to main object
|
||||
else:
|
||||
call_null_m2m = False
|
||||
m2m_op = 'in'
|
||||
if operator in ['not like','not ilike','not in','<>','!=']:
|
||||
m2m_op = 'not in'
|
||||
|
||||
self.__exp[i] = ('id', m2m_op, self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, res_ids, operator, field._type) or [0])
|
||||
if call_null_m2m:
|
||||
m2m_op = 'not in'
|
||||
if operator in ['not like','not ilike','not in','<>','!=']:
|
||||
m2m_op = 'in'
|
||||
self.__exp[i] = ('id', m2m_op, self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, [], operator, field._type) or [0])
|
||||
|
||||
elif field._type == 'many2one':
|
||||
if operator == 'child_of':
|
||||
if isinstance(right, basestring):
|
||||
|
|
|
@ -577,7 +577,11 @@ class orm_template(object):
|
|||
raise Exception(_('Please check that all your lines have %d columns.') % (len(fields),))
|
||||
if not line[i]:
|
||||
continue
|
||||
|
||||
field = fields[i]
|
||||
if prefix and not prefix[0] in field:
|
||||
continue
|
||||
|
||||
if (len(field)==len(prefix)+1) and field[len(prefix)].endswith(':db_id'):
|
||||
# Database ID
|
||||
res = False
|
||||
|
@ -634,7 +638,7 @@ class orm_template(object):
|
|||
id = ir_model_data_obj._get_id(cr, uid, module, xml_id)
|
||||
res_id = ir_model_data_obj.read(cr, uid, [id],
|
||||
['res_id'])[0]['res_id']
|
||||
row[field[0][:-3]] = res_id or False
|
||||
row[field[-1][:-3]] = res_id or False
|
||||
continue
|
||||
if (len(field) == len(prefix)+1) and \
|
||||
len(field[len(prefix)].split(':lang=')) == 2:
|
||||
|
@ -670,7 +674,7 @@ class orm_template(object):
|
|||
try:
|
||||
_check_db_id(self, model_name, line[i])
|
||||
data_res_id = is_db_id = int(line[i])
|
||||
except Exception,e:
|
||||
except Exception,e:
|
||||
warning += [tools.exception_to_unicode(e)]
|
||||
logger.notifyChannel("import", netsvc.LOG_ERROR,
|
||||
tools.exception_to_unicode(e))
|
||||
|
@ -811,7 +815,7 @@ class orm_template(object):
|
|||
try:
|
||||
id = ir_model_data_obj._update(cr, uid, self._name,
|
||||
current_module, res, xml_id=data_id, mode=mode,
|
||||
noupdate=noupdate, res_id=res_id)
|
||||
noupdate=noupdate, res_id=res_id, context=context)
|
||||
except Exception, e:
|
||||
import psycopg2
|
||||
if isinstance(e,psycopg2.IntegrityError):
|
||||
|
@ -1058,19 +1062,37 @@ class orm_template(object):
|
|||
|
||||
buttons = (n for n in node.getElementsByTagName('button') if n.getAttribute('type') != 'object')
|
||||
for button in buttons:
|
||||
ok = True
|
||||
can_click = True
|
||||
if user != 1: # admin user has all roles
|
||||
user_roles = usersobj.read(cr, user, [user], ['roles_id'])[0]['roles_id']
|
||||
cr.execute("select role_id from wkf_transition where signal=%s", (button.getAttribute('name'),))
|
||||
# TODO handle the case of more than one workflow for a model
|
||||
cr.execute("""SELECT DISTINCT t.role_id
|
||||
FROM wkf
|
||||
INNER JOIN wkf_activity a ON a.wkf_id = wkf.id
|
||||
INNER JOIN wkf_transition t ON (t.act_to = a.id)
|
||||
WHERE wkf.osv = %s
|
||||
AND t.signal = %s
|
||||
""", (self._name, button.getAttribute('name'),))
|
||||
roles = cr.fetchall()
|
||||
for role in roles:
|
||||
if role[0]:
|
||||
ok = ok and rolesobj.check(cr, user, user_roles, role[0])
|
||||
|
||||
# draft -> valid = signal_next (role X)
|
||||
# draft -> cancel = signal_cancel (no role)
|
||||
#
|
||||
# valid -> running = signal_next (role Y)
|
||||
# valid -> cancel = signal_cancel (role Z)
|
||||
#
|
||||
# running -> done = signal_next (role Z)
|
||||
# running -> cancel = signal_cancel (role Z)
|
||||
|
||||
|
||||
if not ok:
|
||||
button.setAttribute('readonly', '1')
|
||||
else:
|
||||
button.setAttribute('readonly', '0')
|
||||
# As we don't know the object state, in this scenario,
|
||||
# the button "signal_cancel" will be always shown as there is no restriction to cancel in draft
|
||||
# the button "signal_next" will be show if the user has any of the roles (X Y or Z)
|
||||
# The verification will be made later in workflow process...
|
||||
if roles:
|
||||
can_click = any((not role) or rolesobj.check(cr, user, user_roles, role) for (role,) in roles)
|
||||
|
||||
button.setAttribute('readonly', str(int(not can_click)))
|
||||
|
||||
arch = node.toxml(encoding="utf-8").replace('\t', '')
|
||||
fields = self.fields_get(cr, user, fields_def.keys(), context)
|
||||
|
@ -1208,6 +1230,15 @@ class orm_template(object):
|
|||
model = True
|
||||
sql_res = False
|
||||
while ok:
|
||||
view_ref = context.get(view_type + '_view_ref', False)
|
||||
if view_ref:
|
||||
if '.' in view_ref:
|
||||
module, view_ref = view_ref.split('.', 1)
|
||||
cr.execute("SELECT res_id FROM ir_model_data WHERE model='ir.ui.view' AND module=%s AND name=%s", (module, view_ref))
|
||||
view_ref_res = cr.fetchone()
|
||||
if view_ref_res:
|
||||
view_id = view_ref_res[0]
|
||||
|
||||
if view_id:
|
||||
where = (model and (" and model='%s'" % (self._name,))) or ''
|
||||
cr.execute('SELECT arch,name,field_parent,id,type,inherit_id FROM ir_ui_view WHERE id=%s'+where, (view_id,))
|
||||
|
@ -1332,7 +1363,7 @@ class orm_template(object):
|
|||
def name_get(self, cr, user, ids, context=None):
|
||||
raise _('The name_get method is not implemented on this object !')
|
||||
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=None):
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=80):
|
||||
raise _('The name_search method is not implemented on this object !')
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
|
@ -1441,6 +1472,8 @@ class orm_memory(orm_template):
|
|||
return result
|
||||
|
||||
def write(self, cr, user, ids, vals, context=None):
|
||||
if not ids:
|
||||
return True
|
||||
vals2 = {}
|
||||
upd_todo = []
|
||||
for field in vals:
|
||||
|
@ -1773,7 +1806,7 @@ class orm(orm_template):
|
|||
f_pg_notnull = f_pg_def['attnotnull']
|
||||
if isinstance(f, fields.function) and not f.store:
|
||||
logger.notifyChannel('orm', netsvc.LOG_INFO, 'column %s (%s) in table %s removed: converted to a function !\n' % (k, f.string, self._table))
|
||||
cr.execute('ALTER TABLE %s DROP COLUMN %s'% (self._table, k))
|
||||
cr.execute('ALTER TABLE "%s" DROP COLUMN "%s"'% (self._table, k))
|
||||
cr.commit()
|
||||
f_obj_type = None
|
||||
else:
|
||||
|
@ -1786,6 +1819,8 @@ class orm(orm_template):
|
|||
('varchar', 'text', 'TEXT', ''),
|
||||
('int4', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
|
||||
('date', 'datetime', 'TIMESTAMP', '::TIMESTAMP'),
|
||||
('numeric', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
|
||||
('float8', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
|
||||
]
|
||||
# !!! Avoid reduction of varchar field !!!
|
||||
if f_pg_type == 'varchar' and f._type == 'char' and f_pg_size < f.size:
|
||||
|
@ -1798,13 +1833,15 @@ class orm(orm_template):
|
|||
cr.commit()
|
||||
for c in casts:
|
||||
if (f_pg_type==c[0]) and (f._type==c[1]):
|
||||
logger.notifyChannel('orm', netsvc.LOG_INFO, "column '%s' in table '%s' changed type to %s." % (k, self._table, c[1]))
|
||||
ok = True
|
||||
cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k))
|
||||
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, c[2]))
|
||||
cr.execute(('UPDATE "%s" SET "%s"=temp_change_size'+c[3]) % (self._table, k))
|
||||
cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,))
|
||||
cr.commit()
|
||||
if f_pg_type != f_obj_type:
|
||||
logger.notifyChannel('orm', netsvc.LOG_INFO, "column '%s' in table '%s' changed type to %s." % (k, self._table, c[1]))
|
||||
ok = True
|
||||
cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k))
|
||||
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, c[2]))
|
||||
cr.execute(('UPDATE "%s" SET "%s"=temp_change_size'+c[3]) % (self._table, k))
|
||||
cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,))
|
||||
cr.commit()
|
||||
break
|
||||
|
||||
if f_pg_type != f_obj_type:
|
||||
if not ok:
|
||||
|
@ -1817,7 +1854,7 @@ class orm(orm_template):
|
|||
default = self._defaults[k](self, cr, 1, {})
|
||||
if (default is not None):
|
||||
ss = self._columns[k]._symbol_set
|
||||
query = 'UPDATE "%s" SET "%s"=%s WHERE %s is NULL' % (self._table, k, ss[0], k)
|
||||
query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (self._table, k, ss[0], k)
|
||||
cr.execute(query, (ss[1](default),))
|
||||
# add the NOT NULL constraint
|
||||
cr.commit()
|
||||
|
@ -2876,7 +2913,7 @@ class orm(orm_template):
|
|||
return [(r['id'], tools.ustr(r[self._rec_name])) for r in self.read(cr, user, ids,
|
||||
[self._rec_name], context, load='_classic_write')]
|
||||
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=None):
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=80):
|
||||
if not args:
|
||||
args = []
|
||||
if not context:
|
||||
|
|
|
@ -455,10 +455,10 @@ class _rml_flowable(object):
|
|||
if key in ('rml_except', 'rml_loop', 'rml_tag'):
|
||||
del txt_n.attrib[key]
|
||||
if True or not self._textual(n).isspace():
|
||||
txt_n.text = utils.xml2str(self._textual(n))
|
||||
txt_n.tail = ''
|
||||
if not n.tag == 'bullet':
|
||||
txt_n.text = utils.xml2str(self._textual(n))
|
||||
txt_n.tail = n.tail and utils._process_text(self, n.tail.replace('\n','')) or ''
|
||||
rc1 += etree.tostring(txt_n)
|
||||
#rc1 += utils._process_text(self, node.tail or '')
|
||||
return rc1
|
||||
|
||||
def _table(self, node):
|
||||
|
|
|
@ -42,6 +42,9 @@ import reportlab
|
|||
from lxml import etree
|
||||
import copy
|
||||
import tools
|
||||
import locale
|
||||
import netsvc
|
||||
import traceback, sys
|
||||
|
||||
_regex = re.compile('\[\[(.+?)\]\]')
|
||||
|
||||
|
@ -107,9 +110,13 @@ def _process_text(self, txt):
|
|||
result += self.localcontext.get('translate', lambda x:x)(sps.pop(0))
|
||||
if sps:
|
||||
try:
|
||||
txt = eval(sps.pop(0),self.localcontext)
|
||||
except:
|
||||
pass
|
||||
expr = sps.pop(0)
|
||||
txt = eval(expr,self.localcontext)
|
||||
except Exception,e:
|
||||
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 :\n%s\n%s\nexpr: %s' % (tb_s, str(e),
|
||||
expr.encode('utf-8')))
|
||||
if type(txt)==type('') or type(txt)==type(u''):
|
||||
txt2 = str2xml(txt)
|
||||
result += tools.ustr(txt2)
|
||||
|
@ -133,6 +140,15 @@ units = [
|
|||
def unit_get(size):
|
||||
global units
|
||||
if size:
|
||||
if size.find('.') == -1:
|
||||
decimal_point = '.'
|
||||
try:
|
||||
decimal_point = locale.nl_langinfo(locale.RADIXCHAR)
|
||||
except:
|
||||
decimal_point = locale.localeconv()['decimal_point']
|
||||
|
||||
size = size.replace(decimal_point, '.')
|
||||
|
||||
for unit in units:
|
||||
res = unit[0].search(size, 0)
|
||||
if res:
|
||||
|
@ -163,7 +179,7 @@ def attr_get(node, attrs, dict={}):
|
|||
res[key] = int(node.get(key))
|
||||
elif dict[key]=='unit':
|
||||
res[key] = unit_get(node.get(key))
|
||||
elif dict[key] == 'float' :
|
||||
elif dict[key] == 'float' :
|
||||
res[key] = float(node.get(key))
|
||||
return res
|
||||
|
||||
|
|
|
@ -424,14 +424,14 @@ def trans_generate(lang, modules, dbname=None):
|
|||
xml_name = "%s.%s" % (module, encode(xml_name))
|
||||
|
||||
if not pool.get(model):
|
||||
logger.notifyChannel("db", netsvc.LOG_ERROR, "unable to find object %r" % (model,))
|
||||
logger.notifyChannel("db", netsvc.LOG_ERROR, "Unable to find object %r" % (model,))
|
||||
continue
|
||||
|
||||
try:
|
||||
obj = pool.get(model).browse(cr, uid, res_id)
|
||||
except BrowseRecordError:
|
||||
logger.notifyChannel("db", netsvc.LOG_ERROR, "unable to find object %r with id %d" % (model, res_id))
|
||||
exists = pool.get(model).exists(cr, uid, res_id)
|
||||
if not exists:
|
||||
logger.notifyChannel("db", netsvc.LOG_WARNING, "Unable to find object %r with id %d" % (model, res_id))
|
||||
continue
|
||||
obj = pool.get(model).browse(cr, uid, res_id)
|
||||
|
||||
if model=='ir.ui.view':
|
||||
d = xml.dom.minidom.parseString(encode(obj.arch))
|
||||
|
|
Loading…
Reference in New Issue