diff --git a/odoo/addons/base/models/ir_asset.py b/odoo/addons/base/models/ir_asset.py index 157b1a28a8bbfb..ab85315bc938ea 100644 --- a/odoo/addons/base/models/ir_asset.py +++ b/odoo/addons/base/models/ir_asset.py @@ -202,7 +202,7 @@ def process_path(directive, target, path_def): # 2. Process all addons' manifests. for addon in self._topological_sort(tuple(addons)): - for command in odoo.modules.module._get_manifest_cached(addon)['assets'].get(bundle, ()): + for command in odoo.modules.module._get_manifest_cached(addon, None)['assets'].get(bundle, ()): directive, target, path_def = self._process_command(command) process_path(directive, target, path_def) @@ -257,7 +257,7 @@ def _topological_sort(self, addons_tuple): IrModule = self.env['ir.module.module'] def mapper(addon): - manif = odoo.modules.module._get_manifest_cached(addon) + manif = odoo.modules.module._get_manifest_cached(addon, None) from_terp = IrModule.get_values_from_terp(manif) from_terp['name'] = addon from_terp['depends'] = manif.get('depends', ['base']) @@ -302,7 +302,7 @@ def _get_paths(self, path_def, installed, extensions=None): path_url = fs2web(path_def) path_parts = [part for part in path_url.split('/') if part] addon = path_parts[0] - addon_manifest = odoo.modules.module._get_manifest_cached(addon) + addon_manifest = odoo.modules.module._get_manifest_cached(addon, None) safe_path = True if addon_manifest: diff --git a/odoo/http.py b/odoo/http.py index 79e6bd085f7b1d..ae6cba94dc3ad2 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -159,7 +159,7 @@ import odoo from .exceptions import UserError, AccessError, AccessDenied -from .modules.module import get_manifest +from .modules.module import get_manifest, get_module_path from .modules.registry import Registry from .service import security, model as service_model from .tools import (config, consteq, date_utils, file_path, parse_version, @@ -2117,6 +2117,41 @@ def _response(self, result=None, error=None): return self.request.make_json_response(response) +class ModuleStaticPathMap: + def __init__(self): + self._static_path_map = {} + + def get(self, module): + static_path = self._static_path_map.get(module) + if static_path: + return static_path + module_path = get_module_path(module) + if not module_path: + return None + # not passing module_path to get_manifest(), to take advantage of + # the cached values (in _get_manifest_cached()), as no code calls + # get_manifest() with a module_path. + manifest = get_manifest(module) + static_path = opj(module_path, "static") + if ( + manifest + and (manifest["installable"] or manifest["assets"]) + and os.path.isdir(static_path) + ): + self._static_path_map[module] = static_path + return static_path + return None + + def __getitem__(self, key): + static_path = self.get(key) + if static_path is not None: + return static_path + raise KeyError(key) + + def __contains__(self, value): + return self.get(value) is not None + + # ========================================================= # WSGI Entry Point # ========================================================= @@ -2131,16 +2166,7 @@ def statics(self): Map module names to their absolute ``static`` path on the file system. """ - mod2path = {} - for addons_path in odoo.addons.__path__: - for module in os.listdir(addons_path): - manifest = get_manifest(module) - static_path = opj(addons_path, module, 'static') - if (manifest - and (manifest['installable'] or manifest['assets']) - and os.path.isdir(static_path)): - mod2path[module] = static_path - return mod2path + return ModuleStaticPathMap() def get_static_file(self, url, host=''): """ diff --git a/odoo/modules/module.py b/odoo/modules/module.py index d1699178ab45c9..3017c3f4ee5150 100644 --- a/odoo/modules/module.py +++ b/odoo/modules/module.py @@ -446,7 +446,7 @@ def get_manifest(module, mod_path=None): return copy.deepcopy(_get_manifest_cached(module, mod_path)) @functools.lru_cache(maxsize=None) -def _get_manifest_cached(module, mod_path=None): +def _get_manifest_cached(module, mod_path): return load_manifest(module, mod_path) def load_information_from_description_file(module, mod_path=None):