OLD | NEW |
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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 | 336 |
337 def read_file(self, filename, binary=False): | 337 def read_file(self, filename, binary=False): |
338 for base in self._bases: | 338 for base in self._bases: |
339 if base.has_file(filename): | 339 if base.has_file(filename): |
340 return base.read_file(filename, binary) | 340 return base.read_file(filename, binary) |
341 raise KeyError('File not found {}'.format(filename)) | 341 raise KeyError('File not found {}'.format(filename)) |
342 | 342 |
343 def list_files(self, subdir): | 343 def list_files(self, subdir): |
344 return {f for base in self._bases for f in base.list_files(subdir)} | 344 return {f for base in self._bases for f in base.list_files(subdir)} |
345 | 345 |
| 346 def list_pages(self): |
| 347 # We can't let the base class implementation of `list_pages` handle |
| 348 # this on top of `list_files` because the same page can have multiple |
| 349 # possible source files. When those source files reside in different |
| 350 # base sources, only the first of them should be visible. Possible |
| 351 # source files of the page in later sources should be shadowed to avoid |
| 352 # unexpected conflicts. |
| 353 all_seen = set() |
| 354 for base in self._bases: |
| 355 base_seen = set() |
| 356 for page, ext in base.list_pages(): |
| 357 if page not in all_seen: |
| 358 yield page, ext |
| 359 base_seen.add(page) |
| 360 all_seen.update(base_seen) |
| 361 |
| 362 def has_page(self, page, format=None): |
| 363 # This function has to behave consistently with `list_pages` so we must |
| 364 # check if the page (in any format) exists in earlier bases before we |
| 365 # check later ones. |
| 366 for base in self._bases: |
| 367 if base.has_page(page): |
| 368 if format is None: |
| 369 return True |
| 370 # If a page exists in an earlier base in another format than |
| 371 # requested, it will shadow the same page in later bases. |
| 372 # Therefore, as as soon as we find a base that has the page in |
| 373 # any format, we can delegate to it completely. |
| 374 return base.has_page(page, format) |
| 375 else: |
| 376 return False |
| 377 |
346 | 378 |
347 def _memoize(func): | 379 def _memoize(func): |
348 """Cache results of functions calls.""" | 380 """Cache results of functions calls.""" |
349 memoized = {} | 381 memoized = {} |
350 | 382 |
351 def wrapper(*args): | 383 def wrapper(*args): |
352 try: | 384 try: |
353 return memoized[args] | 385 return memoized[args] |
354 except KeyError: | 386 except KeyError: |
355 return memoized.setdefault(args, func(*args)) | 387 return memoized.setdefault(args, func(*args)) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 'resolve_link', | 434 'resolve_link', |
403 'read_config', | 435 'read_config', |
404 'read_template', | 436 'read_template', |
405 'read_locale', | 437 'read_locale', |
406 'read_include', | 438 'read_include', |
407 'exec_file', | 439 'exec_file', |
408 ]: | 440 ]: |
409 setattr(source, fname, _memoize(getattr(source, fname))) | 441 setattr(source, fname, _memoize(getattr(source, fname))) |
410 | 442 |
411 return source | 443 return source |
OLD | NEW |