summaryrefslogtreecommitdiff
path: root/addons/website_theme_install/models/ir_module_module.py
diff options
context:
space:
mode:
authorJeremy Kersten <jke@odoo.com>2018-09-18 19:27:55 +0200
committerJeremy Kersten <jke@odoo.com>2018-09-21 18:20:00 +0200
commit663da0684a5d4fd2f2b7a9b942ce7e6c398624cd (patch)
treeaa45d12170794e8c6dd8dbfa6647e46db899cfdc /addons/website_theme_install/models/ir_module_module.py
parent39d1d3013f60f655eb0a3f99e0de7aa5925e9f37 (diff)
[FIX] website: improve update theme
Before this commit, it remove and reload the theme. Now we try to make a real update of view except for active field We cannot know if it is True into the template or if it is the default value.
Diffstat (limited to 'addons/website_theme_install/models/ir_module_module.py')
-rw-r--r--addons/website_theme_install/models/ir_module_module.py267
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):