[imp] Split modules selection from actual installation, add handling of hooks and additionals

* Hooks are functions executed when a given module has been selected for installation
  - Named ``_if_%(module_name)s``
  - Provided cr, uid, ids and context
  - If they return something, it must be an iterable of supplementary addons to install
* Additionals are module sets to install when a given set of 1..n module(s) is selected for installation
  - ``_install_if`` class member
  - dictionary of {tuple: iterable}, the tuple is the set of modules to check for,
    the iterable is the set of modules to install if the condition modules are all
    present

bzr revid: xmo@tinyerp.com-20100106115454-r8qrooqkfvy5kg41
This commit is contained in:
Xavier Morel 2010-01-06 12:54:54 +01:00
parent bf462bb02b
commit fa1a8fe6be
1 changed files with 31 additions and 11 deletions

View File

@ -117,19 +117,39 @@ class res_config_installer(osv.osv_memory):
_name = 'res.config.installer'
_inherit = 'res.config'
_install_if = {}
def _modules_to_install(self, cr, uid, ids, context=None):
base = set(module_name
for installer in self.read(cr, uid, ids, context=context)
for module_name, to_install in installer.iteritems()
if module_name != 'id'
if type(self._columns[module_name]) is fields.boolean
if to_install)
hooks_results = set()
for module in base:
hook = getattr(self, '_if_%s'%(module), None)
if hook:
hooks_results.update(hook(cr, uid, ids, context=None) or set())
additionals = set(
module for requirements, consequences \
in self._install_if.iteritems()
if base.issuperset(requirements)
for module in consequences)
return base | hooks_results | additionals
def execute(self, cr, uid, ids, context=None):
modules = self.pool.get('ir.module.module')
for installer in self.read(cr, uid, ids):
for addon_name, to_install in installer.iteritems():
if addon_name != 'id' and to_install:
self.logger.notifyChannel(
'installer', netsvc.LOG_INFO,
'Selecting addon "%s" to install'%addon_name)
modules.button_install(
cr, uid,
modules.search(cr, uid, [('name','=',addon_name)]),
context=context)
for module in self._modules_to_install(cr, uid, ids, context=context):
self.logger.notifyChannel(
'installer', netsvc.LOG_INFO,
'Selecting addon "%s" to install'%module)
modules.button_install(
cr, uid,
modules.search(cr, uid, [('name','=',module)]),
context=context)
cr.commit()
pooler.restart_pool(cr.dbname, update_module=True)