diff options
author | Alexandru DAMIAN <alexandru.damian@intel.com> | 2013-12-11 16:42:34 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-01-10 15:20:25 +0000 |
commit | 2251426ae420640c082ec0d0109b9be435075411 (patch) | |
tree | 0f58f48d18bbfd9054c928f3ef554365f74d6ed8 /bitbake/lib/toaster/toastergui/views.py | |
parent | c2fc6ca2fa68aca17235cac306b6df4b882fe9ff (diff) | |
download | poky-2251426ae420640c082ec0d0109b9be435075411.tar.gz |
bitbake: toaster: Create the base page navigation structure
Updating the general container pages to use the graphical
design and features from the design phase.
In the process of adapting the Simple UI to the designed
interface, we create all the pages and the navigation
structure for the Toaster GUI.
Views for each page have been added, and the url mapping
has been updated to reflect newly added pages.
The table page has been refactored to be component-oriented
instead of class-oriented in order to facilitate reusage.
Changes are made in different layers of the template
(base, basetable) in order to maximize code reuse among
different pages in the build.
(Bitbake rev: d31f039ae31b77023722c06e66542751536a1362)
Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster/toastergui/views.py')
-rw-r--r-- | bitbake/lib/toaster/toastergui/views.py | 167 |
1 files changed, 155 insertions, 12 deletions
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 7cb9b42379..663e03dfd2 100644 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
@@ -19,7 +19,7 @@ | |||
19 | import operator | 19 | import operator |
20 | 20 | ||
21 | from django.db.models import Q | 21 | from django.db.models import Q |
22 | from django.shortcuts import render | 22 | from django.shortcuts import render, redirect |
23 | from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable | 23 | from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe, LogMessage, Variable |
24 | from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency | 24 | from orm.models import Task_Dependency, Recipe_Dependency, Package, Package_File, Package_Dependency |
25 | from orm.models import Target_Installed_Package | 25 | from orm.models import Target_Installed_Package |
@@ -35,6 +35,7 @@ def _build_page_range(paginator, index = 1): | |||
35 | except EmptyPage: | 35 | except EmptyPage: |
36 | page = paginator.page(paginator.num_pages) | 36 | page = paginator.page(paginator.num_pages) |
37 | 37 | ||
38 | |||
38 | page.page_range = [page.number] | 39 | page.page_range = [page.number] |
39 | crt_range = 0 | 40 | crt_range = 0 |
40 | for i in range(1,5): | 41 | for i in range(1,5): |
@@ -48,22 +49,124 @@ def _build_page_range(paginator, index = 1): | |||
48 | break | 49 | break |
49 | return page | 50 | return page |
50 | 51 | ||
51 | @cache_control(no_store=True) | ||
52 | def build(request): | ||
53 | template = 'build.html' | ||
54 | logs = LogMessage.objects.all() | ||
55 | 52 | ||
56 | build_info = _build_page_range(Paginator(Build.objects.order_by("-id"), 10),request.GET.get('page', 1)) | 53 | def _verify_parameters(g, mandatory_parameters): |
54 | miss = [] | ||
55 | for mp in mandatory_parameters: | ||
56 | if not mp in g: | ||
57 | miss.append(mp) | ||
58 | if len(miss): | ||
59 | return miss | ||
60 | return None | ||
61 | |||
62 | def _redirect_parameters(view, g, mandatory_parameters): | ||
63 | import urllib | ||
64 | from django.core.urlresolvers import reverse | ||
65 | url = reverse(view) | ||
66 | params = {} | ||
67 | for i in g: | ||
68 | params[i] = g[i] | ||
69 | for i in mandatory_parameters: | ||
70 | if not i in params: | ||
71 | params[i] = mandatory_parameters[i] | ||
72 | |||
73 | return redirect(url + "?%s" % urllib.urlencode(params)) | ||
74 | |||
57 | 75 | ||
58 | context = {'objects': build_info, 'logs': logs , | 76 | # shows the "all builds" page |
59 | 'hideshowcols' : [ | 77 | def builds(request): |
60 | {'name': 'Output', 'order':10}, | 78 | template = 'build.html' |
61 | {'name': 'Log', 'order':11}, | 79 | # define here what parameters the view needs in the GET portion in order to |
80 | # be able to display something. 'count' and 'page' are mandatory for all views | ||
81 | # that use paginators. | ||
82 | mandatory_parameters = { 'count': 10, 'page' : 1}; | ||
83 | retval = _verify_parameters( request.GET, mandatory_parameters ) | ||
84 | if retval: | ||
85 | return _redirect_parameters( builds, request.GET, mandatory_parameters) | ||
86 | |||
87 | # retrieve the objects that will be displayed in the table | ||
88 | build_info = _build_page_range(Paginator(Build.objects.exclude(outcome = Build.IN_PROGRESS).order_by("-id"), request.GET.get('count', 10)),request.GET.get('page', 1)) | ||
89 | |||
90 | # build view-specific information; this is rendered specifically in the builds page | ||
91 | build_mru = Build.objects.order_by("-started_on")[:3] | ||
92 | for b in [ x for x in build_mru if x.outcome == Build.IN_PROGRESS ]: | ||
93 | tf = Task.objects.filter(build = b) | ||
94 | b.completeper = tf.exclude(order__isnull=True).count()*100/tf.count() | ||
95 | from django.utils import timezone | ||
96 | b.eta = timezone.now() + ((timezone.now() - b.started_on)*100/b.completeper) | ||
97 | |||
98 | # send the data to the template | ||
99 | context = { | ||
100 | # specific info for | ||
101 | 'mru' : build_mru, | ||
102 | # TODO: common objects for all table views, adapt as needed | ||
103 | 'objects' : build_info, | ||
104 | 'tablecols' : [ | ||
105 | {'name': 'Target ', 'clclass': 'target',}, | ||
106 | {'name': 'Machine ', 'clclass': 'machine'}, | ||
107 | {'name': 'Completed on ', 'clclass': 'completed_on'}, | ||
108 | {'name': 'Failed tasks ', 'clclass': 'failed_tasks'}, | ||
109 | {'name': 'Errors ', 'clclass': 'errors_no'}, | ||
110 | {'name': 'Warnings', 'clclass': 'warnings_no'}, | ||
111 | {'name': 'Output ', 'clclass': 'output'}, | ||
112 | {'name': 'Started on ', 'clclass': 'started_on', 'hidden' : 1}, | ||
113 | {'name': 'Time ', 'clclass': 'time', 'hidden' : 1}, | ||
114 | {'name': 'Output', 'clclass': 'output'}, | ||
115 | {'name': 'Log', 'clclass': 'log', 'hidden': 1}, | ||
62 | ]} | 116 | ]} |
63 | 117 | ||
64 | return render(request, template, context) | 118 | return render(request, template, context) |
65 | 119 | ||
66 | 120 | ||
121 | # build dashboard for a single build, coming in as argument | ||
122 | def builddashboard(request, build_id): | ||
123 | template = "builddashboard.html" | ||
124 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
125 | return redirect(builds) | ||
126 | context = { | ||
127 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
128 | } | ||
129 | return render(request, template, context) | ||
130 | |||
131 | def task(request, build_id, task_id): | ||
132 | template = "singletask.html" | ||
133 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
134 | return redirect(builds) | ||
135 | context = { | ||
136 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
137 | } | ||
138 | return render(request, template, context) | ||
139 | |||
140 | def recipe(request, build_id, recipe_id): | ||
141 | template = "recipe.html" | ||
142 | if Recipe.objects.filter(pk=recipe_id).count() == 0 : | ||
143 | return redirect(builds) | ||
144 | context = { | ||
145 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
146 | 'object' : Recipe.objects.filter(pk=recipe_id)[0], | ||
147 | } | ||
148 | return render(request, template, context) | ||
149 | |||
150 | def package(request, build_id, package_id): | ||
151 | template = "singlepackage.html" | ||
152 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
153 | return redirect(builds) | ||
154 | context = { | ||
155 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
156 | } | ||
157 | return render(request, template, context) | ||
158 | |||
159 | def target(request, build_id, target_id): | ||
160 | template = "target.html" | ||
161 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
162 | return redirect(builds) | ||
163 | context = { | ||
164 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
165 | } | ||
166 | return render(request, template, context) | ||
167 | |||
168 | |||
169 | |||
67 | def _find_task_revdep(task): | 170 | def _find_task_revdep(task): |
68 | tp = [] | 171 | tp = [] |
69 | for p in Task_Dependency.objects.filter(depends_on=task): | 172 | for p in Task_Dependency.objects.filter(depends_on=task): |
@@ -81,7 +184,7 @@ def _find_task_provider(task): | |||
81 | return trc | 184 | return trc |
82 | return None | 185 | return None |
83 | 186 | ||
84 | def task(request, build_id): | 187 | def tasks(request, build_id): |
85 | template = 'task.html' | 188 | template = 'task.html' |
86 | 189 | ||
87 | tasks = _build_page_range(Paginator(Task.objects.filter(build=build_id), 100),request.GET.get('page', 1)) | 190 | tasks = _build_page_range(Paginator(Task.objects.filter(build=build_id), 100),request.GET.get('page', 1)) |
@@ -94,12 +197,52 @@ def task(request, build_id): | |||
94 | 197 | ||
95 | return render(request, template, context) | 198 | return render(request, template, context) |
96 | 199 | ||
200 | def recipes(request, build_id): | ||
201 | template = 'recipe.html' | ||
202 | |||
203 | recipes = _build_page_range(Paginator(Recipe.objects.filter(build_recipe=build_id), 100),request.GET.get('page', 1)) | ||
204 | |||
205 | context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': recipes} | ||
206 | |||
207 | return render(request, template, context) | ||
208 | |||
209 | |||
97 | def configuration(request, build_id): | 210 | def configuration(request, build_id): |
98 | template = 'configuration.html' | 211 | template = 'configuration.html' |
99 | variables = _build_page_range(Paginator(Variable.objects.filter(build=build_id), 50), request.GET.get('page', 1)) | 212 | variables = _build_page_range(Paginator(Variable.objects.filter(build=build_id), 50), request.GET.get('page', 1)) |
100 | context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : variables} | 213 | context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : variables} |
101 | return render(request, template, context) | 214 | return render(request, template, context) |
102 | 215 | ||
216 | def buildtime(request, build_id): | ||
217 | template = "buildtime.html" | ||
218 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
219 | return redirect(builds) | ||
220 | context = { | ||
221 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
222 | } | ||
223 | return render(request, template, context) | ||
224 | |||
225 | def cpuusage(request, build_id): | ||
226 | template = "cpuusage.html" | ||
227 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
228 | return redirect(builds) | ||
229 | context = { | ||
230 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
231 | } | ||
232 | return render(request, template, context) | ||
233 | |||
234 | def diskio(request, build_id): | ||
235 | template = "diskio.html" | ||
236 | if Build.objects.filter(pk=build_id).count() == 0 : | ||
237 | return redirect(builds) | ||
238 | context = { | ||
239 | 'build' : Build.objects.filter(pk=build_id)[0], | ||
240 | } | ||
241 | return render(request, template, context) | ||
242 | |||
243 | |||
244 | |||
245 | |||
103 | def bpackage(request, build_id): | 246 | def bpackage(request, build_id): |
104 | template = 'bpackage.html' | 247 | template = 'bpackage.html' |
105 | packages = Package.objects.filter(build = build_id) | 248 | packages = Package.objects.filter(build = build_id) |
@@ -227,8 +370,8 @@ def model_explorer(request, model_name): | |||
227 | response_data['count'] = queryset.count() | 370 | response_data['count'] = queryset.count() |
228 | else: | 371 | else: |
229 | response_data['count'] = 0 | 372 | response_data['count'] = 0 |
230 | |||
231 | response_data['list'] = serializers.serialize('json', queryset) | 373 | response_data['list'] = serializers.serialize('json', queryset) |
374 | # response_data = serializers.serialize('json', queryset) | ||
232 | 375 | ||
233 | return HttpResponse(json.dumps(response_data), | 376 | return HttpResponse(json.dumps(response_data), |
234 | content_type='application/json') | 377 | content_type='application/json') |