diff options
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/filtersnippet.html | 17 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/views.py | 81 |
2 files changed, 58 insertions, 40 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/filtersnippet.html b/bitbake/lib/toaster/toastergui/templates/filtersnippet.html index 2a23c27d44..e0e1181878 100644 --- a/bitbake/lib/toaster/toastergui/templates/filtersnippet.html +++ b/bitbake/lib/toaster/toastergui/templates/filtersnippet.html | |||
| @@ -4,16 +4,25 @@ | |||
| 4 | <input type="hidden" name="search" value="{{request.GET.search}}"/> | 4 | <input type="hidden" name="search" value="{{request.GET.search}}"/> |
| 5 | <div class="modal-header"> | 5 | <div class="modal-header"> |
| 6 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> | 6 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> |
| 7 | <h3>Filter {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} by '{{tc.name}}'</h3> | 7 | {% if search_term %} |
| 8 | <h3>Filter {{total_count}} {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} matching '{{search_term}}' by '{{tc.name}}'</h3> | ||
| 9 | {% else %} | ||
| 10 | <h3>Filter {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} by '{{tc.name}}'</h3> | ||
| 11 | {% endif %} | ||
| 8 | </div> | 12 | </div> |
| 9 | <div class="modal-body"> | 13 | <div class="modal-body"> |
| 10 | <p>{{f.label}}</p> | 14 | <p>{{f.label}}</p> |
| 11 | <label class="radio"> | 15 | <label class="radio"> |
| 12 | <input type="radio" name="filter" {%if request.GET.filter%}{{f.options|check_filter_status:request.GET.filter}} {%else%} checked {%endif%} value=""> All {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} | 16 | <input type="radio" name="filter" {%if request.GET.filter%}{{f.options|check_filter_status:request.GET.filter}} {%else%} checked {%endif%} value=""> All {%if filter_search_display%}{{filter_search_display|title}}{%else%}{{objectname|title}}{%endif%} ({{total_count}}) |
| 13 | </label> | 17 | </label> |
| 14 | {% for option in f.options %} | 18 | {% for option in f.options %} |
| 15 | <label class="radio"> | 19 | {% if option.2 %} |
| 16 | <input type="radio" name="filter" {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}"> {{option.0}} | 20 | <label class="radio"> |
| 21 | <input type="radio" name="filter" {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}"> {{option.0}} ({{option.2}}) | ||
| 22 | {% else %} | ||
| 23 | <label class="radio muted"> | ||
| 24 | <input type="radio" name="filter" disabled {%if request.GET.filter == option.1 %}checked{%endif%} value="{{option.1}}"> {{option.0}} ({{option.2}}) | ||
| 25 | {% endif %} | ||
| 17 | </label> | 26 | </label> |
| 18 | {% endfor %} | 27 | {% endfor %} |
| 19 | </div> | 28 | </div> |
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index f8c8ccd406..a499c30b62 100644 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
| @@ -207,8 +207,9 @@ def builds(request): | |||
| 207 | # boilerplate code that takes a request for an object type and returns a queryset | 207 | # boilerplate code that takes a request for an object type and returns a queryset |
| 208 | # for that object type. copypasta for all needed table searches | 208 | # for that object type. copypasta for all needed table searches |
| 209 | (filter_string, search_term, ordering_string) = _search_tuple(request, Build) | 209 | (filter_string, search_term, ordering_string) = _search_tuple(request, Build) |
| 210 | queryset = Build.objects.exclude(outcome = Build.IN_PROGRESS) | 210 | queryset_all = Build.objects.exclude(outcome = Build.IN_PROGRESS) |
| 211 | queryset = _get_queryset(Build, queryset, filter_string, search_term, ordering_string) | 211 | queryset_with_search = _get_queryset(Build, queryset_all, None, search_term, ordering_string) |
| 212 | queryset = _get_queryset(Build, queryset_all, filter_string, search_term, ordering_string) | ||
| 212 | 213 | ||
| 213 | # retrieve the objects that will be displayed in the table; builds a paginator and gets a page range to display | 214 | # retrieve the objects that will be displayed in the table; builds a paginator and gets a page range to display |
| 214 | build_info = _build_page_range(Paginator(queryset, request.GET.get('count', 10)),request.GET.get('page', 1)) | 215 | build_info = _build_page_range(Paginator(queryset, request.GET.get('count', 10)),request.GET.get('page', 1)) |
| @@ -235,6 +236,8 @@ def builds(request): | |||
| 235 | # TODO: common objects for all table views, adapt as needed | 236 | # TODO: common objects for all table views, adapt as needed |
| 236 | 'objects' : build_info, | 237 | 'objects' : build_info, |
| 237 | 'objectname' : "builds", | 238 | 'objectname' : "builds", |
| 239 | 'search_term' : search_term, | ||
| 240 | 'total_count' : queryset_with_search.count(), | ||
| 238 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns | 241 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns |
| 239 | 'tablecols' : [ | 242 | 'tablecols' : [ |
| 240 | {'name': 'Outcome ', # column with a single filter | 243 | {'name': 'Outcome ', # column with a single filter |
| @@ -248,8 +251,8 @@ def builds(request): | |||
| 248 | 'filter' : {'class' : 'outcome', | 251 | 'filter' : {'class' : 'outcome', |
| 249 | 'label': 'Show:', | 252 | 'label': 'Show:', |
| 250 | 'options' : [ | 253 | 'options' : [ |
| 251 | ('Successful builds', 'outcome:' + str(Build.SUCCEEDED)), # this is the field search expression | 254 | ('Successful builds', 'outcome:' + str(Build.SUCCEEDED), queryset_with_search.filter(outcome=str(Build.SUCCEEDED)).count()), # this is the field search expression |
| 252 | ('Failed builds', 'outcome:'+ str(Build.FAILED)), | 255 | ('Failed builds', 'outcome:'+ str(Build.FAILED), queryset_with_search.filter(outcome=str(Build.FAILED)).count()), |
| 253 | ] | 256 | ] |
| 254 | } | 257 | } |
| 255 | }, | 258 | }, |
| @@ -271,9 +274,9 @@ def builds(request): | |||
| 271 | 'filter' : {'class' : 'started_on', | 274 | 'filter' : {'class' : 'started_on', |
| 272 | 'label': 'Show:', | 275 | 'label': 'Show:', |
| 273 | 'options' : [ | 276 | 'options' : [ |
| 274 | ("Today's builds" , 'started_on__gte:'+timezone.now().strftime("%Y-%m-%d")), | 277 | ("Today's builds" , 'started_on__gte:'+timezone.now().strftime("%Y-%m-%d"), queryset_with_search.filter(started_on__gte=timezone.now().strftime("%Y-%m-%d")).count()), |
| 275 | ("Yesterday's builds", 'started_on__gte:'+(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d")), | 278 | ("Yesterday's builds", 'started_on__gte:'+(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d"), queryset_with_search.filter(started_on__gte=(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d")).count()), |
| 276 | ("This week's builds", 'started_on__gte:'+(timezone.now()-timedelta(days=7)).strftime("%Y-%m-%d")), | 279 | ("This week's builds", 'started_on__gte:'+(timezone.now()-timedelta(days=7)).strftime("%Y-%m-%d"), queryset_with_search.filter(started_on__gte=(timezone.now()-timedelta(days=7)).strftime("%Y-%m-%d")).count()), |
| 277 | ] | 280 | ] |
| 278 | } | 281 | } |
| 279 | }, | 282 | }, |
| @@ -284,9 +287,9 @@ def builds(request): | |||
| 284 | 'filter' : {'class' : 'completed_on', | 287 | 'filter' : {'class' : 'completed_on', |
| 285 | 'label': 'Show:', | 288 | 'label': 'Show:', |
| 286 | 'options' : [ | 289 | 'options' : [ |
| 287 | ("Today's builds", 'completed_on__gte:'+timezone.now().strftime("%Y-%m-%d")), | 290 | ("Today's builds", 'completed_on__gte:'+timezone.now().strftime("%Y-%m-%d"), queryset_with_search.filter(completed_on__gte=timezone.now().strftime("%Y-%m-%d")).count()), |
| 288 | ("Yesterday's builds", 'completed_on__gte:'+(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d")), | 291 | ("Yesterday's builds", 'completed_on__gte:'+(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d"), queryset_with_search.filter(completed_on__gte=(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d")).count()), |
| 289 | ("This week's builds", 'completed_on__gte:'+(timezone.now()-timedelta(days=7)).strftime("%Y-%m-%d")), | 292 | ("This week's builds", 'completed_on__gte:'+(timezone.now()-timedelta(days=7)).strftime("%Y-%m-%d"), queryset_with_search.filter(completed_on__gte=(timezone.now()-timedelta(days=7)).strftime("%Y-%m-%d")).count()), |
| 290 | ] | 293 | ] |
| 291 | } | 294 | } |
| 292 | }, | 295 | }, |
| @@ -295,8 +298,8 @@ def builds(request): | |||
| 295 | 'filter' : {'class' : 'failed_tasks', | 298 | 'filter' : {'class' : 'failed_tasks', |
| 296 | 'label': 'Show:', | 299 | 'label': 'Show:', |
| 297 | 'options' : [ | 300 | 'options' : [ |
| 298 | ('Builds with failed tasks', 'task_build__outcome:4'), | 301 | ('Builds with failed tasks', 'task_build__outcome:4', queryset_with_search.filter(task_build__outcome=4).count()), |
| 299 | ('Builds without failed tasks', 'task_build__outcome:NOT4'), | 302 | ('Builds without failed tasks', 'task_build__outcome:NOT4', queryset_with_search.filter(~Q(task_build__outcome=4)).count()), |
| 300 | ] | 303 | ] |
| 301 | } | 304 | } |
| 302 | }, | 305 | }, |
| @@ -307,8 +310,8 @@ def builds(request): | |||
| 307 | 'filter' : {'class' : 'errors_no', | 310 | 'filter' : {'class' : 'errors_no', |
| 308 | 'label': 'Show:', | 311 | 'label': 'Show:', |
| 309 | 'options' : [ | 312 | 'options' : [ |
| 310 | ('Builds with errors', 'errors_no__gte:1'), | 313 | ('Builds with errors', 'errors_no__gte:1', queryset_with_search.filter(errors_no__gte=1).count()), |
| 311 | ('Builds without errors', 'errors_no:0'), | 314 | ('Builds without errors', 'errors_no:0', queryset_with_search.filter(errors_no=0).count()), |
| 312 | ] | 315 | ] |
| 313 | } | 316 | } |
| 314 | }, | 317 | }, |
| @@ -319,8 +322,8 @@ def builds(request): | |||
| 319 | 'filter' : {'class' : 'warnings_no', | 322 | 'filter' : {'class' : 'warnings_no', |
| 320 | 'label': 'Show:', | 323 | 'label': 'Show:', |
| 321 | 'options' : [ | 324 | 'options' : [ |
| 322 | ('Builds with warnings','warnings_no__gte:1'), | 325 | ('Builds with warnings','warnings_no__gte:1', queryset_with_search.filter(warnings_no__gte=1).count()), |
| 323 | ('Builds without warnings','warnings_no:0'), | 326 | ('Builds without warnings','warnings_no:0', queryset_with_search.filter(warnings_no=0).count()), |
| 324 | ] | 327 | ] |
| 325 | } | 328 | } |
| 326 | }, | 329 | }, |
| @@ -492,8 +495,9 @@ def tasks_common(request, build_id, variant): | |||
| 492 | if retval: | 495 | if retval: |
| 493 | return _redirect_parameters( variant, request.GET, mandatory_parameters, build_id = build_id) | 496 | return _redirect_parameters( variant, request.GET, mandatory_parameters, build_id = build_id) |
| 494 | (filter_string, search_term, ordering_string) = _search_tuple(request, Task) | 497 | (filter_string, search_term, ordering_string) = _search_tuple(request, Task) |
| 495 | queryset = Task.objects.filter(build=build_id, order__gt=0) | 498 | queryset_all = Task.objects.filter(build=build_id, order__gt=0) |
| 496 | queryset = _get_queryset(Task, queryset, filter_string, search_term, ordering_string) | 499 | queryset_with_search = _get_queryset(Task, queryset_all, None , search_term, ordering_string) |
| 500 | queryset = _get_queryset(Task, queryset_all, filter_string, search_term, ordering_string) | ||
| 497 | 501 | ||
| 498 | tasks = _build_page_range(Paginator(queryset, request.GET.get('count', 100)),request.GET.get('page', 1)) | 502 | tasks = _build_page_range(Paginator(queryset, request.GET.get('count', 100)),request.GET.get('page', 1)) |
| 499 | 503 | ||
| @@ -537,8 +541,8 @@ def tasks_common(request, build_id, variant): | |||
| 537 | 'class' : 'executed', | 541 | 'class' : 'executed', |
| 538 | 'label': 'Show:', | 542 | 'label': 'Show:', |
| 539 | 'options' : [ | 543 | 'options' : [ |
| 540 | ('Executed Tasks', 'task_executed:1'), | 544 | ('Executed Tasks', 'task_executed:1', queryset_with_search.filter(task_executed=1).count()), |
| 541 | ('Not Executed Tasks', 'task_executed:0'), | 545 | ('Not Executed Tasks', 'task_executed:0', queryset_with_search.filter(task_executed=0).count()), |
| 542 | ] | 546 | ] |
| 543 | } | 547 | } |
| 544 | 548 | ||
| @@ -553,12 +557,12 @@ def tasks_common(request, build_id, variant): | |||
| 553 | 'class' : 'outcome', | 557 | 'class' : 'outcome', |
| 554 | 'label': 'Show:', | 558 | 'label': 'Show:', |
| 555 | 'options' : [ | 559 | 'options' : [ |
| 556 | ('Succeeded Tasks', 'outcome:%d'%Task.OUTCOME_SUCCESS), | 560 | ('Succeeded Tasks', 'outcome:%d'%Task.OUTCOME_SUCCESS, queryset_with_search.filter(outcome=Task.OUTCOME_SUCCESS).count() ), |
| 557 | ('Failed Tasks', 'outcome:%d'%Task.OUTCOME_FAILED), | 561 | ('Failed Tasks', 'outcome:%d'%Task.OUTCOME_FAILED, queryset_with_search.filter(outcome=Task.OUTCOME_FAILED).count()), |
| 558 | ('Cached Tasks', 'outcome:%d'%Task.OUTCOME_CACHED), | 562 | ('Cached Tasks', 'outcome:%d'%Task.OUTCOME_CACHED, queryset_with_search.filter(outcome=Task.OUTCOME_CACHED).count()), |
| 559 | ('Prebuilt Tasks', 'outcome:%d'%Task.OUTCOME_PREBUILT), | 563 | ('Prebuilt Tasks', 'outcome:%d'%Task.OUTCOME_PREBUILT, queryset_with_search.filter(outcome=Task.OUTCOME_PREBUILT).count()), |
| 560 | ('Covered Tasks', 'outcome:%d'%Task.OUTCOME_COVERED), | 564 | ('Covered Tasks', 'outcome:%d'%Task.OUTCOME_COVERED, queryset_with_search.filter(outcome=Task.OUTCOME_COVERED).count()), |
| 561 | ('Empty Tasks', 'outcome:%d'%Task.OUTCOME_EMPTY), | 565 | ('Empty Tasks', 'outcome:%d'%Task.OUTCOME_EMPTY, queryset_with_search.filter(outcome=Task.OUTCOME_NA).count()), |
| 562 | ] | 566 | ] |
| 563 | } | 567 | } |
| 564 | 568 | ||
| @@ -580,10 +584,10 @@ def tasks_common(request, build_id, variant): | |||
| 580 | 'class' : 'cache_attempt', | 584 | 'class' : 'cache_attempt', |
| 581 | 'label': 'Show:', | 585 | 'label': 'Show:', |
| 582 | 'options' : [ | 586 | 'options' : [ |
| 583 | ('Tasks with cache attempts', 'sstate_result:%d'%Task.SSTATE_NA), | 587 | ('Tasks with cache attempts', 'sstate_result:%d'%Task.SSTATE_NA, queryset_with_search.filter(sstate_result=Task.SSTATE_NA).count()), |
| 584 | ("Tasks with 'File not in cache' attempts", 'sstate_result:%d'%Task.SSTATE_MISS), | 588 | ("Tasks with 'File not in cache' attempts", 'sstate_result:%d'%Task.SSTATE_MISS, queryset_with_search.filter(sstate_result=Task.SSTATE_MISS).count()), |
| 585 | ("Tasks with 'Failed' cache attempts", 'sstate_result:%d'%Task.SSTATE_FAILED), | 589 | ("Tasks with 'Failed' cache attempts", 'sstate_result:%d'%Task.SSTATE_FAILED, queryset_with_search.filter(sstate_result=Task.SSTATE_FAILED).count()), |
| 586 | ("Tasks with 'Succeeded' cache attempts", 'sstate_result:%d'%Task.SSTATE_RESTORED), | 590 | ("Tasks with 'Succeeded' cache attempts", 'sstate_result:%d'%Task.SSTATE_RESTORED, queryset_with_search.filter(sstate_result=Task.SSTATE_RESTORED).count()), |
| 587 | ] | 591 | ] |
| 588 | } | 592 | } |
| 589 | 593 | ||
| @@ -621,6 +625,8 @@ def tasks_common(request, build_id, variant): | |||
| 621 | 'title': title_variant, | 625 | 'title': title_variant, |
| 622 | 'build': Build.objects.filter(pk=build_id)[0], | 626 | 'build': Build.objects.filter(pk=build_id)[0], |
| 623 | 'objects': tasks, | 627 | 'objects': tasks, |
| 628 | 'search_term': search_term, | ||
| 629 | 'total_count': queryset_with_search.count(), | ||
| 624 | 'tablecols':[ | 630 | 'tablecols':[ |
| 625 | tc_order, | 631 | tc_order, |
| 626 | tc_recipe, | 632 | tc_recipe, |
| @@ -784,6 +790,7 @@ def configvars(request, build_id): | |||
| 784 | 790 | ||
| 785 | (filter_string, search_term, ordering_string) = _search_tuple(request, Variable) | 791 | (filter_string, search_term, ordering_string) = _search_tuple(request, Variable) |
| 786 | queryset = Variable.objects.filter(build=build_id).exclude(variable_name__istartswith='B_').exclude(variable_name__istartswith='do_') | 792 | queryset = Variable.objects.filter(build=build_id).exclude(variable_name__istartswith='B_').exclude(variable_name__istartswith='do_') |
| 793 | queryset_with_search = _get_queryset(Variable, queryset, None, search_term, ordering_string).distinct().exclude(variable_value='',vhistory__file_name__isnull=True) | ||
| 787 | queryset = _get_queryset(Variable, queryset, filter_string, search_term, ordering_string) | 794 | queryset = _get_queryset(Variable, queryset, filter_string, search_term, ordering_string) |
| 788 | # remove duplicate records from multiple search hits in the VariableHistory table | 795 | # remove duplicate records from multiple search hits in the VariableHistory table |
| 789 | queryset = queryset.distinct() | 796 | queryset = queryset.distinct() |
| @@ -811,6 +818,8 @@ def configvars(request, build_id): | |||
| 811 | 'file_filter': file_filter, | 818 | 'file_filter': file_filter, |
| 812 | 'build': Build.objects.filter(pk=build_id)[0], | 819 | 'build': Build.objects.filter(pk=build_id)[0], |
| 813 | 'objects' : variables, | 820 | 'objects' : variables, |
| 821 | 'total_count':queryset_with_search.count(), | ||
| 822 | 'search_term':search_term, | ||
| 814 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns | 823 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns |
| 815 | 'tablecols' : [ | 824 | 'tablecols' : [ |
| 816 | {'name': 'Variable ', | 825 | {'name': 'Variable ', |
| @@ -835,11 +844,11 @@ def configvars(request, build_id): | |||
| 835 | 'class' : 'vhistory__file_name', | 844 | 'class' : 'vhistory__file_name', |
| 836 | 'label': 'Show:', | 845 | 'label': 'Show:', |
| 837 | 'options' : [ | 846 | 'options' : [ |
| 838 | ('Local configuration variables', 'vhistory__file_name__regex:conf/(local|bblayers).conf'), | 847 | ('Local configuration variables', 'vhistory__file_name__regex:conf/(local|bblayers).conf', queryset_with_search.filter(vhistory__file_name__contains='conf/local.conf').count()), |
| 839 | ('Machine configuration variables', 'vhistory__file_name__contains:conf/machine/'), | 848 | ('Machine configuration variables', 'vhistory__file_name__contains:conf/machine/',queryset_with_search.filter(vhistory__file_name__contains='conf/machine').count()), |
| 840 | ('Distro configuration variables', 'vhistory__file_name__contains:conf/distro/'), | 849 | ('Distro configuration variables', 'vhistory__file_name__contains:conf/distro/',queryset_with_search.filter(vhistory__file_name__contains='conf/distro').count()), |
| 841 | ('Layer configuration variables', 'vhistory__file_name__contains:conf/layer.conf'), | 850 | ('Layer configuration variables', 'vhistory__file_name__contains:conf/layer.conf',queryset_with_search.filter(vhistory__file_name__contains='conf/layer.conf').count()), |
| 842 | ('bitbake.conf variables', 'vhistory__file_name__contains:/bitbake.conf'), | 851 | ('bitbake.conf variables', 'vhistory__file_name__contains:/bitbake.conf',queryset_with_search.filter(vhistory__file_name__contains='/bitbake.conf').count()), |
| 843 | ] | 852 | ] |
| 844 | }, | 853 | }, |
| 845 | }, | 854 | }, |
| @@ -851,7 +860,7 @@ def configvars(request, build_id): | |||
| 851 | 'class' : 'description', | 860 | 'class' : 'description', |
| 852 | 'label': 'Show:', | 861 | 'label': 'Show:', |
| 853 | 'options' : [ | 862 | 'options' : [ |
| 854 | ('Variables with description', 'description__regex:.+'), | 863 | ('Variables with description', 'description__regex:.+', queryset_with_search.filter(description__regex='.+').count()), |
| 855 | ] | 864 | ] |
| 856 | }, | 865 | }, |
| 857 | }, | 866 | }, |
