[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:
Jeremy Kersten
2018-09-21 18:20:00 +02:00
parent 39d1d3013f
commit 663da0684a
2 changed files with 159 additions and 94 deletions
@@ -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):
+1 -1
View File
@@ -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>