diff options
Diffstat (limited to 'addons/website_theme_install/models/ir_module_module.py')
| -rw-r--r-- | addons/website_theme_install/models/ir_module_module.py | 267 |
1 files changed, 166 insertions, 101 deletions
diff --git a/addons/website_theme_install/models/ir_module_module.py b/addons/website_theme_install/models/ir_module_module.py index 51c225655df..8f7515c3a10 100644 --- a/addons/website_theme_install/models/ir_module_module.py +++ b/addons/website_theme_install/models/ir_module_module.py @@ -40,110 +40,183 @@ class IrModuleModule(models.Model): records |= self.env[model_name].with_context(active_test=False).browse(imd_ids) return records - @api.multi - def _load_one_theme_module(self, website, loaded): - # loaded is a dict updated in place ! - # keep previous record created to update overrided record - _logger.info('Load theme %s for website %s from template.' % (self.mapped('name'), website.id)) - - for attach in self._get_module_data('theme.ir.attachment'): - already_create = loaded['attachments'].filtered(lambda x: x.key == attach.key) - new_attach = { - 'key': attach.key, - 'public': True, - 'res_model': 'ir.ui.view', - 'type': 'url', - 'name': attach.name, - 'url': attach.url, - 'website_id': website.id, - 'theme_template_id': attach.id, - } - if already_create: - already_create.update(new_attach) - else: # if module B override attachment from dependence A - loaded['attachments'] += self.env['ir.attachment'].create(new_attach) - - for view in self._get_module_data('theme.ir.ui.view'): - if view.inherit_id and view.inherit_id._name == 'theme.ir.ui.view': - view.inherit_id = loaded['views'].filtered(lambda x: x.theme_template_id == view.inherit_id) - - new_view = { - 'type': view.type or 'qweb', - 'name': view.name, - 'arch': view.arch, - 'key': view.key, - 'arch_fs': view.arch_fs, - 'priority': view.priority, - 'active': view.active, - 'inherit_id': view.inherit_id and view.inherit_id.id, - 'theme_template_id': view.id, - 'website_id': website.id, - } - if view.mode: # if not provided, computed automatically (if inherit_id or not) - new_view['mode'] = view.mode - loaded['views'] += self.env['ir.ui.view'].create(new_view) - - for page in self._get_module_data('theme.website.page'): - new_page = { - 'url': page.url, - 'view_id': loaded['views'].filtered(lambda x: x.theme_template_id == page.view_id).id, - 'website_indexed': page.website_indexed, - 'theme_template_id': page.id, - } - loaded['pages'] += self.env['website.page'].create(new_page) - - for menu in self._get_module_data('theme.website.menu'): - new_menu = { - 'name': menu.name, - 'url': menu.url, - 'page_id': loaded['pages'].filtered(lambda x: x.theme_template_id == menu.page_id).id, - 'new_window': menu.new_window, - 'sequence': menu.sequence, - 'parent_id': loaded['menus'].filtered(lambda x: x.theme_template_id == menu.parent_id).id, - 'theme_template_id': menu.id, - } - loaded['menus'] += self.env['website.menu'].create(new_menu) - - return True + def _convert_attachment(self, attach, website, **kw): + new_attach = { + 'key': attach.key, + 'public': True, + 'res_model': 'ir.ui.view', + 'type': 'url', + 'name': attach.name, + 'url': attach.url, + 'website_id': website.id, + 'theme_template_id': attach.id, + } + return new_attach + + def _convert_view(self, view, website, **kw): + inherit = view.inherit_id + if view.inherit_id and view.inherit_id._name == 'theme.ir.ui.view': + inherit = view.inherit_id.copy_ids.filtered(lambda x: x.website_id == website) + if not inherit: + # inherit_id not yet created, add to the queue + return False + new_view = { + 'type': view.type or 'qweb', + 'name': view.name, + 'arch': view.arch, + 'key': view.key, + 'inherit_id': inherit and inherit.id, + 'arch_fs': view.arch_fs, + 'priority': view.priority, + 'active': view.active, + 'theme_template_id': view.id, + 'website_id': website.id, + } - @api.multi - def _unload_one_theme_module(self, website): - _logger.info('Unload theme %s for website %s from template.' % (self.mapped('name'), website.id)) + if view.mode: # if not provided, it will be computed automatically (if inherit_id or not) + new_view['mode'] = view.mode - for module in self: - menus = module._get_module_data('theme.website.menu') - menu_todel = menus.with_context(active_test=False).mapped('copy_ids').filtered(lambda m: m.website_id == website) - menu_todel.unlink() + return new_view - pages = module._get_module_data('theme.website.page') - pages_todel = pages.with_context(active_test=False).mapped('copy_ids').filtered(lambda p: p.website_id == website) - pages_todel.unlink() + def _convert_page(self, page, website, **kw): + new_page = { + 'url': page.url, + 'view_id': page.view_id.copy_ids.filtered(lambda x: x.website_id == website), + 'website_indexed': page.website_indexed, + 'theme_template_id': page.id, + } + return new_page + + def _convert_menu(self, menu, website, **kw): + page_id = menu.page_id.copy_ids.filtered(lambda x: x.website_id == website) + parent_id = menu.copy_ids.filtered(lambda x: x.website_id == website) + new_menu = { + 'name': menu.name, + 'url': menu.url, + 'page_id': page_id, + 'new_window': menu.new_window, + 'sequence': menu.sequence, + 'parent_id': parent_id, + 'theme_template_id': menu.id, + } + return new_menu + + def _convert(self, model): + if model == 'ir.ui.view': + return self._convert_view + elif model == 'ir.attachment': + return self._convert_attachment + elif model == 'website.menu': + return self._convert_menu + elif model == 'website.page': + return self._convert_page + else: + _logger.error('No converter found for %s', model) + + def _update_records(self, old, new): + # This function: + # create new record if not in old + # update old record if already exists + # delete old record that are not in new + website = self.env['website'].get_current_website() + model = old._name + created = self.env[model] + updated = self.env[model] + deleted = self.env[model] + + remaining = new + last_len = -1 + while (len(remaining) != last_len): + last_len = len(remaining) + for rec in remaining: + rec_data = self._convert(model)(rec, website) + if not rec_data: + _logger.info('Record queued: %s' % rec.name) + continue + + find = rec.with_context(active_test=False).mapped('copy_ids').filtered(lambda m: m.website_id == website) + + # special case for attachment + # if module B override attachment from dependence A, we update it + if not find and model == 'ir.attachment': + find = rec.copy_ids.search([('key', '=', rec.key), ('website_id', '=', website.id)]) + + if model == 'ir.ui.view': + rec_data.pop('active') + + if find: + imd = self.env['ir.model.data'].search([('model', '=', find._name), ('res_id', '=', find.id)]) + if imd and imd.noupdate: + _logger.info('Noupdate set for %s (%s)' % (find, imd)) + continue + find.update(rec_data) + updated += find + else: + created += self.env[model].create(rec_data) + remaining -= rec + + deleted = old - updated + deleted.unlink() + return (created, updated, deleted) + + def _load_one_theme_module(self, website, with_update=True, **kw): + # load data from xml to template table + old_menus = self._get_module_data('theme.website.menu').with_context(active_test=False).mapped('copy_ids').filtered(lambda m: m.website_id == website) + old_pages = self._get_module_data('theme.website.page').with_context(active_test=False).mapped('copy_ids').filtered(lambda p: p.website_id == website) + old_attachs = self._get_module_data('theme.ir.attachment').with_context(active_test=False).mapped('copy_ids').filtered(lambda a: a.website_id == website) + old_views = self._get_module_data('theme.ir.ui.view').with_context(active_test=False).mapped('copy_ids').filtered(lambda v: v.website_id == website) + + if with_update: + self.button_immediate_upgrade() - attachs = module._get_module_data('theme.ir.attachment') - atachs_todel = attachs.with_context(active_test=False).mapped('copy_ids').filtered(lambda a: a.website_id == website) - atachs_todel.unlink() + new_menus = self._get_module_data('theme.website.menu') + new_pages = self._get_module_data('theme.website.page') + new_attachs = self._get_module_data('theme.ir.attachment') + new_views = self._get_module_data('theme.ir.ui.view') - views = module._get_module_data('theme.ir.ui.view') - views_todel = views.with_context(active_test=False).mapped('copy_ids').filtered(lambda v: v.website_id == website) - # double check - Some records that can be orpahns or no more in the template view. - views_todel2 = self.env['ir.ui.view'].with_context(active_test=False).search([('key', '=like', self.name + '_%'), ('website_id', '=', website.id)]) - (views_todel + views_todel2).unlink() + self._update_records(old_menus, new_menus) + self._update_records(old_pages, new_pages) + self._update_records(old_attachs, new_attachs) + self._update_records(old_views, new_views) + @api.multi + def _unload_one_theme_module(self, website): + self.ensure_one() + _logger.info('Unload theme %s for website %s from template.' % (self.mapped('name'), website.id)) + menus = self._get_module_data('theme.website.menu') + menu_todel = menus.with_context(active_test=False).mapped('copy_ids').filtered(lambda m: m.website_id == website) + menu_todel.unlink() + + pages = self._get_module_data('theme.website.page') + pages_todel = pages.with_context(active_test=False).mapped('copy_ids').filtered(lambda p: p.website_id == website) + pages_todel.unlink() + + attachs = self._get_module_data('theme.ir.attachment') + attachs_todel = attachs.with_context(active_test=False).mapped('copy_ids').filtered(lambda a: a.website_id == website) + # double check - Some records that can be orphans or no more in the template view. + attachs_todel2 = self.env['ir.attachment'].with_context(active_test=False).search([('key', '=like', self.name + '_%'), ('website_id', '=', website.id)]) + (attachs_todel + attachs_todel2).unlink() + + views = self._get_module_data('theme.ir.ui.view') + views_todel = views.with_context(active_test=False).mapped('copy_ids').filtered(lambda v: v.website_id == website) + # double check - Some records that can be orphans or no more in the template view. + views_todel2 = self.env['ir.ui.view'].with_context(active_test=False).search([('key', '=like', self.name + '_%'), ('website_id', '=', website.id)]) + (views_todel + views_todel2).unlink() + + @api.multi def _remove_theme_on_website(self, website): + self.ensure_one() installed_deps = self + website.theme_id.upstream_dependencies(exclude_states=('',)).filtered(lambda x: x.name.startswith('theme_')) for mod in installed_deps: mod._unload_one_theme_module(website) - def _copy_theme_on_website(self, website): - loaded = { - 'views': self.env['ir.ui.view'], - 'attachments': self.env['ir.attachment'], - 'pages': self.env['website.page'], - 'menus': self.env['website.menu'], - } + @api.multi + def _add_theme_on_website(self, website): + self.ensure_one() mods_to_load = reversed(self + self.upstream_dependencies(exclude_states=('',)).filtered(lambda x: x.name.startswith('theme_'))) for mod in mods_to_load: - mod._load_one_theme_module(website, loaded) + _logger.info('Load theme %s for website %s from template.' % (self.mapped('name'), website.id)) + self._load_one_theme_module(website, with_update=False) self.env['theme.utils']._post_copy(mod) @api.multi @@ -166,7 +239,7 @@ class IrModuleModule(models.Model): self = self.env()[self._name].browse(self.id) # Copy new theme from template table to real table - self._copy_theme_on_website(website) + self._add_theme_on_website(website) # Alter next action for redirect if not next_action: @@ -183,15 +256,7 @@ class IrModuleModule(models.Model): def button_refresh_theme(self): website = self.env['website'].get_current_website() - # load data from xml to template table - self.button_immediate_upgrade() - - # delete current theme - # todo: quid of no_update record? - self.button_remove_theme() - - # copy data from template table to real table - self._copy_theme_on_website(website) + self._load_one_theme_module(website, with_update=True) @api.model def update_list(self): |
