diff options
| author | P. Christeas, O. Dony <> | 2010-11-25 15:22:19 +0100 |
|---|---|---|
| committer | Olivier Dony <odo@openerp.com> | 2010-11-25 15:22:19 +0100 |
| commit | 6a69f37cf063525734645fe2d76e2b6ad7792ee5 (patch) | |
| tree | 86849f688569004bc7dc80ba4e222dbbe7ecaa69 /bin/addons | |
| parent | f4c509bcfb2ca305c889a1bd57d4fd0e8cb6b7a0 (diff) | |
| parent | 897ba61b4b12110e574f86fd414220ae53328761 (diff) | |
[MERGE] many improvements regarding translations, logging, reports, http, speed
bzr revid: odo@openerp.com-20101125142219-8bkqfboyuslzpvyo
Diffstat (limited to 'bin/addons')
| -rw-r--r-- | bin/addons/__init__.py | 4 | ||||
| -rw-r--r-- | bin/addons/base/__openerp__.py | 2 | ||||
| -rw-r--r-- | bin/addons/base/base_data.xml | 2 | ||||
| -rw-r--r-- | bin/addons/base/ir/ir_actions.py | 54 | ||||
| -rw-r--r-- | bin/addons/base/ir/ir_attachment.py | 36 | ||||
| -rw-r--r-- | bin/addons/base/ir/ir_model.py | 17 | ||||
| -rw-r--r-- | bin/addons/base/ir/ir_ui_menu.py | 22 | ||||
| -rw-r--r-- | bin/addons/base/module/module.py | 98 | ||||
| -rw-r--r-- | bin/addons/base/module/wizard/base_language_install.py | 4 | ||||
| -rw-r--r-- | bin/addons/base/module/wizard/base_module_upgrade.py | 3 | ||||
| -rw-r--r-- | bin/addons/base/module/wizard/base_update_translations.py | 6 | ||||
| -rw-r--r-- | bin/addons/base/res/res_user.py | 92 |
12 files changed, 206 insertions, 134 deletions
diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 5476dc198f3..814c701e51f 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -857,7 +857,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""") for (model, name) in cr.fetchall(): model_obj = pool.get(model) - if not isinstance(model_obj, osv.osv.osv_memory): + if model_obj and not isinstance(model_obj, osv.osv.osv_memory): logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name)) # Temporary warning while we remove access rights on osv_memory objects, as they have @@ -873,6 +873,8 @@ def load_modules(db, force_demo=False, status=None, update_module=False): obj = pool.get(model) if obj: obj._check_removed_columns(cr, log=True) + else: + logger.notifyChannel('init', netsvc.LOG_WARNING, "Model %s is referenced but not present in the orm pool!" % model) if report.get_report(): logger.notifyChannel('init', netsvc.LOG_INFO, report) diff --git a/bin/addons/base/__openerp__.py b/bin/addons/base/__openerp__.py index 492c397754d..5c0d833b6ce 100644 --- a/bin/addons/base/__openerp__.py +++ b/bin/addons/base/__openerp__.py @@ -23,7 +23,7 @@ { 'name': 'Base', - 'version': '1.2', + 'version': '1.3', 'category': 'Generic Modules/Base', 'description': """The kernel of OpenERP, needed for all installation.""", 'author': 'OpenERP SA', diff --git a/bin/addons/base/base_data.xml b/bin/addons/base/base_data.xml index 075c44ae63b..01869e6a6a6 100644 --- a/bin/addons/base/base_data.xml +++ b/bin/addons/base/base_data.xml @@ -989,7 +989,7 @@ <field name="name">Zambia</field> <field name="code">zm</field> </record> - <!-- DEPRECATED, News name of Zaire is Democratic Republic of the Congo ! --> + <!-- DEPRECATED, New name of Zaire is Democratic Republic of the Congo ! --> <record id="zr" model="res.country"> <field name="name">Zaire</field> <field name="code">zr</field> diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py index 306ec0c1ef1..a90059bb94d 100644 --- a/bin/addons/base/ir/ir_actions.py +++ b/bin/addons/base/ir/ir_actions.py @@ -26,6 +26,7 @@ import time from tools.config import config from tools.translate import _ import netsvc +import logging import re import copy import os @@ -144,18 +145,22 @@ class act_window(osv.osv): _table = 'ir_act_window' _sequence = 'ir_actions_id_seq' - def _check_model(self, cr, uid, ids, context={}): + def _check_model(self, cr, uid, ids, context=None): for action in self.browse(cr, uid, ids, context): if not self.pool.get(action.res_model): return False if action.src_model and not self.pool.get(action.src_model): return False return True + + def _invalid_model_msg(self, cr, uid, ids, context=None): + return _('Invalid model name in the action definition.') + _constraints = [ - (_check_model, 'Invalid model name in the action definition.', ['res_model','src_model']) + (_check_model, _invalid_model_msg, ['res_model','src_model']) ] - def _views_get_fnc(self, cr, uid, ids, name, arg, context={}): + def _views_get_fnc(self, cr, uid, ids, name, arg, context=None): res={} for act in self.browse(cr, uid, ids): res[act.id]=[(view.view_id.id, view.view_mode) for view in act.view_ids] @@ -171,30 +176,34 @@ class act_window(osv.osv): res[act.id].append((False, t)) return res - def _search_view(self, cr, uid, ids, name, arg, context={}): + def _search_view(self, cr, uid, ids, name, arg, context=None): res = {} def encode(s): if isinstance(s, unicode): return s.encode('utf8') return s - for act in self.browse(cr, uid, ids): + for act in self.browse(cr, uid, ids, context=context): fields_from_fields_get = self.pool.get(act.res_model).fields_get(cr, uid, context=context) search_view_id = False if act.search_view_id: search_view_id = act.search_view_id.id else: - res_view = self.pool.get('ir.ui.view').search(cr, uid, [('model','=',act.res_model),('type','=','search'),('inherit_id','=',False)]) + res_view = self.pool.get('ir.ui.view').search(cr, uid, + [('model','=',act.res_model),('type','=','search'), + ('inherit_id','=',False)], context=context) if res_view: search_view_id = res_view[0] if search_view_id: - field_get = self.pool.get(act.res_model).fields_view_get(cr, uid, search_view_id, 'search', context) + field_get = self.pool.get(act.res_model).fields_view_get(cr, uid, search_view_id, + 'search', context) fields_from_fields_get.update(field_get['fields']) field_get['fields'] = fields_from_fields_get res[act.id] = str(field_get) else: def process_child(node, new_node, doc): for child in node.childNodes: - if child.localName=='field' and child.hasAttribute('select') and child.getAttribute('select')=='1': + if child.localName=='field' and child.hasAttribute('select') \ + and child.getAttribute('select')=='1': if child.childNodes: fld = doc.createElement('field') for attr in child.attributes.keys(): @@ -218,7 +227,7 @@ class act_window(osv.osv): res[act.id] = str(form_arch) return res - def _get_help_status(self, cr, uid, ids, name, arg, context={}): + def _get_help_status(self, cr, uid, ids, name, arg, context=None): activate_tips = self.pool.get('res.users').browse(cr, uid, uid).menu_tips return dict([(id, activate_tips) for id in ids]) @@ -336,7 +345,7 @@ class act_url(osv.osv): } act_url() -def model_get(self, cr, uid, context={}): +def model_get(self, cr, uid, context=None): wkf_pool = self.pool.get('workflow') ids = wkf_pool.search(cr, uid, []) osvs = wkf_pool.read(cr, uid, ids, ['osv']) @@ -381,7 +390,7 @@ server_object_lines() # class actions_server(osv.osv): - def _select_signals(self, cr, uid, context={}): + def _select_signals(self, cr, uid, context=None): cr.execute("SELECT distinct w.osv, t.signal FROM wkf w, wkf_activity a, wkf_transition t \ WHERE w.id = a.wkf_id AND t.act_from = a.id OR t.act_to = a.id AND t.signal!='' \ AND t.signal NOT IN (null, NULL)") @@ -393,13 +402,13 @@ class actions_server(osv.osv): res.append(line) return res - def _select_objects(self, cr, uid, context={}): + def _select_objects(self, cr, uid, context=None): model_pool = self.pool.get('ir.model') ids = model_pool.search(cr, uid, [('name','not ilike','.')]) res = model_pool.read(cr, uid, ids, ['model', 'name']) return [(r['model'], r['name']) for r in res] + [('','')] - def change_object(self, cr, uid, ids, copy_object, state, context={}): + def change_object(self, cr, uid, ids, copy_object, state, context=None): if state == 'object_copy': model_pool = self.pool.get('ir.model') model = copy_object.split(',')[0] @@ -470,7 +479,7 @@ class actions_server(osv.osv): } def get_email(self, cr, uid, action, context): - logger = netsvc.Logger() + logger = logging.getLogger('Workflow') obj_pool = self.pool.get(action.model_id.model) id = context.get('active_id') obj = obj_pool.browse(cr, uid, id) @@ -486,12 +495,12 @@ class actions_server(osv.osv): try: obj = getattr(obj, field) except Exception: - logger.notifyChannel('Workflow', netsvc.LOG_ERROR, 'Failed to parse : %s' % (field)) + logger.exception('Failed to parse: %s', field) return obj def get_mobile(self, cr, uid, action, context): - logger = netsvc.Logger() + logger = logging.getLogger('Workflow') obj_pool = self.pool.get(action.model_id.model) id = context.get('active_id') obj = obj_pool.browse(cr, uid, id) @@ -507,7 +516,7 @@ class actions_server(osv.osv): try: obj = getattr(obj, field) except Exception: - logger.notifyChannel('Workflow', netsvc.LOG_ERROR, 'Failed to parse : %s' % (field)) + logger.exception('Failed to parse: %s', field) return obj @@ -543,7 +552,7 @@ class actions_server(osv.osv): # FIXME: refactor all the eval() calls in run()! def run(self, cr, uid, ids, context=None): - logger = netsvc.Logger() + logger = logging.getLogger(self._name) if context is None: context = {} for action in self.browse(cr, uid, ids, context): @@ -591,18 +600,19 @@ class actions_server(osv.osv): pass if not address: - logger.notifyChannel('email', netsvc.LOG_INFO, 'Partner Email address not Specified!') + logger.info('Partner Email address not Specified!') continue if not user: + logger.info('Email-From address not Specified at server!') raise osv.except_osv(_('Error'), _("Please specify server option --email-from !")) subject = self.merge_message(cr, uid, action.subject, action, context) body = self.merge_message(cr, uid, action.message, action, context) if tools.email_send(user, [address], subject, body, debug=False, subtype='html') == True: - logger.notifyChannel('email', netsvc.LOG_INFO, 'Email successfully send to : %s' % (address)) + logger.info('Email successfully sent to: %s', address) else: - logger.notifyChannel('email', netsvc.LOG_ERROR, 'Failed to send email to : %s' % (address)) + logger.warning('Failed to send email to: %s', address) if action.state == 'trigger': wf_service = netsvc.LocalService("workflow") @@ -616,7 +626,7 @@ class actions_server(osv.osv): #TODO: set the user and password from the system # for the sms gateway user / password # USE smsclient module from extra-addons - logger.notifyChannel('sms', netsvc.LOG_ERROR, 'SMS Facility has not been implemented yet. Use smsclient module!') + logger.warning('SMS Facility has not been implemented yet. Use smsclient module!') if action.state == 'other': res = [] diff --git a/bin/addons/base/ir/ir_attachment.py b/bin/addons/base/ir/ir_attachment.py index fb621ea58fc..eeaef655643 100644 --- a/bin/addons/base/ir/ir_attachment.py +++ b/bin/addons/base/ir/ir_attachment.py @@ -24,16 +24,29 @@ from osv.orm import except_orm import tools class ir_attachment(osv.osv): - def check(self, cr, uid, ids, mode, context=None): + def check(self, cr, uid, ids, mode, context=None, values=None): + """Restricts the access to an ir.attachment, according to referred model + In the 'document' module, it is overriden to relax this hard rule, since + more complex ones apply there. + """ if not ids: return ima = self.pool.get('ir.model.access') - if isinstance(ids, (int, long)): - ids = [ids] - cr.execute('select distinct res_model from ir_attachment where id IN %s', (tuple(ids),)) - for obj in cr.fetchall(): - if obj[0]: - ima.check(cr, uid, obj[0], mode, context=context) + res_ids = {} + if ids: + if isinstance(ids, (int, long)): + ids = [ids] + cr.execute('SELECT DISTINCT res_model, res_id FROM ir_attachment WHERE id = ANY (%s)', (ids,)) + for rmod, rid in cr.fetchall(): + if not (rmod and rid): + continue + res_ids.setdefault(rmod,[]).append(rid) + if values: + if 'res_model' in values and 'res_id' in values: + res_ids.setdefault(values['res_model'],[]).append(values['res_id']) + + for model, mids in res_ids.items(): + self.pool.get(model).check_access_rule(cr, uid, mids, mode, context=context) def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False): @@ -64,7 +77,7 @@ class ir_attachment(osv.osv): return super(ir_attachment, self).read(cr, uid, ids, fields_to_read, context, load) def write(self, cr, uid, ids, vals, context=None): - self.check(cr, uid, ids, 'write', context=context) + self.check(cr, uid, ids, 'write', context=context, values=vals) return super(ir_attachment, self).write(cr, uid, ids, vals, context) def copy(self, cr, uid, id, default=None, context=None): @@ -76,8 +89,7 @@ class ir_attachment(osv.osv): return super(ir_attachment, self).unlink(cr, uid, ids, context) def create(self, cr, uid, values, context=None): - if 'res_model' in values and values['res_model'] != '': - self.pool.get('ir.model.access').check(cr, uid, values['res_model'], 'create', context=context) + self.check(cr, uid, [], mode='create', context=context, values=values) return super(ir_attachment, self).create(cr, uid, values, context) def action_get(self, cr, uid, context=None): @@ -114,11 +126,11 @@ class ir_attachment(osv.osv): 'url': fields.char('Url', size=512, oldname="link"), 'type': fields.selection( [ ('url','URL'), ('binary','Binary'), ], - 'Type', help="Binary File or external URL", required=True), + 'Type', help="Binary File or external URL", required=True, change_default=True), 'create_date': fields.datetime('Date Created', readonly=True), 'create_uid': fields.many2one('res.users', 'Owner', readonly=True), - 'company_id': fields.many2one('res.company', 'Company'), + 'company_id': fields.many2one('res.company', 'Company', change_default=True), } _defaults = { diff --git a/bin/addons/base/ir/ir_model.py b/bin/addons/base/ir/ir_model.py index ff4fc9f0feb..a0040a836df 100644 --- a/bin/addons/base/ir/ir_model.py +++ b/bin/addons/base/ir/ir_model.py @@ -75,10 +75,12 @@ class ir_model(osv.osv): fnct_search=_search_osv_memory, help="Indicates whether this object model lives in memory only, i.e. is not persisted (osv.osv_memory)") } + _defaults = { 'model': lambda *a: 'x_', - 'state': lambda self,cr,uid,ctx={}: (ctx and ctx.get('manual',False)) and 'manual' or 'base', + 'state': lambda self,cr,uid,ctx=None: (ctx and ctx.get('manual',False)) and 'manual' or 'base', } + def _check_model_name(self, cr, uid, ids): for model in self.browse(cr, uid, ids): if model.state=='manual': @@ -88,8 +90,10 @@ class ir_model(osv.osv): return False return True + def _model_name_msg(self, cr, uid, ids, context=None): + return _('The Object name must start with x_ and not contain any special character !') _constraints = [ - (_check_model_name, 'The Object name must start with x_ and not contain any special character !', ['model']), + (_check_model_name, _model_name_msg, ['model']), ] # overridden to allow searching both on model name (model field) @@ -181,8 +185,11 @@ class ir_model_fields(osv.osv): 'selectable': lambda *a: 1, } _order = "id" + def _size_gt_zero_msg(self, cr, user, ids, context=None): + return _('Size of the field can never be less than 1 !') + _sql_constraints = [ - ('size_gt_zero', 'CHECK (size>0)', 'Size of the field can never be less than 1 !'), + ('size_gt_zero', 'CHECK (size>0)',_size_gt_zero_msg ), ] def unlink(self, cr, user, ids, context=None): for field in self.browse(cr, user, ids, context): @@ -381,8 +388,8 @@ class ir_model_data(osv.osv): _defaults = { 'date_init': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), 'date_update': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), - 'noupdate': lambda *a: False, - 'module': lambda *a: '' + 'noupdate': False, + 'module': '' } _sql_constraints = [ ('module_name_uniq', 'unique(name, module)', 'You cannot have multiple records with the same id for the same module !'), diff --git a/bin/addons/base/ir/ir_ui_menu.py b/bin/addons/base/ir/ir_ui_menu.py index b41129f642a..43a5cb5bf76 100644 --- a/bin/addons/base/ir/ir_ui_menu.py +++ b/bin/addons/base/ir/ir_ui_menu.py @@ -19,11 +19,13 @@ # ############################################################################## -from osv import fields, osv +import base64 import re + import tools -import base64 import addons +from osv import fields, osv +from tools.translate import _ def one_in(setA, setB): """Check the presence of an element of setA in setB @@ -69,8 +71,10 @@ class ir_ui_menu(osv.osv): # radical but this doesn't frequently happen self._cache = {} - def create_shortcut(self, cr, uid, values, context={}): + def create_shortcut(self, cr, uid, values, context=None): dataobj = self.pool.get('ir.model.data') + if context is None: + context = {} new_context = context.copy() for key in context: if key.startswith('default_'): @@ -309,13 +313,17 @@ class ir_ui_menu(osv.osv): ('ir.actions.server', 'ir.actions.server'), ]), } + + def _rec_message(self, cr, uid, ids, context=None): + return _('Error ! You can not create recursive Menu.') + _constraints = [ - (_check_recursion, 'Error ! You can not create recursive Menu.', ['parent_id']) + (_check_recursion, _rec_message , ['parent_id']) ] _defaults = { - 'icon' : lambda *a: 'STOCK_OPEN', - 'icon_pict': lambda *a: ('stock', ('STOCK_OPEN','ICON_SIZE_MENU')), - 'sequence' : lambda *a: 10, + 'icon' : 'STOCK_OPEN', + 'icon_pict': ('stock', ('STOCK_OPEN','ICON_SIZE_MENU')), + 'sequence' : 10, } _order = "sequence,id" ir_ui_menu() diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py index 81985332157..1dc507da2f3 100644 --- a/bin/addons/base/module/module.py +++ b/bin/addons/base/module/module.py @@ -27,7 +27,6 @@ import urllib import zipimport import addons -import netsvc import pooler import release import tools @@ -41,7 +40,7 @@ class module_category(osv.osv): _name = "ir.module.category" _description = "Module Category" - def _module_nbr(self,cr,uid, ids, prop, unknow_none,context): + def _module_nbr(self,cr,uid, ids, prop, unknow_none, context): cr.execute('SELECT category_id, COUNT(*) \ FROM ir_module_module \ WHERE category_id IN %(ids)s \ @@ -82,13 +81,13 @@ class module(osv.osv): 'module %s', name, exc_info=True) return info - def _get_latest_version(self, cr, uid, ids, field_name=None, arg=None, context={}): + def _get_latest_version(self, cr, uid, ids, field_name=None, arg=None, context=None): res = dict.fromkeys(ids, '') for m in self.browse(cr, uid, ids): res[m.id] = self.get_module_info(m.name).get('version', '') return res - def _get_views(self, cr, uid, ids, field_name=None, arg=None, context={}): + 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') @@ -99,37 +98,36 @@ class module(osv.osv): for m in mlist: mnames[m.name] = m.id res[m.id] = { - 'menus_by_module':'', - 'reports_by_module':'', - 'views_by_module': '' + 'menus_by_module':[], + 'reports_by_module':[], + 'views_by_module': [] } view_id = model_data_obj.search(cr,uid,[('module','in', mnames.keys()), ('model','in',('ir.ui.view','ir.actions.report.xml','ir.ui.menu'))]) for data_id in model_data_obj.browse(cr,uid,view_id,context): # We use try except, because views or menus may not exist try: - key = data_id['model'] + key = data_id.model if key=='ir.ui.view': - try: - v = view_obj.browse(cr,uid,data_id.res_id) - aa = v.inherit_id and '* INHERIT ' or '' - res[mnames[data_id.module]]['views_by_module'] += aa + v.name + ' ('+v.type+')\n' - except Exception: - self.__logger.debug( - 'Unknown error while browsing ir.ui.view[%s]', - data_id.res_id, exc_info=True) + v = view_obj.browse(cr,uid,data_id.res_id) + aa = v.inherit_id and '* INHERIT ' or '' + res[mnames[data_id.module]]['views_by_module'].append(aa + v.name + '('+v.type+')') elif key=='ir.actions.report.xml': - res[mnames[data_id.module]]['reports_by_module'] += report_obj.browse(cr,uid,data_id.res_id).name + '\n' + res[mnames[data_id.module]]['reports_by_module'].append(report_obj.browse(cr,uid,data_id.res_id).name) elif key=='ir.ui.menu': - try: - m = menu_obj.browse(cr,uid,data_id.res_id) - res[mnames[data_id.module]]['menus_by_module'] += m.complete_name + '\n' - except Exception: - self.__logger.debug( - 'Unknown error while browsing ir.ui.menu[%s]', - data_id.res_id, exc_info=True) - except KeyError: + res[mnames[data_id.module]]['menus_by_module'].append(menu_obj.browse(cr,uid,data_id.res_id).complete_name) + except KeyError, e: + self.__logger.warning( + 'Data not found for reference %s[%s:%s.%s]', data_id.model, + data_id.res_id, data_id.model, data_id.name, exc_info=True) pass + except Exception, e: + self.__logger.warning('Unknown error while browsing %s[%s]', + data_id.model, data_id.res_id, exc_info=True) + pass + for key, value in res.iteritems(): + for k, v in res[key].iteritems() : + res[key][k] = "\n".join(sorted(v)) return res _columns = { @@ -180,16 +178,21 @@ class module(osv.osv): } _defaults = { - 'state': lambda *a: 'uninstalled', - 'demo': lambda *a: False, - 'license': lambda *a: 'AGPL-3', + 'state': 'uninstalled', + 'demo': False, + 'license': 'AGPL-3', 'web': False, } _order = 'name' + def _name_uniq_msg(self, cr, uid, ids, context=None): + return _('The name of the module must be unique !') + def _certificate_uniq_msg(self, cr, uid, ids, context=None): + return _('The certificate ID of the module must be unique !') + _sql_constraints = [ - ('name_uniq', 'unique (name)', 'The name of the module must be unique !'), - ('certificate_uniq', 'unique (certificate)', 'The certificate ID of the module must be unique !') + ('name_uniq', 'UNIQUE (name)',_name_uniq_msg ), + ('certificate_uniq', 'UNIQUE (certificate)',_certificate_uniq_msg ) ] def unlink(self, cr, uid, ids, context=None): @@ -266,14 +269,14 @@ class module(osv.osv): demo = demo or mdemo return demo - def button_install(self, cr, uid, ids, context={}): + def button_install(self, cr, uid, ids, context=None): return self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context) - def button_install_cancel(self, cr, uid, ids, context={}): + def button_install_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'uninstalled', 'demo':False}) return True - def button_uninstall(self, cr, uid, ids, context={}): + def button_uninstall(self, cr, uid, ids, context=None): for module in self.browse(cr, uid, ids): cr.execute('''select m.state,m.name from @@ -289,7 +292,7 @@ class module(osv.osv): self.write(cr, uid, ids, {'state': 'to remove'}) return True - def button_uninstall_cancel(self, cr, uid, ids, context={}): + def button_uninstall_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'installed'}) return True @@ -325,7 +328,7 @@ class module(osv.osv): self.button_install(cr, uid, to_install, context=context) return True - def button_upgrade_cancel(self, cr, uid, ids, context={}): + def button_upgrade_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'installed'}) return True def button_update_translations(self, cr, uid, ids, context=None): @@ -418,7 +421,9 @@ class module(osv.osv): zimp.load_module(mod.name) return res - def _update_dependencies(self, cr, uid, id, depends=[]): + def _update_dependencies(self, cr, uid, id, depends=None): + if depends is None: + depends = [] for d in depends: cr.execute('INSERT INTO ir_module_module_dependency (module_id, name) values (%s, %s)', (id, d)) @@ -441,8 +446,8 @@ class module(osv.osv): categs = categs[1:] self.write(cr, uid, [id], {'category_id': p_id}) - def update_translations(self, cr, uid, ids, filter_lang=None, context={}): - logger = netsvc.Logger() + def update_translations(self, cr, uid, ids, filter_lang=None, context=None): + logger = logging.getLogger('i18n') if not filter_lang: pool = pooler.get_pool(cr.dbname) lang_obj = pool.get('res.lang') @@ -462,13 +467,18 @@ class module(osv.osv): if len(lang) > 5: raise osv.except_osv(_('Error'), _('You Can Not Load Translation For language Due To Invalid Language/Country Code')) iso_lang = tools.get_iso_codes(lang) - f = os.path.join(modpath, 'i18n', iso_lang + '.po') - if not os.path.exists(f) and iso_lang.find('_') != -1: - f = os.path.join(modpath, 'i18n', iso_lang.split('_')[0] + '.po') + f = addons.get_module_resource(mod.name, 'i18n', iso_lang + '.po') + # Implementation notice: we must first search for the full name of + # the language derivative, like "en_UK", and then the generic, + # like "en". + if (not f) and '_' in iso_lang: + f = addons.get_module_resource(mod.name, 'i18n', iso_lang.split('_')[0] + '.po') iso_lang = iso_lang.split('_')[0] - if os.path.exists(f): - logger.notifyChannel("i18n", netsvc.LOG_INFO, 'module %s: loading translation file for language %s' % (mod.name, iso_lang)) + if f: + logger.info('module %s: loading translation file for language %s', mod.name, iso_lang) tools.trans_load(cr.dbname, f, lang, verbose=False, context=context) + else: + logger.warning('module %s: no translation for language %s', mod.name, iso_lang) def check(self, cr, uid, ids, context=None): logger = logging.getLogger('init') @@ -537,7 +547,7 @@ class module_dependency(osv.osv): _name = "ir.module.module.dependency" _description = "Module dependency" - def _state(self, cr, uid, ids, name, args, context={}): + def _state(self, cr, uid, ids, name, args, context=None): result = {} mod_obj = self.pool.get('ir.module.module') for md in self.browse(cr, uid, ids): diff --git a/bin/addons/base/module/wizard/base_language_install.py b/bin/addons/base/module/wizard/base_language_install.py index 9cdae41ad2b..f7b469f85ed 100644 --- a/bin/addons/base/module/wizard/base_language_install.py +++ b/bin/addons/base/module/wizard/base_language_install.py @@ -38,7 +38,9 @@ class base_language_install(osv.osv_memory): 'state': 'init', 'overwrite': False } - def lang_install(self, cr, uid, ids, context): + def lang_install(self, cr, uid, ids, context=None): + if context is None: + context = {} language_obj = self.browse(cr, uid, ids)[0] lang = language_obj.lang if lang: diff --git a/bin/addons/base/module/wizard/base_module_upgrade.py b/bin/addons/base/module/wizard/base_module_upgrade.py index de9df1ec3e0..d712b3ccf77 100644 --- a/bin/addons/base/module/wizard/base_module_upgrade.py +++ b/bin/addons/base/module/wizard/base_module_upgrade.py @@ -20,6 +20,7 @@ ############################################################################## import pooler +import wizard from osv import osv, fields class base_module_upgrade(osv.osv_memory): @@ -80,7 +81,7 @@ class base_module_upgrade(osv.osv_memory): res = mod_obj.read(cr, uid, ids, ['name','state'], context) return {'module_info': '\n'.join(map(lambda x: x['name']+' : '+x['state'], res))} - def upgrade_module(self, cr, uid, ids, context): + def upgrade_module(self, cr, uid, ids, context=None): pool = pooler.get_pool(cr.dbname) mod_obj = self.pool.get('ir.module.module') data_obj = self.pool.get('ir.model.data') diff --git a/bin/addons/base/module/wizard/base_update_translations.py b/bin/addons/base/module/wizard/base_update_translations.py index b413e9d7093..6b329cf1212 100644 --- a/bin/addons/base/module/wizard/base_update_translations.py +++ b/bin/addons/base/module/wizard/base_update_translations.py @@ -35,7 +35,7 @@ class base_update_translations(osv.osv_memory): lang_obj=pooler.get_pool(cr.dbname).get('res.lang') ids=lang_obj.search(cr, uid, [('code', '=', lang_code)]) if not ids: - raise osv.except_osv(_('No language with code "%s" exists') % lang_code) + raise osv.except_osv(_('Error!'), _('No language with code "%s" exists') % lang_code) lang = lang_obj.browse(cr, uid, ids[0]) return lang.name def act_cancel(self, cr, uid, ids, context=None): @@ -51,12 +51,14 @@ class base_update_translations(osv.osv_memory): return {'type': 'ir.actions.act_window_close'} def default_get(self, cr, uid, fields, context=None): + if context is None: + context = {} res = super(base_update_translations, self).default_get(cr, uid, fields, context=context) if context.get('active_model') != "res.lang": return res - record_id = context and context.get('active_id', False) or False + record_id = context.get('active_id', False) or False if record_id: lang = self.pool.get('res.lang').browse(cr, uid, record_id).code res.update(lang=lang) diff --git a/bin/addons/base/res/res_user.py b/bin/addons/base/res/res_user.py index 543185530e3..72ec45e3e76 100644 --- a/bin/addons/base/res/res_user.py +++ b/bin/addons/base/res/res_user.py @@ -46,7 +46,7 @@ class groups(osv.osv): ('name_uniq', 'unique (name)', 'The name of the group must be unique !') ] - def copy(self, cr, uid, id, default=None, context={}): + def copy(self, cr, uid, id, default=None, context=None): group_name = self.read(cr, uid, [id], ['name'])[0]['name'] default.update({'name': _('%s (copy)')%group_name}) return super(groups, self).copy(cr, uid, id, default, context) @@ -83,14 +83,14 @@ class groups(osv.osv): groups() -def _lang_get(self, cr, uid, context={}): +def _lang_get(self, cr, uid, context=None): obj = self.pool.get('res.lang') ids = obj.search(cr, uid, [('translatable','=',True)]) - res = obj.read(cr, uid, ids, ['code', 'name'], context) + res = obj.read(cr, uid, ids, ['code', 'name'], context=context) res = [(r['code'], r['name']) for r in res] return res -def _tz_get(self,cr,uid, context={}): +def _tz_get(self,cr,uid, context=None): return [(x, x) for x in pytz.all_timezones] class users(osv.osv): @@ -315,9 +315,9 @@ class users(osv.osv): return result _defaults = { - 'password' : lambda *a : '', - 'context_lang': lambda *args: 'en_US', - 'active' : lambda *a: True, + 'password' : '', + 'context_lang': 'en_US', + 'active' : True, 'menu_id': _get_menu, 'company_id': _get_company, 'company_ids': _get_companies, @@ -373,7 +373,7 @@ class users(osv.osv): ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit) return self.name_get(cr, user, ids) - def copy(self, cr, uid, id, default=None, context={}): + def copy(self, cr, uid, id, default=None, context=None): user2copy = self.read(cr, uid, [id], ['login','name'])[0] if default is None: default = {} @@ -395,25 +395,28 @@ class users(osv.osv): result[k[8:]] = res or False return result - def action_get(self, cr, uid, context={}): + def action_get(self, cr, uid, context=None): dataobj = self.pool.get('ir.model.data') data_id = dataobj._get_id(cr, 1, 'base', 'action_res_users_my') - return dataobj.browse(cr, uid, data_id, context).res_id + return dataobj.browse(cr, uid, data_id, context=context).res_id def login(self, db, login, password): if not password: return False cr = pooler.get_db(db).cursor() - cr.execute('select id from res_users where login=%s and password=%s and active', (tools.ustr(login), tools.ustr(password))) - res = cr.fetchone() - result = False - if res: - cr.execute("update res_users set date=%s where id=%s", (time.strftime('%Y-%m-%d %H:%M:%S'),res[0])) + try: + cr.execute('UPDATE res_users SET date=now() WHERE login=%s AND password=%s AND active RETURNING id', + (tools.ustr(login), tools.ustr(password))) + res = cr.fetchone() cr.commit() - result = res[0] - cr.close() - return result + if res: + return res[0] + else: + return False + finally: + cr.close() + def check_super(self, passwd): if passwd == tools.config['admin_passwd']: return True @@ -427,29 +430,34 @@ class users(osv.osv): if (cached_pass is not None) and cached_pass == passwd: return True cr = pooler.get_db(db).cursor() - cr.execute('select count(1) from res_users where id=%s and password=%s and active=%s', (int(uid), passwd, True)) - res = cr.fetchone()[0] - cr.close() - if not bool(res): - raise security.ExceptionNoTb('AccessDenied') - if res: - if self._uid_cache.has_key(db): - ulist = self._uid_cache[db] - ulist[uid] = passwd - else: - self._uid_cache[db] = {uid:passwd} - return bool(res) + try: + cr.execute('SELECT COUNT(1) FROM res_users WHERE id=%s AND password=%s AND active=%s', + (int(uid), passwd, True)) + res = cr.fetchone()[0] + if not bool(res): + raise security.ExceptionNoTb('AccessDenied') + if res: + if self._uid_cache.has_key(db): + ulist = self._uid_cache[db] + ulist[uid] = passwd + else: + self._uid_cache[db] = {uid:passwd} + return bool(res) + finally: + cr.close() def access(self, db, uid, passwd, sec_level, ids): if not passwd: return False cr = pooler.get_db(db).cursor() - cr.execute('select id from res_users where id=%s and password=%s', (uid, passwd)) - res = cr.fetchone() - cr.close() - if not res: - raise security.ExceptionNoTb('Bad username or password') - return res[0] + try: + cr.execute('SELECT id FROM res_users WHERE id=%s AND password=%s', (uid, passwd)) + res = cr.fetchone() + if not res: + raise security.ExceptionNoTb('Bad username or password') + return res[0] + finally: + cr.close() users() @@ -512,9 +520,19 @@ class groups2(osv.osv): ##FIXME: Is there a reason to inherit this object ? } def unlink(self, cr, uid, ids, context=None): + group_users = [] for record in self.read(cr, uid, ids, ['users'], context=context): if record['users']: - raise osv.except_osv(_('Warning !'), _('Make sure you have no users linked with the group(s)!')) + group_users.extend(record['users']) + + if group_users: + user_names = [user.name for user in self.pool.get('res.users').browse(cr, uid, group_users, context=context)] + if len(user_names) >= 5: + user_names = user_names[:5] + user_names += '...' + raise osv.except_osv(_('Warning !'), + _('Group(s) cannot be deleted, because some user(s) still belong to them: %s !') % \ + ', '.join(user_names)) return super(groups2, self).unlink(cr, uid, ids, context=context) groups2() |
