comparison piecrust/data/filters.py @ 233:4379d8f8f831

internal: Removing some dependency of filters and iterators on pages.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 11 Feb 2015 20:36:18 -0800
parents 474c9882decf
children 8c0c53a315ae
comparison
equal deleted inserted replaced
232:e534d2bc657c 233:4379d8f8f831
3 3
4 logger = logging.getLogger(__name__) 4 logger = logging.getLogger(__name__)
5 5
6 6
7 class PaginationFilter(object): 7 class PaginationFilter(object):
8 def __init__(self): 8 def __init__(self, value_accessor=None):
9 self.root_clause = None 9 self.root_clause = None
10 self.value_accessor = value_accessor or self._default_value_accessor
10 11
11 @property 12 @property
12 def is_empty(self): 13 def is_empty(self):
13 return self.root_clause is None 14 return self.root_clause is None
14 15
21 self._addClausesFromConfigRecursive(config, self.root_clause) 22 self._addClausesFromConfigRecursive(config, self.root_clause)
22 23
23 def pageMatches(self, page): 24 def pageMatches(self, page):
24 if self.root_clause is None: 25 if self.root_clause is None:
25 return True 26 return True
26 return self.root_clause.pageMatches(page) 27 return self.root_clause.pageMatches(self, page)
27 28
28 def _ensureRootClause(self): 29 def _ensureRootClause(self):
29 if self.root_clause is None: 30 if self.root_clause is None:
30 self.root_clause = AndBooleanClause() 31 self.root_clause = AndBooleanClause()
31 32
74 parent_clause.addClause(IsFilterClause(setting_name, val)) 75 parent_clause.addClause(IsFilterClause(setting_name, val))
75 76
76 else: 77 else:
77 raise Exception("Unknown filter clause: %s" % key) 78 raise Exception("Unknown filter clause: %s" % key)
78 79
80 @staticmethod
81 def _default_value_accessor(item, name):
82 try:
83 return getattr(item, name)
84 except AttributeError:
85 return None
79 86
80 87
81 class IFilterClause(object): 88 class IFilterClause(object):
82 def addClause(self, clause): 89 def addClause(self, clause):
83 raise NotImplementedError() 90 raise NotImplementedError()
84 91
85 def pageMatches(self, page): 92 def pageMatches(self, fil, page):
86 raise NotImplementedError() 93 raise NotImplementedError()
87 94
88 95
89 class NotClause(IFilterClause): 96 class NotClause(IFilterClause):
90 def __init__(self): 97 def __init__(self):
94 if self.child is not None: 101 if self.child is not None:
95 raise Exception("'NOT' filtering clauses can only have one " 102 raise Exception("'NOT' filtering clauses can only have one "
96 "child clause.") 103 "child clause.")
97 self.child = clause 104 self.child = clause
98 105
99 def pageMatches(self, page): 106 def pageMatches(self, fil, page):
100 if self.child is None: 107 if self.child is None:
101 raise Exception("'NOT' filtering clauses must have one child " 108 raise Exception("'NOT' filtering clauses must have one child "
102 "clause.") 109 "clause.")
103 return not self.child.pageMatches(page) 110 return not self.child.pageMatches(fil, page)
104 111
105 112
106 class BooleanClause(IFilterClause): 113 class BooleanClause(IFilterClause):
107 def __init__(self): 114 def __init__(self):
108 self.clauses = [] 115 self.clauses = []
110 def addClause(self, clause): 117 def addClause(self, clause):
111 self.clauses.append(clause) 118 self.clauses.append(clause)
112 119
113 120
114 class AndBooleanClause(BooleanClause): 121 class AndBooleanClause(BooleanClause):
115 def pageMatches(self, page): 122 def pageMatches(self, fil, page):
116 for c in self.clauses: 123 for c in self.clauses:
117 if not c.pageMatches(page): 124 if not c.pageMatches(fil, page):
118 return False 125 return False
119 return True 126 return True
120 127
121 128
122 class OrBooleanClause(BooleanClause): 129 class OrBooleanClause(BooleanClause):
123 def pageMatches(self, page): 130 def pageMatches(self, fil, page):
124 for c in self.clauses: 131 for c in self.clauses:
125 if c.pageMatches(page): 132 if c.pageMatches(fil, page):
126 return True 133 return True
127 return False 134 return False
128 135
129 136
130 class SettingFilterClause(IFilterClause): 137 class SettingFilterClause(IFilterClause):
137 raise Exception("Setting filter clauses can't have child clauses. " 144 raise Exception("Setting filter clauses can't have child clauses. "
138 "Use a boolean filter clause instead.") 145 "Use a boolean filter clause instead.")
139 146
140 147
141 class HasFilterClause(SettingFilterClause): 148 class HasFilterClause(SettingFilterClause):
142 def pageMatches(self, page): 149 def pageMatches(self, fil, page):
143 actual_value = page.config.get(self.name) 150 actual_value = fil.value_accessor(page, self.name)
144 if actual_value is None or not isinstance(actual_value, list): 151 if actual_value is None or not isinstance(actual_value, list):
145 return False 152 return False
146 153
147 if self.coercer: 154 if self.coercer:
148 actual_value = list(map(self.coercer, actual_value)) 155 actual_value = list(map(self.coercer, actual_value))
149 156
150 return self.value in actual_value 157 return self.value in actual_value
151 158
152 159
153 class IsFilterClause(SettingFilterClause): 160 class IsFilterClause(SettingFilterClause):
154 def pageMatches(self, page): 161 def pageMatches(self, fil, page):
155 actual_value = page.config.get(self.name) 162 actual_value = fil.value_accessor(page, self.name)
156 if self.coercer: 163 if self.coercer:
157 actual_value = self.coercer(actual_value) 164 actual_value = self.coercer(actual_value)
158 return actual_value == self.value 165 return actual_value == self.value
159 166