diff --git a/addons/web_editor/controllers/main.py b/addons/web_editor/controllers/main.py index 622a0b751c4..adad212bd87 100644 --- a/addons/web_editor/controllers/main.py +++ b/addons/web_editor/controllers/main.py @@ -407,7 +407,7 @@ class Web_Editor(http.Controller): continue # Check if the file is customized and get bundle/path info - file_data = AssetsUtils.get_asset_info(url) + file_data = AssetsUtils._get_data_from_url(url) if not file_data: continue @@ -454,14 +454,14 @@ class Web_Editor(http.Controller): urls = [] for bundle_data in files_data_by_bundle: urls += bundle_data[1] - custom_attachments = AssetsUtils.get_all_custom_attachments(urls) + custom_attachments = AssetsUtils._get_custom_attachment(urls, op='in') for bundle_data in files_data_by_bundle: for i in range(0, len(bundle_data[1])): url = bundle_data[1][i] url_info = url_infos[url] - content = AssetsUtils.get_asset_content(url, url_info, custom_attachments) + content = AssetsUtils._get_content_from_url(url, url_info, custom_attachments) bundle_data[1][i] = { 'url': "/%s/%s" % (url_info["module"], url_info["resource_path"]), @@ -471,41 +471,6 @@ class Web_Editor(http.Controller): return files_data_by_bundle - @http.route("/web_editor/save_asset", type="json", auth="user", website=True) - def save_asset(self, url, bundle, content, file_type): - """ - Save a given modification of a scss/js file. - - Params: - url (str): - the original url of the scss/js file which has to be modified - - bundle (str): - the name of the bundle in which the scss/js file addition can - be found - - content (str): the new content of the scss/js file - - file_type (str): 'scss' or 'js' - """ - request.env['web_editor.assets'].save_asset(url, bundle, content, file_type) - - @http.route("/web_editor/reset_asset", type="json", auth="user", website=True) - def reset_asset(self, url, bundle): - """ - The reset_asset route is in charge of reverting all the changes that - were done to a scss/js file. - - Params: - url (str): - the original URL of the scss/js file to reset - - bundle (str): - the name of the bundle in which the scss/js file addition can - be found - """ - request.env['web_editor.assets'].reset_asset(url, bundle) - @http.route("/web_editor/public_render_template", type="json", auth="public", website=True) def public_render_template(self, args, kwargs): # pylint: disable=unused-argument # args[0]: xml id of the template to render diff --git a/addons/web_editor/models/assets.py b/addons/web_editor/models/assets.py index 6e0ce892416..4c304416dd8 100644 --- a/addons/web_editor/models/assets.py +++ b/addons/web_editor/models/assets.py @@ -2,23 +2,20 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. import base64 -import os import re -import uuid -from lxml import etree - -from odoo import models +from odoo import api, models from odoo.tools import misc from odoo.addons.base.models.assetsbundle import EXTENSIONS -_match_asset_file_url_regex = re.compile("^/(\w+)/(.+?)(\.custom\.(.+))?\.(\w+)$") +_match_asset_file_url_regex = re.compile(r"^/(\w+)/(.+?)(\.custom\.(.+))?\.(\w+)$") class Assets(models.AbstractModel): _name = 'web_editor.assets' _description = 'Assets Utils' + @api.model def reset_asset(self, url, bundle): """ Delete the potential customizations made to a given (original) asset. @@ -30,13 +27,14 @@ class Assets(models.AbstractModel): the name of the bundle in which the customizations to delete were made """ - custom_url = self.make_custom_asset_file_url(url, bundle) + custom_url = self._make_custom_asset_url(url, bundle) # Simply delete the attachement which contains the modified scss/js file # and the xpath view which links it self._get_custom_attachment(custom_url).unlink() self._get_custom_asset(custom_url).unlink() + @api.model def save_asset(self, url, bundle, content, file_type): """ Customize the content of a given asset (scss / js). @@ -55,7 +53,7 @@ class Assets(models.AbstractModel): file_type (src): either 'scss' or 'js' according to the file being customized """ - custom_url = self.make_custom_asset_file_url(url, bundle) + custom_url = self._make_custom_asset_url(url, bundle) datas = base64.b64encode((content or "\n").encode("utf-8")) # Check if the file to save had already been modified @@ -91,26 +89,14 @@ class Assets(models.AbstractModel): new_asset['bundle'] = target_asset.bundle new_asset['sequence'] = target_asset.sequence else: - path_parts = '/'.join(os.path.split(custom_url)).split('/') - new_asset['name'] = '%s: replace %s' % (bundle, path_parts[-1]) + new_asset['name'] = '%s: replace %s' % (bundle, custom_url.split('/')[-1]) new_asset['bundle'] = IrAsset._get_related_bundle(url, bundle) IrAsset.create(new_asset) self.env["ir.qweb"].clear_caches() - def get_all_custom_attachments(self, urls): - """ - Fetch all the ir.attachment records related to given URLs. - - Params: - urls (str[]): list of urls - - Returns: - ir.attachment(): attachment records related to the given URLs. - """ - return self._get_custom_attachment(urls, op='in') - - def get_asset_content(self, url, url_info=None, custom_attachments=None): + @api.model + def _get_content_from_url(self, url, url_info=None, custom_attachments=None): """ Fetch the content of an asset (scss / js) file. That content is either the one of the related file on the disk or the one of the corresponding @@ -120,7 +106,7 @@ class Assets(models.AbstractModel): url (str): the URL of the asset (scss / js) file/ir.attachment url_info (dict, optional): - the related url info (see get_asset_info) (allows to optimize + the related url info (see _get_data_from_url) (allows to optimize some code which already have the info and do not want this function to re-get it) @@ -133,7 +119,7 @@ class Assets(models.AbstractModel): utf-8 encoded content of the asset (scss / js) """ if url_info is None: - url_info = self.get_asset_info(url) + url_info = self._get_data_from_url(url) if url_info["customized"]: # If the file is already customized, the content is found in the @@ -150,7 +136,8 @@ class Assets(models.AbstractModel): with misc.file_open(url.strip('/'), 'rb', filter_ext=EXTENSIONS) as f: return f.read() - def get_asset_info(self, url): + @api.model + def _get_data_from_url(self, url): """ Return information about an asset (scss / js) file/ir.attachment just by looking at its URL. @@ -181,7 +168,8 @@ class Assets(models.AbstractModel): 'bundle': m.group(4) or False } - def make_custom_asset_file_url(self, url, bundle_xmlid): + @api.model + def _make_custom_asset_url(self, url, bundle_xmlid): """ Return the customized version of an asset URL, that is the URL the asset would have if it was customized. @@ -197,6 +185,7 @@ class Assets(models.AbstractModel): parts = url.rsplit(".", 1) return "%s.custom.%s.%s" % (parts[0], bundle_xmlid, parts[1]) + @api.model def _get_custom_attachment(self, custom_url, op='='): """ Fetch the ir.attachment record related to the given customized asset. @@ -211,6 +200,7 @@ class Assets(models.AbstractModel): assert op in ('in', '='), 'Invalid operator' return self.env["ir.attachment"].search([("url", op, custom_url)]) + @api.model def _get_custom_asset(self, custom_url): """ Fetch the ir.asset record related to the given customized asset (the @@ -225,6 +215,7 @@ class Assets(models.AbstractModel): url = custom_url[1:] if custom_url.startswith(('/', '\\')) else custom_url return self.env['ir.asset'].search([('path', 'like', url)]) + @api.model def _save_asset_hook(self): """ Returns the additional values to use to write the DB on customized diff --git a/addons/web_editor/static/src/js/common/ace.js b/addons/web_editor/static/src/js/common/ace.js index 61089330a76..460254a5a17 100644 --- a/addons/web_editor/static/src/js/common/ace.js +++ b/addons/web_editor/static/src/js/common/ace.js @@ -593,11 +593,9 @@ var ViewEditor = Widget.extend({ } else { var resource = type === 'scss' ? this.scss[resID] : this.js[resID]; return this._rpc({ - route: '/web_editor/reset_asset', - params: { - url: resID, - bundle: resource.bundle, - }, + model: 'web_editor.assets', + method: 'reset_asset', + args: [resID, resource.bundle], }); } }, @@ -616,13 +614,9 @@ var ViewEditor = Widget.extend({ var bundle = sessionIdEndsWithJS ? this.js[session.id].bundle : this.scss[session.id].bundle; var fileType = sessionIdEndsWithJS ? 'js' : 'scss'; return self._rpc({ - route: '/web_editor/save_asset', - params: { - url: session.id, - bundle, - content: session.text, - file_type: fileType, - }, + model: 'web_editor.assets', + method: 'save_asset', + args: [session.id, bundle, session.text, fileType], }).then(function () { self._toggleDirtyInfo(session.id, fileType, false); }); diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 1677fd67594..961b1b58c3e 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -733,25 +733,6 @@ class Website(Home): 'website.assets_editor': request.env['ir.qweb']._get_asset_link_urls('website.assets_editor'), } - @http.route(['/website/make_scss_custo'], type='json', auth='user', website=True) - def make_scss_custo(self, url, values): - """ - Params: - url (str): - the URL of the scss file to customize (supposed to be a variable - file which will appear in the assets_common bundle) - - values (dict): - key,value mapping to integrate in the file's map (containing the - word hook). If a key is already in the file's map, its value is - overridden. - - Returns: - boolean - """ - request.env['web_editor.assets'].make_scss_customization(url, values) - return True - # ------------------------------------------------------ # Server actions # ------------------------------------------------------ diff --git a/addons/website/models/assets.py b/addons/website/models/assets.py index 219a119024c..1b82ff56254 100644 --- a/addons/website/models/assets.py +++ b/addons/website/models/assets.py @@ -3,12 +3,13 @@ import re -from odoo import models +from odoo import api, models class Assets(models.AbstractModel): _inherit = 'web_editor.assets' + @api.model def make_scss_customization(self, url, values): """ Makes a scss customization of the given file. That file must @@ -43,8 +44,8 @@ class Assets(models.AbstractModel): 'copyright-gradient': 'null', }) - custom_url = self.make_custom_asset_file_url(url, 'web.assets_common') - updatedFileContent = self.get_asset_content(custom_url) or self.get_asset_content(url) + custom_url = self._make_custom_asset_url(url, 'web.assets_common') + updatedFileContent = self._get_content_from_url(custom_url) or self._get_content_from_url(url) updatedFileContent = updatedFileContent.decode('utf-8') for name, value in values.items(): pattern = "'%s': %%s,\n" % name @@ -59,30 +60,33 @@ class Assets(models.AbstractModel): # variables scss files self.save_asset(url, 'web.assets_common', updatedFileContent, 'scss') + @api.model def _get_custom_attachment(self, custom_url, op='='): """ See web_editor.Assets._get_custom_attachment Extend to only return the attachments related to the current website. """ website = self.env['website'].get_current_website() - res = super(Assets, self)._get_custom_attachment(custom_url, op=op) + res = super()._get_custom_attachment(custom_url, op=op) return res.with_context(website_id=website.id).filtered(lambda x: not x.website_id or x.website_id == website) + @api.model def _get_custom_asset(self, custom_url): """ See web_editor.Assets._get_custom_asset Extend to only return the views related to the current website. """ website = self.env['website'].get_current_website() - res = super(Assets, self)._get_custom_asset(custom_url) + res = super()._get_custom_asset(custom_url) return res.with_context(website_id=website.id).filter_duplicate() + @api.model def _save_asset_hook(self): """ See web_editor.Assets._save_asset_hook Extend to add website ID at attachment creation. """ - res = super(Assets, self)._save_asset_hook() + res = super()._save_asset_hook() website = self.env['website'].get_current_website() if website: diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 35b114f4e4c..12fe10b2859 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -638,11 +638,9 @@ options.Class.include({ */ _makeSCSSCusto: async function (url, values, defaultValue = 'null') { return this._rpc({ - route: '/website/make_scss_custo', - params: { - 'url': url, - 'values': _.mapObject(values, v => v || defaultValue), - }, + model: 'web_editor.assets', + method: 'make_scss_customization', + args: [url, _.mapObject(values, v => v || defaultValue)], }); }, /**