comparison piecrust/data/iterators.py @ 226:e9dc18a275ff

data: Add ability for `IPaginationSource`s to specify how to get settings. The `IPaginationSource` has a new `getSettingAccessor` method that returns how to access settings values on items in the pagination source. A default accessor is also available, which uses standard attribute lookup. Also clean some stuff in `LazyPageConfigData`.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 04 Feb 2015 23:49:52 -0800
parents 53b9df2263dc
children 8015fb40c28b
comparison
equal deleted inserted replaced
225:a75d024ee839 226:e9dc18a275ff
78 class SettingSortIterator(object): 78 class SettingSortIterator(object):
79 def __init__(self, it, name, reverse=False, value_accessor=None): 79 def __init__(self, it, name, reverse=False, value_accessor=None):
80 self.it = it 80 self.it = it
81 self.name = name 81 self.name = name
82 self.reverse = reverse 82 self.reverse = reverse
83 self.value_accessor = value_accessor 83 self.value_accessor = value_accessor or self._default_value_accessor
84 84
85 def __iter__(self): 85 def __iter__(self):
86 return iter(sorted(self.it, key=self._key_getter, 86 return iter(sorted(self.it, key=self._key_getter,
87 reverse=self.reverse)) 87 reverse=self.reverse))
88 88
89 def _key_getter(self, item): 89 def _key_getter(self, item):
90 if self.value_accessor: 90 key = self.value_accessor(item, self.name)
91 return self.value_accessor(item, self.name) 91 if key is None:
92 return item.config.get(self.name) 92 return 0
93 return key
94
95 @staticmethod
96 def _default_value_accessor(item, name):
97 try:
98 return getattr(item, name)
99 except AttributeError:
100 return None
93 101
94 102
95 class PaginationFilterIterator(object): 103 class PaginationFilterIterator(object):
96 def __init__(self, it, fil): 104 def __init__(self, it, fil):
97 self.it = it 105 self.it = it
123 self._pages = src_it 131 self._pages = src_it
124 132
125 # Apply any filter first, before we start sorting or slicing. 133 # Apply any filter first, before we start sorting or slicing.
126 if pagination_filter is not None: 134 if pagination_filter is not None:
127 self._simpleNonSortedWrap(PaginationFilterIterator, 135 self._simpleNonSortedWrap(PaginationFilterIterator,
128 pagination_filter) 136 pagination_filter)
129 137
130 if offset > 0 or limit > 0: 138 if offset > 0 or limit > 0:
131 self.slice(offset, limit) 139 self.slice(offset, limit)
132 140
133 self._locked = locked 141 self._locked = locked
205 213
206 def sort(self, setting_name=None, reverse=False): 214 def sort(self, setting_name=None, reverse=False):
207 self._ensureUnlocked() 215 self._ensureUnlocked()
208 self._unload() 216 self._unload()
209 if setting_name is not None: 217 if setting_name is not None:
218 accessor = None
219 if not isinstance(self._source, IPaginationSource):
220 accessor = self._source.getSettingAccessor()
210 self._pages = SettingSortIterator(self._pages, setting_name, 221 self._pages = SettingSortIterator(self._pages, setting_name,
211 reverse) 222 reverse, accessor)
212 else: 223 else:
213 self._pages = NaturalSortIterator(self._pages, reverse) 224 self._pages = NaturalSortIterator(self._pages, reverse)
214 self._has_sorter = True 225 self._has_sorter = True
215 return self 226 return self
216 227