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