171 |
171 |
172 |
172 |
173 class ConcatFiles(LongTimeExpiringFile): |
173 class ConcatFiles(LongTimeExpiringFile): |
174 def __init__(self, config, paths): |
174 def __init__(self, config, paths): |
175 _, ext = osp.splitext(paths[0]) |
175 _, ext = osp.splitext(paths[0]) |
|
176 self._resources = {} |
176 # create a unique / predictable filename |
177 # create a unique / predictable filename |
177 fname = 'cache_concat_' + hashlib.md5(';'.join(paths)).hexdigest() + ext |
178 fname = 'cache_concat_' + hashlib.md5(';'.join(paths)).hexdigest() + ext |
178 filepath = osp.join(config.appdatahome, 'uicache', fname) |
179 filepath = osp.join(config.appdatahome, 'uicache', fname) |
179 LongTimeExpiringFile.__init__(self, config, filepath) |
180 LongTimeExpiringFile.__init__(self, config, filepath) |
180 self._concat_cached_filepath(filepath, paths) |
181 self._concat_cached_filepath(filepath, paths) |
181 |
182 |
|
183 def _resource(self, path): |
|
184 try: |
|
185 return self._resources[path] |
|
186 except KeyError: |
|
187 self._resources[path] = self.config.locate_resource(path) |
|
188 return self._resources[path] |
|
189 |
182 def _concat_cached_filepath(self, filepath, paths): |
190 def _concat_cached_filepath(self, filepath, paths): |
183 if not self._up_to_date(filepath, paths): |
191 if not self._up_to_date(filepath, paths): |
184 concat_data = [] |
192 concat_data = [] |
185 for path in paths: |
193 for path in paths: |
186 # FIXME locate_resource is called twice() in debug-mode, but |
194 dirpath, rid = self._resource(path) |
187 # it's a @cached method |
|
188 dirpath, rid = self.config.locate_resource(path) |
|
189 if rid is None: |
195 if rid is None: |
190 raise ConcatFileNotFoundError(path) |
196 if self.config.debugmode: |
191 concat_data.append(open(osp.join(dirpath, rid)).read()) |
197 raise ConcatFileNotFoundError(path) |
|
198 else: |
|
199 # In production mode log an error, do not return a 404 |
|
200 # XXX the erroneous content is cached anyway |
|
201 LOGGER.error('concatenated data url error: %r file ' |
|
202 'does not exist', path) |
|
203 else: |
|
204 concat_data.append(open(osp.join(dirpath, rid)).read()) |
192 with open(filepath, 'wb') as f: |
205 with open(filepath, 'wb') as f: |
193 f.write('\n'.join(concat_data)) |
206 f.write('\n'.join(concat_data)) |
194 |
207 |
195 def _up_to_date(self, filepath, paths): |
208 def _up_to_date(self, filepath, paths): |
196 """ |
209 """ |
201 if not osp.isfile(filepath): |
214 if not osp.isfile(filepath): |
202 return False |
215 return False |
203 if self.config.debugmode: |
216 if self.config.debugmode: |
204 concat_lastmod = os.stat(filepath).st_mtime |
217 concat_lastmod = os.stat(filepath).st_mtime |
205 for path in paths: |
218 for path in paths: |
206 dirpath, rid = self.config.locate_resource(path) |
219 dirpath, rid = self._resource(path) |
207 if rid is None: |
220 if rid is None: |
208 raise ConcatFileNotFoundError(path) |
221 raise ConcatFileNotFoundError(path) |
209 path = osp.join(dirpath, rid) |
222 path = osp.join(dirpath, rid) |
210 if os.stat(path).st_mtime > concat_lastmod: |
223 if os.stat(path).st_mtime > concat_lastmod: |
211 return False |
224 return False |