summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/widgets.py
diff options
context:
space:
mode:
authorElliot Smith <elliot.smith@intel.com>2016-01-15 13:00:50 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-01-15 16:29:59 +0000
commit809046c6fbd544907b5d5f3bb554b71724c74661 (patch)
tree9a20e81100395ba67934f3e865c6e9356f4e0232 /bitbake/lib/toaster/toastergui/widgets.py
parent294579b531d5a96a17aa863554e71f4680d35812 (diff)
downloadpoky-809046c6fbd544907b5d5f3bb554b71724c74661.tar.gz
bitbake: toastergui: refactor ToasterTable filtering
The filter code for ToasterTable was difficult to follow and inflexible (not allowing different types of filter, for example). Refactor to a set of filter classes to make the structure cleaner and provide the flexibility needed for other filter types (e.g. date range filter). [YOCTO #8738] (Bitbake rev: 94031bb30bdaf665d0c8c68b591fcb7a17b6674d) Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster/toastergui/widgets.py')
-rw-r--r--bitbake/lib/toaster/toastergui/widgets.py90
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
39import collections 39import collections
40import operator 40import operator
41import re 41import re
42import urllib
42 43
43import logging 44import logging
44logger = logging.getLogger("toaster") 45logger = logging.getLogger("toaster")
45 46
46from toastergui.views import objtojson 47from toastergui.views import objtojson
48from toastergui.tablefilter import TableFilterMap
47 49
48class ToasterTable(TemplateView): 50class 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