[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.
This commit is contained in:
@@ -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))
|
||||
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
|
||||
|
||||
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)
|
||||
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,
|
||||
}
|
||||
|
||||
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)
|
||||
if view.mode: # if not provided, it will be computed automatically (if inherit_id or not)
|
||||
new_view['mode'] = view.mode
|
||||
|
||||
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)
|
||||
return 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)
|
||||
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
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
return True
|
||||
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()
|
||||
|
||||
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')
|
||||
|
||||
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()
|
||||
|
||||
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()
|
||||
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()
|
||||
|
||||
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()
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
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()
|
||||
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):
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</div>
|
||||
<div t-attf-class="bg-gray-lighter #{has_screenshot? 'o_theme_screenshot' : (has_image ? 'o_theme_cover' : 'o_theme_logo')}" t-attf-style="background-image: url(#{image_url});"/>
|
||||
<div t-if="record.is_installed_on_current_website.raw_value" class="o_button_area">
|
||||
<button type="object" name="button_refresh_theme" class="btn btn-primary">Update theme</button>
|
||||
<button type="object" name="load_theme" class="btn btn-primary">Update theme</button>
|
||||
<hr />
|
||||
<button type="object" name="button_remove_theme" class="btn btn-secondary">Remove theme</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user