@@ -23,6 +23,21 @@ class PipelineManifestStorage(PipelineMixin, ManifestFilesMixin, StaticFilesStor
2323    imports in comments. Ref: https://code.djangoproject.com/ticket/21080 
2424    """ 
2525
26+     # Skip map files 
27+     # https://code.djangoproject.com/ticket/33353#comment:13 
28+     patterns  =  (
29+         (
30+             "*.css" ,
31+             (
32+                 "(?P<matched>url\\ (['\" ]{0,1}\\ s*(?P<url>.*?)[\" ']{0,1}\\ ))" ,
33+                 (
34+                     "(?P<matched>@import\\ s*[\" ']\\ s*(?P<url>.*?)[\" '])" ,
35+                     '@import url("%(url)s")' ,
36+                 ),
37+             ),
38+         ),
39+     )
40+ 
2641    def  get_comment_blocks (self , content ):
2742        """ 
2843        Return a list of (start, end) tuples for each comment block. 
@@ -32,73 +47,85 @@ def get_comment_blocks(self, content):
3247            for  match  in  re .finditer (r'\/\*.*?\*\/' , content , flags = re .DOTALL )
3348        ]
3449
35-     def  url_converter (self , name , hashed_files , template = None , comment_blocks = None ):
50+ 
51+     def  is_in_comment (self , pos , comments ):
52+         for  start , end  in  comments :
53+             if  start  <  pos  and  pos  <  end :
54+                 return  True 
55+             if  pos  <  start :
56+                 return  False 
57+         return  False 
58+ 
59+ 
60+     def  url_converter (self , name , hashed_files , template = None , comment_blocks = []):
3661        """ 
3762        Return the custom URL converter for the given file name. 
3863        """ 
39-         if  comment_blocks  is  None :
40-             comment_blocks  =  []
41- 
4264        if  template  is  None :
4365            template  =  self .default_template 
4466
4567        def  converter (matchobj ):
4668            """ 
4769            Convert the matched URL to a normalized and hashed URL. 
70+ 
4871            This requires figuring out which files the matched URL resolves 
4972            to and calling the url() method of the storage. 
5073            """ 
51-             matched , url  =  matchobj .groups ()
74+             matches  =  matchobj .groupdict ()
75+             matched  =  matches ["matched" ]
76+             url  =  matches ["url" ]
5277
5378            # Ignore URLs in comments. 
5479            if  self .is_in_comment (matchobj .start (), comment_blocks ):
5580                return  matched 
5681
5782            # Ignore absolute/protocol-relative and data-uri URLs. 
58-             if  re .match (r' ^[a-z]+:'  , url ):
83+             if  re .match (r" ^[a-z]+:"  , url ):
5984                return  matched 
6085
6186            # Ignore absolute URLs that don't point to a static file (dynamic 
6287            # CSS / JS?). Note that STATIC_URL cannot be empty. 
63-             if  url .startswith ('/' ) and  not  url .startswith (settings .STATIC_URL ):
88+             if  url .startswith ("/" ) and  not  url .startswith (settings .STATIC_URL ):
6489                return  matched 
6590
6691            # Strip off the fragment so a path-like fragment won't interfere. 
6792            url_path , fragment  =  urldefrag (url )
6893
69-             if  url_path .startswith ('/' ):
94+             # Ignore URLs without a path 
95+             if  not  url_path :
96+                 return  matched 
97+ 
98+             if  url_path .startswith ("/" ):
7099                # Otherwise the condition above would have returned prematurely. 
71100                assert  url_path .startswith (settings .STATIC_URL )
72-                 target_name  =  url_path [len (settings .STATIC_URL ):]
101+                 target_name  =  url_path [len (settings .STATIC_URL )  :]
73102            else :
74103                # We're using the posixpath module to mix paths and URLs conveniently. 
75-                 source_name  =  name  if  os .sep  ==  '/'  else  name .replace (os .sep , '/' )
104+                 source_name  =  name  if  os .sep  ==  "/"  else  name .replace (os .sep , "/" )
76105                target_name  =  posixpath .join (posixpath .dirname (source_name ), url_path )
77106
78107            # Determine the hashed name of the target file with the storage backend. 
79108            hashed_url  =  self ._url (
80-                 self ._stored_name , unquote (target_name ),
81-                 force = True , hashed_files = hashed_files ,
109+                 self ._stored_name ,
110+                 unquote (target_name ),
111+                 force = True ,
112+                 hashed_files = hashed_files ,
82113            )
83114
84-             transformed_url  =  '/' .join (url_path .split ('/' )[:- 1 ] +  hashed_url .split ('/' )[- 1 :])
115+             transformed_url  =  "/" .join (
116+                 url_path .split ("/" )[:- 1 ] +  hashed_url .split ("/" )[- 1 :]
117+             )
85118
86119            # Restore the fragment that was stripped off earlier. 
87120            if  fragment :
88-                 transformed_url  +=  ('?#'  if  '?#'  in  url  else  '#' ) +  fragment 
121+                 transformed_url  +=  ("?#"  if  "?#"  in  url  else  "#" ) +  fragment 
89122
90123            # Return the hashed version to the file 
91-             return  template  %  unquote (transformed_url )
124+             matches ["url" ] =  unquote (transformed_url )
125+             return  template  %  matches 
92126
93127        return  converter 
94128
95-     def  is_in_comment (self , pos , comments ):
96-         for  start , end  in  comments :
97-             if  start  <  pos  and  pos  <  end :
98-                 return  True 
99-             if  pos  <  start :
100-                 return  False 
101-         return  False 
102129
103130    def  _post_process (self , paths , adjustable_paths , hashed_files ):
104131        # Sort the files by directory level 
@@ -122,7 +149,7 @@ def path_level(name):
122149                    hashed_name  =  hashed_files [hash_key ]
123150
124151                # then get the original's file content.. 
125-                 if  hasattr (original_file , ' seek' 
152+                 if  hasattr (original_file , " seek" 
126153                    original_file .seek (0 )
127154
128155                hashed_file_exists  =  self .exists (hashed_name )
@@ -131,12 +158,14 @@ def path_level(name):
131158                # ..to apply each replacement pattern to the content 
132159                if  name  in  adjustable_paths :
133160                    old_hashed_name  =  hashed_name 
134-                     content  =  original_file .read ().decode (settings . FILE_CHARSET )
161+                     content  =  original_file .read ().decode ("utf-8" )
135162                    for  extension , patterns  in  self ._patterns .items ():
136163                        if  matches_patterns (path , (extension ,)):
137164                            comment_blocks  =  self .get_comment_blocks (content )
138165                            for  pattern , template  in  patterns :
139-                                 converter  =  self .url_converter (name , hashed_files , template , comment_blocks )
166+                                 converter  =  self .url_converter (
167+                                     name , hashed_files , template , comment_blocks 
168+                                 )
140169                                try :
141170                                    content  =  pattern .sub (converter , content )
142171                                except  ValueError  as  exc :
@@ -145,8 +174,9 @@ def path_level(name):
145174                        self .delete (hashed_name )
146175                    # then save the processed result 
147176                    content_file  =  ContentFile (content .encode ())
148-                     # Save intermediate file for reference 
149-                     saved_name  =  self ._save (hashed_name , content_file )
177+                     if  self .keep_intermediate_files :
178+                         # Save intermediate file for reference 
179+                         self ._save (hashed_name , content_file )
150180                    hashed_name  =  self .hashed_name (name , content_file )
151181
152182                    if  self .exists (hashed_name ):
0 commit comments