comparison piecrust/data/iterators.py @ 10:cd35d356ccce

Fix some bugs with iterators, add some unit tests.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 17 Aug 2014 21:18:48 -0700
parents f5ca5c5bed85
children 3a13b43e77c1
comparison
equal deleted inserted replaced
9:8f7ba2c95025 10:cd35d356ccce
21 21
22 def __iter__(self): 22 def __iter__(self):
23 if self._cache is None: 23 if self._cache is None:
24 inner_list = list(self.it) 24 inner_list = list(self.it)
25 self.inner_count = len(inner_list) 25 self.inner_count = len(inner_list)
26 self.has_more = self.inner_count > (self.offset + self.limit) 26
27 self._cache = inner_list[self.offset:self.offset + self.limit] 27 if self.limit > 0:
28 self.has_more = self.inner_count > (self.offset + self.limit)
29 self._cache = inner_list[self.offset:self.offset + self.limit]
30 else:
31 self.has_more = False
32 self._cache = inner_list[self.offset:]
33
28 if self.current_page: 34 if self.current_page:
29 idx = inner_list.index(self.current_page) 35 idx = inner_list.index(self.current_page)
30 if idx >= 0: 36 if idx >= 0:
31 if idx < self.inner_count - 1: 37 if idx < self.inner_count - 1:
32 self.next_page = inner_list[idx + 1] 38 self.next_page = inner_list[idx + 1]
33 if idx > 0: 39 if idx > 0:
34 self.prev_page = inner_list[idx - 1] 40 self.prev_page = inner_list[idx - 1]
41
35 return iter(self._cache) 42 return iter(self._cache)
36 43
37 44
38 class SettingFilterIterator(object): 45 class SettingFilterIterator(object):
39 def __init__(self, it, fil_conf, page_accessor=None): 46 def __init__(self, it, fil_conf, page_accessor=None):
54 page = i 61 page = i
55 if self._fil.pageMatches(page): 62 if self._fil.pageMatches(page):
56 yield i 63 yield i
57 64
58 65
66 class NaturalSortIterator(object):
67 def __init__(self, it, reverse=False):
68 self.it = it
69 self.reverse = reverse
70
71 def __iter__(self):
72 return iter(sorted(self.it, reverse=self.reverse))
73
74
59 class SettingSortIterator(object): 75 class SettingSortIterator(object):
60 def __init__(self, it, name, reverse=False, value_accessor=None): 76 def __init__(self, it, name, reverse=False, value_accessor=None):
61 self.it = it 77 self.it = it
62 self.name = name 78 self.name = name
63 self.reverse = reverse 79 self.reverse = reverse
64 self.value_accessor = value_accessor 80 self.value_accessor = value_accessor
65 81
66 def __iter__(self): 82 def __iter__(self):
67 def comparer(x, y): 83 return iter(sorted(self.it, key=self._key_getter,
68 if self.value_accessor: 84 reverse=self.reverse))
69 v1 = self.value_accessor(x, self.name) 85
70 v2 = self.value_accessor(y, self.name) 86 def _key_getter(self, item):
71 else: 87 if self.value_accessor:
72 v1 = x.config.get(self.name) 88 return self.value_accessor(item, self.name)
73 v2 = y.config.get(self.name) 89 return item.config.get(self.name)
74
75 if v1 is None and v2 is None:
76 return 0
77 if v1 is None and v2 is not None:
78 return 1 if self.reverse else -1
79 if v1 is not None and v2 is None:
80 return -1 if self.reverse else 1
81
82 if v1 == v2:
83 return 0
84 if self.reverse:
85 return 1 if v1 < v2 else -1
86 else:
87 return -1 if v1 < v2 else 1
88
89 return sorted(self.it, cmp=self._comparer, reverse=self.reverse)
90 90
91 91
92 class PaginationFilterIterator(object): 92 class PaginationFilterIterator(object):
93 def __init__(self, it, fil): 93 def __init__(self, it, fil):
94 self.it = it 94 self.it = it
198 raise Exception("Couldn't find filter '%s' in the configuration " 198 raise Exception("Couldn't find filter '%s' in the configuration "
199 "header for page: %s" % 199 "header for page: %s" %
200 (filter_name, self._current_page.path)) 200 (filter_name, self._current_page.path))
201 return self._simpleNonSortedWrap(SettingFilterIterator, filter_conf) 201 return self._simpleNonSortedWrap(SettingFilterIterator, filter_conf)
202 202
203 def sort(self, setting_name, reverse=False): 203 def sort(self, setting_name=None, reverse=False):
204 self._ensureUnlocked() 204 self._ensureUnlocked()
205 self._unload() 205 self._unload()
206 self._pages = SettingSortIterator(self._pages, setting_name, reverse) 206 if setting_name is not None:
207 self._pages = SettingSortIterator(self._pages, setting_name,
208 reverse)
209 else:
210 self._pages = NaturalSortIterator(self._pages, reverse)
207 self._has_sorter = True 211 self._has_sorter = True
208 return self 212 return self
209 213
210 def reset(self): 214 def reset(self):
211 self._ensureUnlocked() 215 self._ensureUnlocked()