diff options
Diffstat (limited to 'bitbake/lib/toaster/toastergui/widgets.py')
-rw-r--r-- | bitbake/lib/toaster/toastergui/widgets.py | 90 |
1 files changed, 40 insertions, 50 deletions
diff --git a/bitbake/lib/toaster/toastergui/widgets.py b/bitbake/lib/toaster/toastergui/widgets.py index 71b29eaa1e..8790340db9 100644 --- a/bitbake/lib/toaster/toastergui/widgets.py +++ b/bitbake/lib/toaster/toastergui/widgets.py | |||
@@ -39,11 +39,13 @@ import json | |||
39 | import collections | 39 | import collections |
40 | import operator | 40 | import operator |
41 | import re | 41 | import re |
42 | import urllib | ||
42 | 43 | ||
43 | import logging | 44 | import logging |
44 | logger = logging.getLogger("toaster") | 45 | logger = logging.getLogger("toaster") |
45 | 46 | ||
46 | from toastergui.views import objtojson | 47 | from toastergui.views import objtojson |
48 | from toastergui.tablefilter import TableFilterMap | ||
47 | 49 | ||
48 | class ToasterTable(TemplateView): | 50 | class ToasterTable(TemplateView): |
49 | def __init__(self, *args, **kwargs): | 51 | def __init__(self, *args, **kwargs): |
@@ -53,7 +55,10 @@ class ToasterTable(TemplateView): | |||
53 | self.title = "Table" | 55 | self.title = "Table" |
54 | self.queryset = None | 56 | self.queryset = None |
55 | self.columns = [] | 57 | self.columns = [] |
56 | self.filters = {} | 58 | |
59 | # map from field names to Filter instances | ||
60 | self.filter_map = TableFilterMap() | ||
61 | |||
57 | self.total_count = 0 | 62 | self.total_count = 0 |
58 | self.static_context_extra = {} | 63 | self.static_context_extra = {} |
59 | self.filter_actions = {} | 64 | self.filter_actions = {} |
@@ -66,7 +71,7 @@ class ToasterTable(TemplateView): | |||
66 | orderable=True, | 71 | orderable=True, |
67 | field_name="id") | 72 | field_name="id") |
68 | 73 | ||
69 | # prevent HTTP caching of table data | 74 | # prevent HTTP caching of table data |
70 | @cache_control(must_revalidate=True, max_age=0, no_store=True, no_cache=True) | 75 | @cache_control(must_revalidate=True, max_age=0, no_store=True, no_cache=True) |
71 | def dispatch(self, *args, **kwargs): | 76 | def dispatch(self, *args, **kwargs): |
72 | return super(ToasterTable, self).dispatch(*args, **kwargs) | 77 | return super(ToasterTable, self).dispatch(*args, **kwargs) |
@@ -108,27 +113,10 @@ class ToasterTable(TemplateView): | |||
108 | self.apply_search(search) | 113 | self.apply_search(search) |
109 | 114 | ||
110 | name = request.GET.get("name", None) | 115 | name = request.GET.get("name", None) |
111 | if name is None: | 116 | table_filter = self.filter_map.get_filter(name) |
112 | data = json.dumps(self.filters, | 117 | return json.dumps(table_filter.to_json(self.queryset), |
113 | indent=2, | 118 | indent=2, |
114 | cls=DjangoJSONEncoder) | 119 | cls=DjangoJSONEncoder) |
115 | else: | ||
116 | for actions in self.filters[name]['filter_actions']: | ||
117 | queryset_filter = self.filter_actions[actions['name']] | ||
118 | actions['count'] = queryset_filter.count(self.queryset) | ||
119 | |||
120 | # Add the "All" items filter action | ||
121 | self.filters[name]['filter_actions'].insert(0, { | ||
122 | 'name' : 'all', | ||
123 | 'title' : 'All', | ||
124 | 'count' : self.queryset.count(), | ||
125 | }) | ||
126 | |||
127 | data = json.dumps(self.filters[name], | ||
128 | indent=2, | ||
129 | cls=DjangoJSONEncoder) | ||
130 | |||
131 | return data | ||
132 | 120 | ||
133 | def setup_columns(self, *args, **kwargs): | 121 | def setup_columns(self, *args, **kwargs): |
134 | """ function to implement in the subclass which sets up the columns """ | 122 | """ function to implement in the subclass which sets up the columns """ |
@@ -140,33 +128,13 @@ class ToasterTable(TemplateView): | |||
140 | """ function to implement in the subclass which sets up the queryset""" | 128 | """ function to implement in the subclass which sets up the queryset""" |
141 | pass | 129 | pass |
142 | 130 | ||
143 | def add_filter(self, name, title, filter_actions): | 131 | def add_filter(self, table_filter): |
144 | """Add a filter to the table. | 132 | """Add a filter to the table. |
145 | 133 | ||
146 | Args: | 134 | Args: |
147 | name (str): Unique identifier of the filter. | 135 | table_filter: Filter instance |
148 | title (str): Title of the filter. | ||
149 | filter_actions: Actions for all the filters. | ||
150 | """ | 136 | """ |
151 | self.filters[name] = { | 137 | self.filter_map.add_filter(table_filter.name, table_filter) |
152 | 'title' : title, | ||
153 | 'filter_actions' : filter_actions, | ||
154 | } | ||
155 | |||
156 | def make_filter_action(self, name, title, queryset_filter): | ||
157 | """ | ||
158 | Utility to make a filter_action; queryset_filter is an instance | ||
159 | of QuerysetFilter or a function | ||
160 | """ | ||
161 | |||
162 | action = { | ||
163 | 'title' : title, | ||
164 | 'name' : name, | ||
165 | } | ||
166 | |||
167 | self.filter_actions[name] = queryset_filter | ||
168 | |||
169 | return action | ||
170 | 138 | ||
171 | def add_column(self, title="", help_text="", | 139 | def add_column(self, title="", help_text="", |
172 | orderable=False, hideable=True, hidden=False, | 140 | orderable=False, hideable=True, hidden=False, |
@@ -216,19 +184,41 @@ class ToasterTable(TemplateView): | |||
216 | return template.render(context) | 184 | return template.render(context) |
217 | 185 | ||
218 | def apply_filter(self, filters, **kwargs): | 186 | def apply_filter(self, filters, **kwargs): |
187 | """ | ||
188 | Apply a filter submitted in the querystring to the ToasterTable | ||
189 | |||
190 | filters: (str) in the format: | ||
191 | '<filter name>:<action name>!<action params>' | ||
192 | where <action params> is optional | ||
193 | |||
194 | <filter name> and <action name> are used to look up the correct filter | ||
195 | in the ToasterTable's filter map; the <action params> are set on | ||
196 | TableFilterAction* before its filter is applied and may modify the | ||
197 | queryset returned by the filter | ||
198 | """ | ||
219 | self.setup_filters(**kwargs) | 199 | self.setup_filters(**kwargs) |
220 | 200 | ||
221 | try: | 201 | try: |
222 | filter_name, filter_action = filters.split(':') | 202 | filter_name, action_name_and_params = filters.split(':') |
203 | |||
204 | action_name = None | ||
205 | action_params = None | ||
206 | if re.search('!', action_name_and_params): | ||
207 | action_name, action_params = action_name_and_params.split('!') | ||
208 | action_params = urllib.unquote_plus(action_params) | ||
209 | else: | ||
210 | action_name = action_name_and_params | ||
223 | except ValueError: | 211 | except ValueError: |
224 | return | 212 | return |
225 | 213 | ||
226 | if "all" in filter_action: | 214 | if "all" in action_name: |
227 | return | 215 | return |
228 | 216 | ||
229 | try: | 217 | try: |
230 | queryset_filter = self.filter_actions[filter_action] | 218 | table_filter = self.filter_map.get_filter(filter_name) |
231 | self.queryset = queryset_filter.filter(self.queryset) | 219 | action = table_filter.get_action(action_name) |
220 | action.set_params(action_params) | ||
221 | self.queryset = action.filter(self.queryset) | ||
232 | except KeyError: | 222 | except KeyError: |
233 | # pass it to the user - programming error here | 223 | # pass it to the user - programming error here |
234 | raise | 224 | raise |