From ffdcf3367353028ba0ee72fedc0dd91aae943be2 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 19 Sep 2013 13:45:08 +0200 Subject: [PATCH 1/4] [IMP] ir.ui.view: log traceback when validation of view arch fail bzr revid: chs@openerp.com-20130919114508-72pv3u1stxw4l3ry --- openerp/addons/base/ir/ir_ui_view.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index f46ac13af42..794f3fcd826 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -129,6 +129,7 @@ class view(osv.osv): fvg = self.pool[view.model].fields_view_get(cr, uid, view_id=view.id, view_type=view.type, context=context) return fvg['arch'] except Exception: + _logger.exception('cannot render view %s', view.xml_id) return False def _check_xml(self, cr, uid, ids, context=None): From 28b09221d6b0673edd6eda7708d66bc7f76869cb Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 19 Sep 2013 13:47:11 +0200 Subject: [PATCH 2/4] [FIX] orm.BaseModel.exists(): early return if no ids given bzr revid: chs@openerp.com-20130919114711-ofx2aubtr5z7dgh4 --- openerp/osv/orm.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 83346cae8b3..608b8043706 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -5117,6 +5117,8 @@ class BaseModel(object): """ if type(ids) in (int, long): ids = [ids] + if not ids: + return [] query = 'SELECT id FROM "%s"' % self._table cr.execute(query + "WHERE ID IN %s", (tuple(ids),)) return [x[0] for x in cr.fetchall()] From ef96f0424a0e26dbab23a049be9e8103ee93c586 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 19 Sep 2013 13:50:14 +0200 Subject: [PATCH 3/4] [IMP] ir.module.module: _get_views(): explictly skip non-existing records instead of catching exceptions. This avoid useless error logs bzr revid: chs@openerp.com-20130919115014-bwjaar877w04k41s --- openerp/addons/base/module/module.py | 40 +++++++++++----------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 39d59a4ab2c..e160c49481e 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -24,6 +24,7 @@ from docutils.transforms import Transform, writer_aux from docutils.writers.html4css1 import Writer import imp import logging +from operator import attrgetter import os import re import shutil @@ -178,9 +179,6 @@ class module(osv.osv): def _get_views(self, cr, uid, ids, field_name=None, arg=None, context=None): res = {} model_data_obj = self.pool.get('ir.model.data') - view_obj = self.pool.get('ir.ui.view') - report_obj = self.pool.get('ir.actions.report.xml') - menu_obj = self.pool.get('ir.ui.menu') dmodels = [] if field_name is None or 'views_by_module' in field_name: @@ -192,7 +190,7 @@ class module(osv.osv): assert dmodels, "no models for %s" % field_name for module_rec in self.browse(cr, uid, ids, context=context): - res[module_rec.id] = { + res_mod_dic = res[module_rec.id] = { 'menus_by_module': [], 'reports_by_module': [], 'views_by_module': [] @@ -212,28 +210,20 @@ class module(osv.osv): for imd_res in model_data_obj.read(cr, uid, imd_ids, ['model', 'res_id'], context=context): imd_models[imd_res['model']].append(imd_res['res_id']) - # For each one of the models, get the names of these ids. - # We use try except, because views or menus may not exist. - try: - res_mod_dic = res[module_rec.id] - view_ids = imd_models.get('ir.ui.view', []) - for v in view_obj.browse(cr, uid, view_ids, context=context): - aa = v.inherit_id and '* INHERIT ' or '' - res_mod_dic['views_by_module'].append('%s%s (%s)' % (aa, v.name, v.type)) + def browse(model): + M = self.pool[model] + # as this method is called before the module update, some xmlid may be invalid at this stage + # explictly filter records before reading them + ids = M.exists(cr, uid, imd_models.get(model, []), context) + return M.browse(cr, uid, ids, context) - report_ids = imd_models.get('ir.actions.report.xml', []) - for rx in report_obj.browse(cr, uid, report_ids, context=context): - res_mod_dic['reports_by_module'].append(rx.name) + def format_view(v): + aa = v.inherit_id and '* INHERIT ' or '' + return '%s%s (%s)' % (aa, v.name, v.type) - menu_ids = imd_models.get('ir.ui.menu', []) - for um in menu_obj.browse(cr, uid, menu_ids, context=context): - res_mod_dic['menus_by_module'].append(um.complete_name) - except KeyError, e: - _logger.warning('Data not found for items of %s', module_rec.name) - except AttributeError, e: - _logger.warning('Data not found for items of %s %s', module_rec.name, str(e)) - except Exception, e: - _logger.warning('Unknown error while fetching data of %s', module_rec.name, exc_info=True) + res_mod_dic['views_by_module'] = map(format_view, browse('ir.ui.view')) + res_mod_dic['reports_by_module'] = map(attrgetter('name'), browse('ir.actions.report.xml')) + res_mod_dic['menus_by_module'] = map(attrgetter('complete_name'), browse('ir.ui.menu')) for key in res.iterkeys(): for k, v in res[key].iteritems(): @@ -624,7 +614,7 @@ class module(osv.osv): # wsgi handlers, so they can react accordingly if tuple(res) != (0, 0): for handler in openerp.service.wsgi_server.module_handlers: - if hasattr(handler,'load_addons'): + if hasattr(handler, 'load_addons'): handler.load_addons() return res From fcd47fbd9f289f3087f865d7ac796666aa9ece38 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 19 Sep 2013 16:46:58 +0200 Subject: [PATCH 4/4] [IMP] im: tell orm to rename field user => user_id bzr revid: chs@openerp.com-20130919144658-tf53x1zimnvbsk0u --- addons/im/im.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/im/im.py b/addons/im/im.py index f91017e1712..3c4f0bfcd14 100644 --- a/addons/im/im.py +++ b/addons/im/im.py @@ -303,7 +303,7 @@ class im_user(osv.osv): 'name': fields.function(_get_name, type='char', size=200, string="Name", store=True, readonly=True), 'assigned_name': fields.char(string="Assigned Name", size=200, required=False), 'image': fields.related('user_id', 'image_small', type='binary', string="Image", readonly=True), - 'user_id': fields.many2one("res.users", string="User", select=True, ondelete='cascade'), + 'user_id': fields.many2one("res.users", string="User", select=True, ondelete='cascade', oldname='user'), 'uuid': fields.char(string="UUID", size=50, select=True), 'im_last_received': fields.integer(string="Instant Messaging Last Received Message"), 'im_last_status': fields.boolean(strint="Instant Messaging Last Status"),