@@ -74,17 +73,17 @@
{% for build in objects %}
- | {%if build.outcome == build.SUCCEEDED%}{%elif build.outcome == build.FAILED%}{%else%}{%endif%} |
+ {%if build.outcome == build.SUCCEEDED%}{%elif build.outcome == build.FAILED%}{%else%}{%endif%} |
{% for t in build.target_set.all %}{%if t.is_image %}{% endif %}{{t.target}}{% if t.is_image %}{% endif %} {% endfor %} |
- {{build.machine}} |
- {{build.started_on}} |
- {{build.completed_on}} |
+ {{build.machine}} |
+ {{build.started_on}} |
+ {{build.completed_on}} |
|
- {% if build.errors_no %}{{build.errors_no}} error{{build.errors_no|pluralize}}{%endif%} |
- {% if build.warnings_no %}{{build.warnings_no}} warning{{build.warnings_no|pluralize}}{%endif%} |
- {{build|timespent}} |
+ {% if build.errors_no %}{{build.errors_no}} error{{build.errors_no|pluralize}}{%endif%} |
+ {% if build.warnings_no %}{{build.warnings_no}} warning{{build.warnings_no|pluralize}}{%endif%} |
+ {{build|timespent}} |
{{build.log}} |
- {% if build.outcome == 0 %}{% for t in build.target_set.all %}{% if t.is_image %}{{build.image_fstypes}}{% endif %}{% endfor %}{% endif %} |
+ {% if build.outcome == 0 %}{% for t in build.target_set.all %}{% if t.is_image %}{{build.image_fstypes}}{% endif %}{% endfor %}{% endif %} |
{% endfor %}
diff --git a/bitbake/lib/toaster/toastergui/templates/builddashboard.html b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
index 7c58cc0b25..3b184372bf 100644
--- a/bitbake/lib/toaster/toastergui/templates/builddashboard.html
+++ b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
@@ -1,8 +1,74 @@
{% extends "basebuildpage.html" %}
+{% load humanize %}
+{% load projecttags %}
{% block localbreadcrumb %}
Dashboard
{% endblock %}
{% block buildinfomain %}
+
+
+
+
+
+
+
+
+{%if build.outcome == build.SUCCEEDED%}
+
+
+
+{%else%}
+
+{%endif%}
+
+
+
+
Build summary
+
+
+
+ - Machine
- {{build.machine}}
+ - Distro
+ - Layers
{% for i in build.layer_version_build.all %}- {{i.layer.name}}
{%endfor%}
+
+
+
+
+
+ - Total number of tasks
- {{build.task_build.all.count}}
+ - Tasks executed
- {% query build.task_build task_executed=1 order__gt=0 as exectask%}{{exectask.count}}
+ - Tasks prebuilt
- {% query build.task_build task_executed=0 order__gt=0 as noexectask%}{{noexectask.count}}
+ - Reuse
- {% query build.task_build order__gt=0 as texec %}{{noexectask.count|multiply:100|divide:texec.count}}%
+
+
+
+
+
+ - Recipes used
- {{recipecount}}
+ - Packages built
- {{build.package_set.all.count}}
+
+
+
{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
index 5f60379932..1455026754 100644
--- a/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
+++ b/bitbake/lib/toaster/toastergui/templatetags/projecttags.py
@@ -29,3 +29,21 @@ def time_difference(start_time, end_time):
def timespent(build_object):
tdsec = (build_object.completed_on - build_object.started_on).total_seconds()
return "%02d:%02d:%02d" % (int(tdsec/3600), int((tdsec - tdsec/ 3600)/ 60), int(tdsec) % 60)
+
+@register.assignment_tag
+def query(qs, **kwargs):
+ """ template tag which allows queryset filtering. Usage:
+ {% query books author=author as mybooks %}
+ {% for book in mybooks %}
+ ...
+ {% endfor %}
+ """
+ return qs.filter(**kwargs)
+
+@register.filter
+def divide(value, arg):
+ return int(value) / int(arg)
+
+@register.filter
+def multiply(value, arg):
+ return int(value) * int(arg)
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 663e03dfd2..7d4d710f83 100644
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -59,10 +59,10 @@ def _verify_parameters(g, mandatory_parameters):
return miss
return None
-def _redirect_parameters(view, g, mandatory_parameters):
+def _redirect_parameters(view, g, mandatory_parameters, *args, **kwargs):
import urllib
from django.core.urlresolvers import reverse
- url = reverse(view)
+ url = reverse(view, kwargs=kwargs)
params = {}
for i in g:
params[i] = g[i]
@@ -70,7 +70,7 @@ def _redirect_parameters(view, g, mandatory_parameters):
if not i in params:
params[i] = mandatory_parameters[i]
- return redirect(url + "?%s" % urllib.urlencode(params))
+ return redirect(url + "?%s" % urllib.urlencode(params), *args, **kwargs)
# shows the "all builds" page
@@ -82,7 +82,7 @@ def builds(request):
mandatory_parameters = { 'count': 10, 'page' : 1};
retval = _verify_parameters( request.GET, mandatory_parameters )
if retval:
- return _redirect_parameters( builds, request.GET, mandatory_parameters)
+ return _redirect_parameters( 'all-builds', request.GET, mandatory_parameters)
# retrieve the objects that will be displayed in the table
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))
@@ -125,6 +125,7 @@ def builddashboard(request, build_id):
return redirect(builds)
context = {
'build' : Build.objects.filter(pk=build_id)[0],
+ 'recipecount' : Recipe.objects.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id)).count()
}
return render(request, template, context)
@@ -186,8 +187,12 @@ def _find_task_provider(task):
def tasks(request, build_id):
template = 'task.html'
+ mandatory_parameters = { 'count': 100, 'page' : 1};
+ retval = _verify_parameters( request.GET, mandatory_parameters )
+ if retval:
+ return _redirect_parameters( 'tasks', request.GET, mandatory_parameters, build_id = build_id)
- tasks = _build_page_range(Paginator(Task.objects.filter(build=build_id), 100),request.GET.get('page', 1))
+ tasks = _build_page_range(Paginator(Task.objects.filter(build=build_id, order__gt=0), request.GET.get('count', 100)),request.GET.get('page', 1))
for t in tasks:
if t.outcome == Task.OUTCOME_COVERED:
@@ -199,16 +204,25 @@ def tasks(request, build_id):
def recipes(request, build_id):
template = 'recipe.html'
+ mandatory_parameters = { 'count': 100, 'page' : 1};
+ retval = _verify_parameters( request.GET, mandatory_parameters )
+ if retval:
+ return _redirect_parameters( 'recipes', request.GET, mandatory_parameters, build_id = build_id)
- recipes = _build_page_range(Paginator(Recipe.objects.filter(build_recipe=build_id), 100),request.GET.get('page', 1))
+ recipes = _build_page_range(Paginator(Recipe.objects.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id)), request.GET.get('count', 100)),request.GET.get('page', 1))
- context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': recipes}
+ context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': recipes, }
return render(request, template, context)
def configuration(request, build_id):
template = 'configuration.html'
+ mandatory_parameters = { 'count': 100, 'page' : 1};
+ retval = _verify_parameters( request.GET, mandatory_parameters )
+ if retval:
+ return _redirect_parameters( 'configuration', request.GET, mandatory_parameters, build_id = build_id)
+
variables = _build_page_range(Paginator(Variable.objects.filter(build=build_id), 50), request.GET.get('page', 1))
context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : variables}
return render(request, template, context)
@@ -245,7 +259,13 @@ def diskio(request, build_id):
def bpackage(request, build_id):
template = 'bpackage.html'
- packages = Package.objects.filter(build = build_id)
+ mandatory_parameters = { 'count': 100, 'page' : 1};
+ retval = _verify_parameters( request.GET, mandatory_parameters )
+ if retval:
+ return _redirect_parameters( 'packages', request.GET, mandatory_parameters, build_id = build_id)
+
+ packages = _build_page_range(Paginator(Package.objects.filter(build = build_id), request.GET.get('count', 100)),request.GET.get('page', 1))
+
context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : packages}
return render(request, template, context)