diff options
author | Elliot Smith <elliot.smith@intel.com> | 2016-01-15 13:00:53 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-01-15 16:30:00 +0000 |
commit | f8d383d87f0b9d4a4c9ae7b1a6c8ceebf90ef9b0 (patch) | |
tree | cda7dc3eb23a5b6a97241c965bbd9b0dcddc02eb /bitbake/lib/toaster/toastergui/tablefilter.py | |
parent | b929889cdd4a36846f9569d89fabd9987e94b39e (diff) | |
download | poky-f8d383d87f0b9d4a4c9ae7b1a6c8ceebf90ef9b0.tar.gz |
bitbake: toastergui: implement date range filters for builds
Implement the completed_on and started_on filtering for
builds.
Also separate the name of a filter ("filter" in the querystring)
from its value ("filter_value" in the querystring). This enables
filtering to be defined in the querystring more intuitively,
and also makes it easier to add other types of filter (e.g.
by day).
[YOCTO #8738]
(Bitbake rev: d47c32e88c2d4a423f4d94d49759e557f425a539)
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/tablefilter.py')
-rw-r--r-- | bitbake/lib/toaster/toastergui/tablefilter.py | 113 |
1 files changed, 101 insertions, 12 deletions
diff --git a/bitbake/lib/toaster/toastergui/tablefilter.py b/bitbake/lib/toaster/toastergui/tablefilter.py index b42fd52865..1ea30da304 100644 --- a/bitbake/lib/toaster/toastergui/tablefilter.py +++ b/bitbake/lib/toaster/toastergui/tablefilter.py | |||
@@ -18,12 +18,15 @@ | |||
18 | # You should have received a copy of the GNU General Public License along | 18 | # You should have received a copy of the GNU General Public License along |
19 | # with this program; if not, write to the Free Software Foundation, Inc., | 19 | # with this program; if not, write to the Free Software Foundation, Inc., |
20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
21 | from django.db.models import Q, Max, Min | ||
22 | from django.utils import dateparse, timezone | ||
21 | 23 | ||
22 | class TableFilter(object): | 24 | class TableFilter(object): |
23 | """ | 25 | """ |
24 | Stores a filter for a named field, and can retrieve the action | 26 | Stores a filter for a named field, and can retrieve the action |
25 | requested for that filter | 27 | requested from the set of actions for that filter |
26 | """ | 28 | """ |
29 | |||
27 | def __init__(self, name, title): | 30 | def __init__(self, name, title): |
28 | self.name = name | 31 | self.name = name |
29 | self.title = title | 32 | self.title = title |
@@ -64,42 +67,128 @@ class TableFilter(object): | |||
64 | 'filter_actions': filter_actions | 67 | 'filter_actions': filter_actions |
65 | } | 68 | } |
66 | 69 | ||
67 | class TableFilterActionToggle(object): | 70 | class TableFilterAction(object): |
68 | """ | 71 | """ |
69 | Stores a single filter action which will populate one radio button of | 72 | A filter action which displays in the filter popup for a ToasterTable |
70 | a ToasterTable filter popup; this filter can either be on or off and | 73 | and uses an associated QuerysetFilter to filter the queryset for that |
71 | has no other parameters | 74 | ToasterTable |
72 | """ | 75 | """ |
73 | 76 | ||
74 | def __init__(self, name, title, queryset_filter): | 77 | def __init__(self, name, title, queryset_filter): |
75 | self.name = name | 78 | self.name = name |
76 | self.title = title | 79 | self.title = title |
77 | self.__queryset_filter = queryset_filter | 80 | self.queryset_filter = queryset_filter |
78 | self.type = 'toggle' | 81 | |
82 | # set in subclasses | ||
83 | self.type = None | ||
79 | 84 | ||
80 | def set_params(self, params): | 85 | def set_filter_params(self, params): |
81 | """ | 86 | """ |
82 | params: (str) a string of extra parameters for the action; | 87 | params: (str) a string of extra parameters for the action; |
83 | the structure of this string depends on the type of action; | 88 | the structure of this string depends on the type of action; |
84 | it's ignored for a toggle filter action, which is just on or off | 89 | it's ignored for a toggle filter action, which is just on or off |
85 | """ | 90 | """ |
86 | pass | 91 | if not params: |
92 | return | ||
87 | 93 | ||
88 | def filter(self, queryset): | 94 | def filter(self, queryset): |
89 | return self.__queryset_filter.filter(queryset) | 95 | return self.queryset_filter.filter(queryset) |
90 | 96 | ||
91 | def to_json(self, queryset): | 97 | def to_json(self, queryset): |
92 | """ Dump as a JSON object """ | 98 | """ Dump as a JSON object """ |
93 | return { | 99 | return { |
94 | 'title': self.title, | 100 | 'title': self.title, |
95 | 'type': self.type, | 101 | 'type': self.type, |
96 | 'count': self.__queryset_filter.count(queryset) | 102 | 'count': self.queryset_filter.count(queryset) |
97 | } | 103 | } |
98 | 104 | ||
105 | class TableFilterActionToggle(TableFilterAction): | ||
106 | """ | ||
107 | A single filter action which will populate one radio button of | ||
108 | a ToasterTable filter popup; this filter can either be on or off and | ||
109 | has no other parameters | ||
110 | """ | ||
111 | |||
112 | def __init__(self, *args): | ||
113 | super(TableFilterActionToggle, self).__init__(*args) | ||
114 | self.type = 'toggle' | ||
115 | |||
116 | class TableFilterActionDateRange(TableFilterAction): | ||
117 | """ | ||
118 | A filter action which will filter the queryset by a date range. | ||
119 | The date range can be set via set_params() | ||
120 | """ | ||
121 | |||
122 | def __init__(self, name, title, field, queryset_filter): | ||
123 | """ | ||
124 | field: the field to find the max/min range from in the queryset | ||
125 | """ | ||
126 | super(TableFilterActionDateRange, self).__init__( | ||
127 | name, | ||
128 | title, | ||
129 | queryset_filter | ||
130 | ) | ||
131 | |||
132 | self.type = 'daterange' | ||
133 | self.field = field | ||
134 | |||
135 | def set_filter_params(self, params): | ||
136 | """ | ||
137 | params: (str) a string of extra parameters for the filtering | ||
138 | in the format "2015-12-09,2015-12-11" (from,to); this is passed in the | ||
139 | querystring and used to set the criteria on the QuerysetFilter | ||
140 | associated with this action | ||
141 | """ | ||
142 | |||
143 | # if params are invalid, return immediately, resetting criteria | ||
144 | # on the QuerysetFilter | ||
145 | try: | ||
146 | from_date_str, to_date_str = params.split(',') | ||
147 | except ValueError: | ||
148 | self.queryset_filter.set_criteria(None) | ||
149 | return | ||
150 | |||
151 | # one of the values required for the filter is missing, so set | ||
152 | # it to the one which was supplied | ||
153 | if from_date_str == '': | ||
154 | from_date_str = to_date_str | ||
155 | elif to_date_str == '': | ||
156 | to_date_str = from_date_str | ||
157 | |||
158 | date_from_naive = dateparse.parse_datetime(from_date_str + ' 00:00:00') | ||
159 | date_to_naive = dateparse.parse_datetime(to_date_str + ' 23:59:59') | ||
160 | |||
161 | tz = timezone.get_default_timezone() | ||
162 | date_from = timezone.make_aware(date_from_naive, tz) | ||
163 | date_to = timezone.make_aware(date_to_naive, tz) | ||
164 | |||
165 | args = {} | ||
166 | args[self.field + '__gte'] = date_from | ||
167 | args[self.field + '__lte'] = date_to | ||
168 | |||
169 | criteria = Q(**args) | ||
170 | self.queryset_filter.set_criteria(criteria) | ||
171 | |||
172 | def to_json(self, queryset): | ||
173 | """ Dump as a JSON object """ | ||
174 | data = super(TableFilterActionDateRange, self).to_json(queryset) | ||
175 | |||
176 | # additional data about the date range covered by the queryset's | ||
177 | # records, retrieved from its <field> column | ||
178 | data['min'] = queryset.aggregate(Min(self.field))[self.field + '__min'] | ||
179 | data['max'] = queryset.aggregate(Max(self.field))[self.field + '__max'] | ||
180 | |||
181 | # a range filter has a count of None, as the number of records it | ||
182 | # will select depends on the date range entered | ||
183 | data['count'] = None | ||
184 | |||
185 | return data | ||
186 | |||
99 | class TableFilterMap(object): | 187 | class TableFilterMap(object): |
100 | """ | 188 | """ |
101 | Map from field names to Filter objects for those fields | 189 | Map from field names to TableFilter objects for those fields |
102 | """ | 190 | """ |
191 | |||
103 | def __init__(self): | 192 | def __init__(self): |
104 | self.__filters = {} | 193 | self.__filters = {} |
105 | 194 | ||