Mercurial > piecrust2
comparison piecrust/data/linker.py @ 212:701591ebfcba
data: Improve the Linker and RecursiveLinker features. Add tests.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sat, 31 Jan 2015 11:50:50 -0800 |
parents | 4fc1d306046b |
children | d6d0e4976beb |
comparison
equal
deleted
inserted
replaced
211:0b2d8f6df4ce | 212:701591ebfcba |
---|---|
1 import logging | 1 import logging |
2 import collections | 2 import collections |
3 from piecrust.data.base import PaginationData | 3 from piecrust.data.base import PaginationData, IPaginationSource |
4 from piecrust.data.iterators import PageIterator | |
4 from piecrust.sources.base import IListableSource, build_pages | 5 from piecrust.sources.base import IListableSource, build_pages |
5 | 6 |
6 | 7 |
7 logger = logging.getLogger(__name__) | 8 logger = logging.getLogger(__name__) |
8 | 9 |
18 @property | 19 @property |
19 def is_dir(self): | 20 def is_dir(self): |
20 return False | 21 return False |
21 | 22 |
22 | 23 |
24 class LinkedPageDataIterator(object): | |
25 def __init__(self, items): | |
26 self._items = list(items) | |
27 self._index = -1 | |
28 | |
29 def __iter__(self): | |
30 return self | |
31 | |
32 def __next__(self): | |
33 self._index += 1 | |
34 if self._index >= len(self._items): | |
35 raise StopIteration() | |
36 return self._items[self._index] | |
37 | |
38 def sort(self, name): | |
39 def key_getter(item): | |
40 return item[name] | |
41 self._items = sorted(self._item, key=key_getter) | |
42 return self | |
43 | |
44 | |
23 class Linker(object): | 45 class Linker(object): |
24 debug_render_doc = """Provides access to sibling and children pages.""" | 46 debug_render_doc = """Provides access to sibling and children pages.""" |
25 | 47 |
26 def __init__(self, source, *, name=None, dir_path=None, page_path=None): | 48 def __init__(self, source, *, name=None, dir_path=None, page_path=None): |
27 self.source = source | 49 self.source = source |
31 self._cache = None | 53 self._cache = None |
32 self._is_listable = None | 54 self._is_listable = None |
33 | 55 |
34 def __iter__(self): | 56 def __iter__(self): |
35 self._load() | 57 self._load() |
36 return iter(self._cache.values()) | 58 return LinkedPageDataIterator(self._cache.values()) |
37 | 59 |
38 def __getattr__(self, name): | 60 def __getattr__(self, name): |
39 self._load() | 61 self._load() |
40 try: | 62 try: |
41 return self._cache[name] | 63 return self._cache[name] |
83 self._cache[name] = LinkedPageData(name, page, | 105 self._cache[name] = LinkedPageData(name, page, |
84 is_root_page) | 106 is_root_page) |
85 | 107 |
86 | 108 |
87 class RecursiveLinker(Linker): | 109 class RecursiveLinker(Linker): |
88 def __init__(self, source, page_path): | 110 def __init__(self, source, *args, **kwargs): |
89 super(RecursiveLinker, self).__init__(source, page_path=page_path) | 111 super(RecursiveLinker, self).__init__(source, *args, **kwargs) |
90 | 112 |
91 def __iter__(self): | 113 def __iter__(self): |
114 return iter(PageIterator(self._iterateLinkers())) | |
115 | |
116 def siblings(self): | |
117 return PageIterator(self._iterateLinkers(0)) | |
118 | |
119 def frompath(self, rel_path): | |
120 return RecursiveLinker(self.source, name='.', dir_path=rel_path) | |
121 | |
122 def _iterateLinkers(self, max_depth=-1): | |
92 self._load() | 123 self._load() |
93 if not self._is_listable: | 124 if not self._is_listable: |
94 return | 125 return |
95 yield from walk_linkers(self) | 126 yield from walk_linkers(self, 0, max_depth) |
96 | 127 |
97 | 128 |
98 def walk_linkers(linker): | 129 def walk_linkers(linker, depth=0, max_depth=-1): |
99 linker._load() | 130 linker._load() |
100 for item in linker._cache.values(): | 131 for item in linker._cache.values(): |
101 if item.is_dir: | 132 if item.is_dir: |
102 yield from walk_linkers(item) | 133 if max_depth < 0 or depth + 1 <= max_depth: |
134 yield from walk_linkers(item, depth + 1, max_depth) | |
103 else: | 135 else: |
104 yield item | 136 yield item |
105 | 137 |