summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/bldviewer/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster/bldviewer/views.py')
-rw-r--r--bitbake/lib/toaster/bldviewer/views.py287
1 files changed, 287 insertions, 0 deletions
diff --git a/bitbake/lib/toaster/bldviewer/views.py b/bitbake/lib/toaster/bldviewer/views.py
new file mode 100644
index 0000000000..c2e0c0c25d
--- /dev/null
+++ b/bitbake/lib/toaster/bldviewer/views.py
@@ -0,0 +1,287 @@
1#
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# BitBake Toaster Implementation
6#
7# Copyright (C) 2013 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
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.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22import operator
23
24from django.db.models import Q
25from django.shortcuts import render
26from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable, Target_Installed_Package
27from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency
28from orm.models import Target_Installed_Package, VariableHistory, Target_Image_File, Target_File
29from django.views.decorators.cache import cache_control
30from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
31
32
33def _build_page_range(paginator, index = 1):
34 try:
35 page = paginator.page(index)
36 except PageNotAnInteger:
37 page = paginator.page(1)
38 except EmptyPage:
39 page = paginator.page(paginator.num_pages)
40
41 page.page_range = [page.number]
42 crt_range = 0
43 for i in range(1,5):
44 if (page.number + i) <= paginator.num_pages:
45 page.page_range = page.page_range + [ page.number + i]
46 crt_range +=1
47 if (page.number - i) > 0:
48 page.page_range = [page.number -i] + page.page_range
49 crt_range +=1
50 if crt_range == 4:
51 break
52 return page
53
54@cache_control(no_store=True)
55def build(request):
56 template = 'simple_build.html'
57 logs = LogMessage.objects.all()
58
59 build_info = _build_page_range(Paginator(Build.objects.order_by("-id"), 10),request.GET.get('page', 1))
60
61 context = {'objects': build_info, 'logs': logs ,
62 'hideshowcols' : [
63 {'name': 'Output', 'order':10},
64 {'name': 'Log', 'order':11},
65 ]}
66
67 return render(request, template, context)
68
69
70def _find_task_revdep(task):
71 tp = []
72 for p in Task_Dependency.objects.filter(depends_on=task):
73 tp.append(p.task);
74 return tp
75
76def _find_task_provider(task):
77 task_revdeps = _find_task_revdep(task)
78 for tr in task_revdeps:
79 if tr.outcome != Task.OUTCOME_COVERED:
80 return tr
81 for tr in task_revdeps:
82 trc = _find_task_provider(tr)
83 if trc is not None:
84 return trc
85 return None
86
87def task(request, build_id):
88 template = 'simple_task.html'
89
90 tasks = _build_page_range(Paginator(Task.objects.filter(build=build_id, order__gt=0), 100),request.GET.get('page', 1))
91
92 for t in tasks:
93 if t.outcome == Task.OUTCOME_COVERED:
94 t.provider = _find_task_provider(t)
95
96 context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': tasks}
97
98 return render(request, template, context)
99
100def configuration(request, build_id):
101 template = 'simple_configuration.html'
102 variables = _build_page_range(Paginator(Variable.objects.filter(build=build_id), 50), request.GET.get('page', 1))
103 context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : variables}
104 return render(request, template, context)
105
106def bpackage(request, build_id):
107 template = 'simple_bpackage.html'
108 packages = Package.objects.filter(build = build_id)
109 context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : packages}
110 return render(request, template, context)
111
112def bfile(request, build_id, package_id):
113 template = 'simple_bfile.html'
114 files = Package_File.objects.filter(package = package_id)
115 context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : files}
116 return render(request, template, context)
117
118def tpackage(request, build_id, target_id):
119 template = 'simple_package.html'
120 packages = map(lambda x: x.package, list(Target_Installed_Package.objects.filter(target=target_id)))
121 context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : packages}
122 return render(request, template, context)
123
124def layer(request):
125 template = 'simple_layer.html'
126 layer_info = Layer.objects.all()
127
128 for li in layer_info:
129 li.versions = Layer_Version.objects.filter(layer = li)
130 for liv in li.versions:
131 liv.count = Recipe.objects.filter(layer_version__id = liv.id).count()
132
133 context = {'objects': layer_info}
134
135 return render(request, template, context)
136
137
138def layer_versions_recipes(request, layerversion_id):
139 template = 'simple_recipe.html'
140 recipes = Recipe.objects.filter(layer_version__id = layerversion_id)
141
142 context = {'objects': recipes,
143 'layer_version' : Layer_Version.objects.filter( id = layerversion_id )[0]
144 }
145
146 return render(request, template, context)
147
148#### API
149
150import json
151from django.core import serializers
152from django.http import HttpResponse, HttpResponseBadRequest
153
154
155def model_explorer(request, model_name):
156
157 DESCENDING = 'desc'
158 response_data = {}
159 model_mapping = {
160 'build': Build,
161 'target': Target,
162 'target_file': Target_File,
163 'target_image_file': Target_Image_File,
164 'task': Task,
165 'task_dependency': Task_Dependency,
166 'package': Package,
167 'layer': Layer,
168 'layerversion': Layer_Version,
169 'recipe': Recipe,
170 'recipe_dependency': Recipe_Dependency,
171 'package': Package,
172 'package_dependency': Package_Dependency,
173 'target_installed_package': Target_Installed_Package,
174 'build_file': Package_File,
175 'variable': Variable,
176 'variablehistory': VariableHistory,
177 'logmessage': LogMessage,
178 }
179
180 if model_name not in model_mapping.keys():
181 return HttpResponseBadRequest()
182
183 model = model_mapping[model_name]
184
185 try:
186 limit = int(request.GET.get('limit', 0))
187 except ValueError:
188 limit = 0
189
190 try:
191 offset = int(request.GET.get('offset', 0))
192 except ValueError:
193 offset = 0
194
195 ordering_string, invalid = _validate_input(request.GET.get('orderby', ''),
196 model)
197 if invalid:
198 return HttpResponseBadRequest()
199
200 filter_string, invalid = _validate_input(request.GET.get('filter', ''),
201 model)
202 if invalid:
203 return HttpResponseBadRequest()
204
205 search_term = request.GET.get('search', '')
206
207 if filter_string:
208 filter_terms = _get_filtering_terms(filter_string)
209 try:
210 queryset = model.objects.filter(**filter_terms)
211 except ValueError:
212 queryset = []
213 else:
214 queryset = model.objects.all()
215
216 if search_term:
217 queryset = _get_search_results(search_term, queryset, model)
218
219 if ordering_string and queryset:
220 column, order = ordering_string.split(':')
221 if order.lower() == DESCENDING:
222 queryset = queryset.order_by('-' + column)
223 else:
224 queryset = queryset.order_by(column)
225
226 if offset and limit:
227 queryset = queryset[offset:(offset+limit)]
228 elif offset:
229 queryset = queryset[offset:]
230 elif limit:
231 queryset = queryset[:limit]
232
233 if queryset:
234 response_data['count'] = queryset.count()
235 else:
236 response_data['count'] = 0
237
238 response_data['list'] = serializers.serialize('json', queryset)
239
240 return HttpResponse(json.dumps(response_data),
241 content_type='application/json')
242
243def _get_filtering_terms(filter_string):
244
245 search_terms = filter_string.split(":")
246 keys = search_terms[0].split(',')
247 values = search_terms[1].split(',')
248
249 return dict(zip(keys, values))
250
251def _validate_input(input, model):
252
253 invalid = 0
254
255 if input:
256 input_list = input.split(":")
257
258 # Check we have only one colon
259 if len(input_list) != 2:
260 invalid = 1
261 return None, invalid
262
263 # Check we have an equal number of terms both sides of the colon
264 if len(input_list[0].split(',')) != len(input_list[1].split(',')):
265 invalid = 1
266 return None, invalid
267
268 # Check we are looking for a valid field
269 valid_fields = model._meta.get_all_field_names()
270 for field in input_list[0].split(','):
271 if field not in valid_fields:
272 invalid = 1
273 return None, invalid
274
275 return input, invalid
276
277def _get_search_results(search_term, queryset, model):
278 search_objects = []
279 for st in search_term.split(" "):
280 q_map = map(lambda x: Q(**{x+'__icontains': st}),
281 model.search_allowed_fields)
282
283 search_objects.append(reduce(operator.or_, q_map))
284 search_object = reduce(operator.and_, search_objects)
285 queryset = queryset.filter(search_object)
286
287 return queryset