11# © 2024 initOS GmbH
22# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
33import logging
4+ import mimetypes
45import os
56import re
67
78from odoo import models
8- from odoo .http import ALLOWED_DEBUG_MODES
9+ from odoo .addons . web . models . ir_http import ALLOWED_DEBUG_MODES
910
1011_logger = logging .getLogger (__name__ )
1112
1213# Failsafe because it has the potential to lock everyone out of the UI
13- ALLOWED_DEBUG_MODES .append ("unfiltered" )
14+ if "unfiltered" not in ALLOWED_DEBUG_MODES :
15+ ALLOWED_DEBUG_MODES .append ("unfiltered" )
1416
1517
1618def filesize (filename ):
@@ -31,45 +33,74 @@ def filesize(filename):
3133class IrQweb (models .AbstractModel ):
3234 _inherit = "ir.qweb"
3335
34- def _generate_asset_nodes (
36+ def _get_asset_nodes (
3537 self ,
3638 bundle ,
3739 css = True ,
3840 js = True ,
3941 debug = False ,
40- async_load = False ,
4142 defer_load = False ,
4243 lazy_load = False ,
4344 media = None ,
4445 ):
46+ path = None
47+ assets = self .env ["web.assets" ].sudo ()
48+ try :
49+ from odoo .http import request
4550
46- if "|" in bundle :
47- bundle = bundle .rsplit ("|" , 1 )[0 ]
51+ path = request .httprequest .path
52+ except RuntimeError : # pylint: disable=except-pass
53+ pass
54+
55+ if path :
56+ domain = [
57+ ("bundle" , "=" , bundle ),
58+ ("active" , "=" , True ),
59+ ("path_regex" , "!=" , False ),
60+ ]
61+ for rec in assets .search (domain ):
62+ pattern = r"^" + rec .path_regex .strip (r"^" )
63+ if re .match (pattern , path ):
64+ assets = rec
65+ break
4866
49- return super ()._generate_asset_nodes (
67+ skip_filtering = bool (debug and "unfiltered" in debug )
68+ if assets and not skip_filtering :
69+ bundle += f"|{ assets .hashsum } "
70+
71+ return super (
72+ IrQweb ,
73+ self .with_context (
74+ bundle_skip_filtering = skip_filtering ,
75+ ),
76+ )._get_asset_nodes (
5077 bundle ,
5178 css = css ,
5279 js = js ,
5380 debug = debug ,
54- async_load = async_load ,
5581 defer_load = defer_load ,
5682 lazy_load = lazy_load ,
5783 media = media ,
5884 )
5985
60- def get_asset_bundle (self , bundle_name , files , env = None , css = True , js = True ):
61- if "|" in bundle_name :
62- bundle_name = bundle_name .rsplit ("|" , 1 )[0 ]
86+ def _get_asset_content (self , bundle , assets_params = None ):
87+ # Extract and strip the hashsum suffix appended by _get_asset_nodes
88+ hashsum = None
89+ if "|" in bundle :
90+ bundle , hashsum = bundle .rsplit ("|" , 1 )
91+
92+ files , external_assets = super ()._get_asset_content (
93+ bundle , assets_params = assets_params
94+ )
6395
64- hashsum = self .env .context .get ("bundle_hashsum" )
6596 skip = self .env .context .get ("bundle_skip_filtering" )
6697 if not hashsum or skip :
67- return super (). get_asset_bundle ( bundle_name , files , env = env , css = css , js = js )
98+ return files , external_assets
6899
69- urls = {a ["url" ]: a for a in files }
100+ urls = {f ["url" ]: f for f in files }
70101
71- # Synchronize assets files
72- assets = self .env ["web.assets" ].sudo ().search ([("bundle" , "=" , bundle_name )])
102+ # Synchronize web. assets.file records with the actual bundle file list
103+ assets = self .env ["web.assets" ].sudo ().search ([("bundle" , "=" , bundle )])
73104 assets .mapped ("file_ids" ).filtered_domain (
74105 [("name" , "not in" , list (urls ))]
75106 ).unlink ()
@@ -81,83 +112,25 @@ def get_asset_bundle(self, bundle_name, files, env=None, css=True, js=True):
81112 )
82113
83114 for asset in assets :
84- for file in set (urls ) - set (asset .mapped ("file_ids.name" )):
85- data = urls [file ]
86-
115+ for file_url in set (urls ) - set (asset .mapped ("file_ids.name" )):
116+ data = urls [file_url ]
117+ mimetype = mimetypes . guess_type ( file_url )[ 0 ] or ""
87118 asset .file_ids .create (
88119 {
89120 "asset_id" : asset .id ,
90- "name" : file ,
91- "mimetype" : data [ "atype" ] ,
121+ "name" : file_url ,
122+ "mimetype" : mimetype ,
92123 "include" : True ,
93124 "size" : filesize (data .get ("filename" , "" )),
94125 }
95126 )
96127
97- # Filter the assets files
128+ # Filter the file list to only the files enabled in the matching config
98129 domain = [
99- ("bundle" , "=" , bundle_name ),
130+ ("bundle" , "=" , bundle ),
100131 ("hashsum" , "=" , hashsum ),
101132 ("active" , "=" , True ),
102133 ]
103134 assets = assets .search (domain , limit = 1 )
104135 names = set (assets .mapped ("file_ids" ).filtered ("include" ).mapped ("name" ))
105- return super ().get_asset_bundle (
106- bundle_name ,
107- [file for file in files if file ["url" ] in names ],
108- env = env ,
109- css = css ,
110- js = js ,
111- )
112-
113- def _get_asset_nodes (
114- self ,
115- bundle ,
116- css = True ,
117- js = True ,
118- debug = False ,
119- async_load = False ,
120- defer_load = False ,
121- lazy_load = False ,
122- media = None ,
123- ):
124- path = None
125- assets = self .env ["web.assets" ].sudo ()
126- try :
127- from odoo .http import request
128-
129- path = request .httprequest .path
130- except RuntimeError : # pylint: disable=except-pass
131- pass
132-
133- if path :
134- domain = [
135- ("bundle" , "=" , bundle ),
136- ("active" , "=" , True ),
137- ("path_regex" , "!=" , False ),
138- ]
139- for rec in assets .search (domain ):
140- pattern = r"^" + rec .path_regex .strip (r"^" )
141- if re .match (pattern , path ):
142- assets = rec
143- break
144-
145- if assets :
146- bundle += f"|{ assets .hashsum } "
147-
148- return super (
149- IrQweb ,
150- self .with_context (
151- bundle_hashsum = assets .hashsum ,
152- bundle_skip_filtering = debug and "unfiltered" in debug ,
153- ),
154- )._get_asset_nodes (
155- bundle ,
156- css = css ,
157- js = js ,
158- debug = debug ,
159- async_load = async_load ,
160- defer_load = defer_load ,
161- lazy_load = lazy_load ,
162- media = media ,
163- )
136+ return [f for f in files if f ["url" ] in names ], external_assets
0 commit comments