diff options
author | Elliot Smith <elliot.smith@intel.com> | 2016-01-15 13:00:55 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-01-15 16:28:59 +0000 |
commit | 87bcfb740dd2d9944e35a2a1f71cbf8ff3b266e9 (patch) | |
tree | 787b2efb6bd8a9136bd6f38336c763ecc2366fe9 /lib/toaster/toastergui/tables.py | |
parent | f17cfa009e58833e0e55884fa04de8abd522b6bc (diff) | |
download | bitbake-87bcfb740dd2d9944e35a2a1f71cbf8ff3b266e9.tar.gz |
toastergui: convert project builds page to ToasterTable
Use the all builds ToasterTable as the basis for the project builds
ToasterTable.
[YOCTO #8738]
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 'lib/toaster/toastergui/tables.py')
-rw-r--r-- | lib/toaster/toastergui/tables.py | 184 |
1 files changed, 151 insertions, 33 deletions
diff --git a/lib/toaster/toastergui/tables.py b/lib/toaster/toastergui/tables.py index 58abe36b0..d0ed49625 100644 --- a/lib/toaster/toastergui/tables.py +++ b/lib/toaster/toastergui/tables.py @@ -23,9 +23,11 @@ from toastergui.widgets import ToasterTable from toastergui.querysetfilter import QuerysetFilter from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project from orm.models import CustomImageRecipe, Package, Build, LogMessage, Task +from orm.models import ProjectTarget from django.db.models import Q, Max, Count from django.conf.urls import url -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse, resolve +from django.http import HttpResponse from django.views.generic import TemplateView import itertools @@ -775,7 +777,7 @@ class ProjectsTable(ToasterTable): ''' errors_template = ''' - {% if data.get_number_of_builds > 0 %} + {% if data.get_number_of_builds > 0 and data.get_last_errors > 0 %} <a class="errors.count error" href="{% url "builddashboard" data.get_last_build_id %}#errors"> {{data.get_last_errors}} error{{data.get_last_errors | pluralize}} @@ -784,7 +786,7 @@ class ProjectsTable(ToasterTable): ''' warnings_template = ''' - {% if data.get_number_of_builds > 0 %} + {% if data.get_number_of_builds > 0 and data.get_last_warnings > 0 %} <a class="warnings.count warning" href="{% url "builddashboard" data.get_last_build_id %}#warnings"> {{data.get_last_warnings}} warning{{data.get_last_warnings | pluralize}} @@ -886,30 +888,45 @@ class BuildsTable(ToasterTable): def __init__(self, *args, **kwargs): super(BuildsTable, self).__init__(*args, **kwargs) self.default_orderby = '-completed_on' - self.title = 'All builds' self.static_context_extra['Build'] = Build self.static_context_extra['Task'] = Task + # attributes that are overridden in subclasses + + # title for the page + self.title = '' + + # 'project' or 'all'; determines how the mrb (most recent builds) + # section is displayed + self.mrb_type = '' + + def get_builds(self): + """ + overridden in ProjectBuildsTable to return builds for a + single project + """ + return Build.objects.all() + def get_context_data(self, **kwargs): context = super(BuildsTable, self).get_context_data(**kwargs) # for the latest builds section - queryset = Build.objects.all() + builds = self.get_builds() finished_criteria = Q(outcome=Build.SUCCEEDED) | Q(outcome=Build.FAILED) latest_builds = itertools.chain( - queryset.filter(outcome=Build.IN_PROGRESS).order_by("-started_on"), - queryset.filter(finished_criteria).order_by("-completed_on")[:3] + builds.filter(outcome=Build.IN_PROGRESS).order_by("-started_on"), + builds.filter(finished_criteria).order_by("-completed_on")[:3] ) context['mru'] = list(latest_builds) - context['mrb_type'] = 'all' + context['mrb_type'] = self.mrb_type return context def setup_queryset(self, *args, **kwargs): - queryset = Build.objects.all() + queryset = self.get_builds() # don't include in progress builds queryset = queryset.exclude(outcome=Build.IN_PROGRESS) @@ -949,7 +966,8 @@ class BuildsTable(ToasterTable): {% if data.cooker_log_path %} <a href="{% url "build_artifact" data.id "cookerlog" data.id %}"> - <i class="icon-download-alt" title="Download build log"></i> + <i class="icon-download-alt get-help" + data-original-title="Download build log"></i> </a> {% endif %} ''' @@ -1031,19 +1049,6 @@ class BuildsTable(ToasterTable): {% endif %} ''' - project_template = ''' - {% load project_url_tag %} - <a href="{% project_url data.project %}"> - {{data.project.name}} - </a> - {% if data.project.is_default %} - <i class="icon-question-sign get-help hover-help" title="" - data-original-title="This project shows information about - the builds you start from the command line while Toaster is - running" style="visibility: hidden;"></i> - {% endif %} - ''' - self.add_column(title='Outcome', help_text='Final state of the build (successful \ or failed)', @@ -1098,16 +1103,16 @@ class BuildsTable(ToasterTable): help_text='The number of errors encountered during \ the build (if any)', hideable=True, - orderable=False, - static_data_name='errors', + orderable=True, + static_data_name='errors_no', static_data_template=errors_template) self.add_column(title='Warnings', help_text='The number of warnings encountered during \ the build (if any)', hideable=True, - orderable=False, - static_data_name='warnings', + orderable=True, + static_data_name='warnings_no', static_data_template=warnings_template) self.add_column(title='Time', @@ -1125,12 +1130,6 @@ class BuildsTable(ToasterTable): static_data_name='image_files', static_data_template=image_files_template) - self.add_column(title='Project', - hideable=True, - orderable=False, - static_data_name='project-name', - static_data_template=project_template) - def setup_filters(self, *args, **kwargs): # outcomes outcome_filter = TableFilter( @@ -1239,3 +1238,122 @@ class BuildsTable(ToasterTable): failed_tasks_filter.add_action(with_failed_tasks_action) failed_tasks_filter.add_action(without_failed_tasks_action) self.add_filter(failed_tasks_filter) + + def post(self, request, *args, **kwargs): + """ Process HTTP POSTs which make build requests """ + + project = Project.objects.get(pk=kwargs['pid']) + + if 'buildCancel' in request.POST: + for i in request.POST['buildCancel'].strip().split(" "): + try: + br = BuildRequest.objects.select_for_update().get(project = project, pk = i, state__lte = BuildRequest.REQ_QUEUED) + br.state = BuildRequest.REQ_DELETED + br.save() + except BuildRequest.DoesNotExist: + pass + + if 'buildDelete' in request.POST: + for i in request.POST['buildDelete'].strip().split(" "): + try: + BuildRequest.objects.select_for_update().get(project = project, pk = i, state__lte = BuildRequest.REQ_DELETED).delete() + except BuildRequest.DoesNotExist: + pass + + if 'targets' in request.POST: + ProjectTarget.objects.filter(project = project).delete() + s = str(request.POST['targets']) + for t in s.translate(None, ";%|\"").split(" "): + if ":" in t: + target, task = t.split(":") + else: + target = t + task = "" + ProjectTarget.objects.create(project = project, + target = target, + task = task) + project.schedule_build() + + # redirect back to builds page so any new builds in progress etc. + # are visible + response = HttpResponse() + response.status_code = 302 + response['Location'] = request.build_absolute_uri() + return response + +class AllBuildsTable(BuildsTable): + """ Builds page for all builds """ + + def __init__(self, *args, **kwargs): + super(AllBuildsTable, self).__init__(*args, **kwargs) + self.title = 'All builds' + self.mrb_type = 'all' + + def setup_columns(self, *args, **kwargs): + """ + All builds page shows a column for the project + """ + + super(AllBuildsTable, self).setup_columns(*args, **kwargs) + + project_template = ''' + {% load project_url_tag %} + <a href="{% project_url data.project %}"> + {{data.project.name}} + </a> + {% if data.project.is_default %} + <i class="icon-question-sign get-help hover-help" title="" + data-original-title="This project shows information about + the builds you start from the command line while Toaster is + running" style="visibility: hidden;"></i> + {% endif %} + ''' + + self.add_column(title='Project', + hideable=True, + orderable=True, + static_data_name='project', + static_data_template=project_template) + +class ProjectBuildsTable(BuildsTable): + """ + Builds page for a single project; a BuildsTable, with the queryset + filtered by project + """ + + def __init__(self, *args, **kwargs): + super(ProjectBuildsTable, self).__init__(*args, **kwargs) + self.title = 'All project builds' + self.mrb_type = 'project' + + # set from the querystring + self.project_id = None + + def setup_queryset(self, *args, **kwargs): + """ + NOTE: self.project_id must be set before calling super(), + as it's used in setup_queryset() + """ + self.project_id = kwargs['pid'] + super(ProjectBuildsTable, self).setup_queryset(*args, **kwargs) + + project = Project.objects.get(pk=self.project_id) + self.queryset = self.queryset.filter(project=project) + + def get_context_data(self, **kwargs): + """ + NOTE: self.project_id must be set before calling super(), + as it's used in get_context_data() + """ + self.project_id = kwargs['pid'] + + context = super(ProjectBuildsTable, self).get_context_data(**kwargs) + context['project'] = Project.objects.get(pk=self.project_id) + + return context + + def get_builds(self): + """ override: only return builds for the relevant project """ + + project = Project.objects.get(pk=self.project_id) + return Build.objects.filter(project=project) |