diff options
| author | Raphael Collet <rco@openerp.com> | 2014-07-06 16:44:26 +0200 |
|---|---|---|
| committer | Antony Lesuisse <al@openerp.com> | 2014-07-06 17:05:41 +0200 |
| commit | cbe2dbb672a6c55d86f2e515f9d1cdfee426ef80 (patch) | |
| tree | d6ff62b719fce32392397783c961b734b1e4c50e /openerp/addons/base/module | |
| parent | d78192c489d3be66cd6487b39f5ce7ba4733a187 (diff) | |
[MERGE] new v8 api by rco
A squashed merge is required as the conversion of the apiculture branch from
bzr to git was not correctly done. The git history contains irrelevant blobs
and commits. This branch brings a lot of changes and fixes, too many to list
exhaustively.
- New orm api, objects are now used instead of ids
- Environements to encapsulates cr uid context while maintaining backward compatibility
- Field compute attribute is a new object oriented way to define function fields
- Shared browse record cache
- New onchange protocol
- Optional copy flag on fields
- Documentation update
- Dead code cleanup
- Lots of fixes
Diffstat (limited to 'openerp/addons/base/module')
4 files changed, 75 insertions, 84 deletions
diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index d0cb6b18f7b..89f3e9d006e 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -48,7 +48,8 @@ from openerp.modules.db import create_categories from openerp.modules import get_module_resource from openerp.tools.parse_version import parse_version from openerp.tools.translate import _ -from openerp.osv import fields, osv, orm +from openerp.osv import osv, orm, fields +from openerp import api, fields as fields2 _logger = logging.getLogger(__name__) @@ -374,34 +375,41 @@ class module(osv.osv): msg = _('Unable to process module "%s" because an external dependency is not met: %s') raise orm.except_orm(_('Error'), msg % (module_name, e.args[0])) - def state_update(self, cr, uid, ids, newstate, states_to_update, context=None, level=100): + @api.multi + def state_update(self, newstate, states_to_update, level=100): if level < 1: raise orm.except_orm(_('Error'), _('Recursion error in modules dependencies !')) + + # whether some modules are installed with demo data demo = False - for module in self.browse(cr, uid, ids, context=context): - mdemo = False + + for module in self: + # determine dependency modules to update/others + update_mods, ready_mods = self.browse(), self.browse() for dep in module.dependencies_id: if dep.state == 'unknown': raise orm.except_orm(_('Error'), _("You try to install module '%s' that depends on module '%s'.\nBut the latter module is not available in your system.") % (module.name, dep.name,)) - ids2 = self.search(cr, uid, [('name', '=', dep.name)]) - if dep.state != newstate: - mdemo = self.state_update(cr, uid, ids2, newstate, states_to_update, context, level - 1) or mdemo + if dep.depend_id.state == newstate: + ready_mods += dep.depend_id else: - od = self.browse(cr, uid, ids2)[0] - mdemo = od.demo or mdemo + update_mods += dep.depend_id + # update dependency modules that require it, and determine demo for module + update_demo = update_mods.state_update(newstate, states_to_update, level=level-1) + module_demo = module.demo or update_demo or any(mod.demo for mod in ready_mods) + demo = demo or module_demo + + # check dependencies and update module itself self.check_external_dependencies(module.name, newstate) - if not module.dependencies_id: - mdemo = module.demo if module.state in states_to_update: - self.write(cr, uid, [module.id], {'state': newstate, 'demo': mdemo}) - demo = demo or mdemo + module.write({'state': newstate, 'demo': module_demo}) + return demo def button_install(self, cr, uid, ids, context=None): # Mark the given modules to be installed. - self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context) + self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context=context) # Mark (recursively) the newly satisfied modules to also be installed @@ -524,7 +532,7 @@ class module(osv.osv): def button_upgrade(self, cr, uid, ids, context=None): depobj = self.pool.get('ir.module.module.dependency') - todo = self.browse(cr, uid, ids, context=context) + todo = list(self.browse(cr, uid, ids, context=context)) self.update_list(cr, uid) i = 0 @@ -598,7 +606,7 @@ class module(osv.osv): for key in values: old = getattr(mod, key) updated = isinstance(values[key], basestring) and tools.ustr(values[key]) or values[key] - if not old == updated: + if (old or updated) and updated != old: updated_values[key] = values[key] if terp.get('installable', True) and mod.state == 'uninstallable': updated_values['state'] = 'uninstalled' @@ -726,6 +734,7 @@ class module(osv.osv): cr.execute('INSERT INTO ir_module_module_dependency (module_id, name) values (%s, %s)', (mod_browse.id, dep)) for dep in (existing - needed): cr.execute('DELETE FROM ir_module_module_dependency WHERE module_id = %s and name = %s', (mod_browse.id, dep)) + self.invalidate_cache(cr, uid, ['dependencies_id'], [mod_browse.id]) def _update_category(self, cr, uid, mod_browse, category='Uncategorized'): current_category = mod_browse.category_id @@ -754,37 +763,47 @@ class module(osv.osv): if not mod.description: _logger.warning('module %s: description is empty !', mod.name) -class module_dependency(osv.osv): + +DEP_STATES = [ + ('uninstallable', 'Uninstallable'), + ('uninstalled', 'Not Installed'), + ('installed', 'Installed'), + ('to upgrade', 'To be upgraded'), + ('to remove', 'To be removed'), + ('to install', 'To be installed'), + ('unknown', 'Unknown'), +] + +class module_dependency(osv.Model): _name = "ir.module.module.dependency" _description = "Module dependency" - 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): - ids = mod_obj.search(cr, uid, [('name', '=', md.name)]) - if ids: - result[md.id] = mod_obj.read(cr, uid, [ids[0]], ['state'])[0]['state'] - else: - result[md.id] = 'unknown' - return result + # the dependency name + name = fields2.Char(index=True) - _columns = { - # The dependency name - 'name': fields.char('Name', select=True), + # the module that depends on it + module_id = fields2.Many2one('ir.module.module', 'Module', ondelete='cascade') - # The module that depends on it - 'module_id': fields.many2one('ir.module.module', 'Module', select=True, ondelete='cascade'), + # the module corresponding to the dependency, and its status + depend_id = fields2.Many2one('ir.module.module', 'Dependency', compute='_compute_depend') + state = fields2.Selection(DEP_STATES, string='Status', compute='_compute_state') + + @api.multi + @api.depends('name') + def _compute_depend(self): + # retrieve all modules corresponding to the dependency names + names = list(set(dep.name for dep in self)) + mods = self.env['ir.module.module'].search([('name', 'in', names)]) + + # index modules by name, and assign dependencies + name_mod = dict((mod.name, mod) for mod in mods) + for dep in self: + dep.depend_id = name_mod.get(dep.name) + + @api.one + @api.depends('depend_id.state') + def _compute_state(self): + self.state = self.depend_id.state or 'unknown' - 'state': fields.function(_state, type='selection', selection=[ - ('uninstallable', 'Uninstallable'), - ('uninstalled', 'Not Installed'), - ('installed', 'Installed'), - ('to upgrade', 'To be upgraded'), - ('to remove', 'To be removed'), - ('to install', 'To be installed'), - ('unknown', 'Unknown'), - ], string='Status', readonly=True, select=True), - } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_import_language.py b/openerp/addons/base/module/wizard/base_import_language.py index d8757605d64..bd554a47c5c 100644 --- a/openerp/addons/base/module/wizard/base_import_language.py +++ b/openerp/addons/base/module/wizard/base_import_language.py @@ -44,7 +44,7 @@ class base_language_import(osv.osv_memory): context = {} this = self.browse(cr, uid, ids[0]) if this.overwrite: - context.update(overwrite=True) + context = dict(context, overwrite=True) fileobj = TemporaryFile('w+') try: fileobj.write(base64.decodestring(this.data)) diff --git a/openerp/addons/base/module/wizard/base_module_update.py b/openerp/addons/base/module/wizard/base_module_update.py index e2d8ce01d4a..2f3d0cc1af2 100644 --- a/openerp/addons/base/module/wizard/base_module_update.py +++ b/openerp/addons/base/module/wizard/base_module_update.py @@ -1,49 +1,23 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## -from openerp.osv import osv, fields - -class base_module_update(osv.osv_memory): - """ Update Module """ +from openerp import models, fields, api +class base_module_update(models.TransientModel): _name = "base.module.update" _description = "Update Module" - _columns = { - 'update': fields.integer('Number of modules updated', readonly=True), - 'add': fields.integer('Number of modules added', readonly=True), - 'state':fields.selection([('init','init'),('done','done')], 'Status', readonly=True), - } - - _defaults = { - 'state': 'init', - } + updated = fields.Integer('Number of modules updated', readonly=True) + added = fields.Integer('Number of modules added', readonly=True) + state = fields.Selection([('init', 'init'), ('done', 'done')], 'Status', readonly=True, default='init') - def update_module(self, cr, uid, ids, context=None): - module_obj = self.pool.get('ir.module.module') - update, add = module_obj.update_list(cr, uid,) - self.write(cr, uid, ids, {'update': update, 'add': add, 'state': 'done'}, context=context) + @api.one + def update_module(self): + self.updated, self.added = self.env['ir.module.module'].update_list() + self.state = 'done' return False - def action_module_open(self, cr, uid, ids, context): + @api.multi + def action_module_open(self): res = { 'domain': str([]), 'name': 'Modules', @@ -54,5 +28,3 @@ class base_module_update(osv.osv_memory): 'type': 'ir.actions.act_window', } return res - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/base/module/wizard/base_module_update_view.xml b/openerp/addons/base/module/wizard/base_module_update_view.xml index 3dccc061593..eff8e790677 100644 --- a/openerp/addons/base/module/wizard/base_module_update_view.xml +++ b/openerp/addons/base/module/wizard/base_module_update_view.xml @@ -13,8 +13,8 @@ <label string="Click on Update below to start the process..." /> </group> <group states="done" > - <field name="update"/> - <field name="add" /> + <field name="updated"/> + <field name="added" /> </group> <footer> <div states="init"> |
