Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: cms/sources.py

Issue 29555839: Issue 5336 - Allow additional include, page, and template paths using CMS (Closed)
Patch Set: Address comments on PS1 Created Sept. 27, 2017, 11:33 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cms/bin/test_server.py ('k') | tests/__init__.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # This file is part of the Adblock Plus web scripts, 1 # This file is part of the Adblock Plus web scripts,
2 # Copyright (C) 2006-present eyeo GmbH 2 # Copyright (C) 2006-present eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 4 # Adblock Plus is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 3 as 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 path = os.path.join(dir, filename) 296 path = os.path.join(dir, filename)
297 if os.path.isfile(path): 297 if os.path.isfile(path):
298 result.append(relpath + filename) 298 result.append(relpath + filename)
299 elif os.path.isdir(path): 299 elif os.path.isdir(path):
300 do_list(path, relpath + filename + '/') 300 do_list(path, relpath + filename + '/')
301 do_list(self.get_path(subdir), '') 301 do_list(self.get_path(subdir), '')
302 return result 302 return result
303 303
304 def get_cache_dir(self): 304 def get_cache_dir(self):
305 return os.path.join(self._dir, 'cache') 305 return os.path.join(self._dir, 'cache')
306
307
308 class MultiSource(Source):
309 """A source that combines the contents of multiple other sources."""
310
311 def __init__(self, base_sources):
312 self._bases = base_sources
313
314 @property
315 def version(self):
316 return self._bases[0].version
317
318 def get_cache_dir(self):
319 return self._bases[0].get_cache_dir()
320
321 def __enter__(self):
322 for base in self._bases:
323 base.__enter__()
324 return self
325
326 def __exit__(self, exc_type, exc_value, tb):
327 return any(base.__exit__(exc_type, exc_value, tb)
328 for base in self._bases)
329
330 def close(self):
331 for base in self._bases:
332 base.close()
333
334 def has_file(self, filename):
335 return any(base.has_file(filename) for base in self._bases)
336
337 def read_file(self, filename, binary=False):
338 for base in self._bases:
339 if base.has_file(filename):
340 return base.read_file(filename, binary)
341 raise KeyError('File not found {}'.format(filename))
342
343 def list_files(self, subdir):
344 return list({f for base in self._bases
345 for f in base.list_files(subdir)})
346
347
348 def _memoize(func):
349 """Cache results of functions calls."""
350 memoized = {}
351
352 def wrapper(*args):
353 try:
354 return memoized[args]
355 except KeyError:
356 return memoized.setdefault(args, func(*args))
357 wrapper.cache_clear = memoized.clear
358 return wrapper
359
360
361 def create_source(path, static=False, revision='default'):
362 """Create a source from path and optional revision.
363
364 `static` flag determines the type of the source that will be created and
365 its caching behavior:
366 - If `static` is `True`, we use version-control-aware `MercurialSource`,
367 pass the revision and cache the results of most used functions.
368 - If `static` is `False` (as is the case with the preview server), we use
369 simpler `FileSource` and don't cache anything to be able to respond to
370 changes on the filesystem.
371
372 If `settings.ini` in the source contains `[paths]` section with an
373 `additional-paths` key that contains the list of additional root folders,
374 `MultiSource` will be instantiated and its bases will be the original
375 source plus an additional source for each additional root folder.
376 `MultiSource` looks up files in its base sources in the order they are
377 provided, so the files in the additional folders will only be used if the
378 original source doesn't contain that file.
379 """
380 if static:
381 source = MercurialSource(path, revision)
382 else:
383 source = FileSource(path)
384
385 config = source.read_config()
386 try:
387 ap = config.get('paths', 'additional-paths').strip()
388 additional_paths = filter(None, ap.split())
389 except ConfigParser.NoSectionError:
390 additional_paths = []
391
392 if additional_paths:
393 additional_sources = [
394 create_source(os.path.join(path, p))
395 for p in additional_paths
396 ]
397 source = MultiSource([source] + additional_sources)
398
399 if static:
400 for fname in [
401 'resolve_link',
402 'read_config',
403 'read_template',
404 'read_locale',
405 'read_include',
406 'exec_file',
407 ]:
408 setattr(source, fname, _memoize(getattr(source, fname)))
409
410 return source
OLDNEW
« no previous file with comments | « cms/bin/test_server.py ('k') | tests/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld