diff --git a/layerindex/urls.py b/layerindex/urls.py index bfa7628..9a5d01c 100644 --- a/layerindex/urls.py +++ b/layerindex/urls.py @@ -8,7 +8,7 @@ from django.conf.urls import * from django.views.generic import TemplateView, DetailView, ListView, RedirectView from django.views.defaults import page_not_found from django.core.urlresolvers import reverse_lazy -from layerindex.views import LayerListView, LayerReviewListView, LayerReviewDetailView, RecipeSearchView, MachineSearchView, LayerDetailView, edit_layer_view, delete_layer_view, edit_layernote_view, delete_layernote_view, HistoryListView, EditProfileFormView, AdvancedRecipeSearchView, BulkChangeView, BulkChangeSearchView, bulk_change_edit_view, bulk_change_patch_view, BulkChangeDeleteView, RecipeDetailView, RedirectParamsView, ClassicRecipeSearchView, ClassicRecipeDetailView, ClassicRecipeStatsView, LayerUpdateDetailView, UpdateListView, UpdateDetailView, StatsView, publish_view, LayerCheckListView +from layerindex.views import LayerListView, LayerReviewListView, LayerReviewDetailView, RecipeSearchView, MachineSearchView, LayerDetailView, edit_layer_view, delete_layer_view, edit_layernote_view, delete_layernote_view, HistoryListView, EditProfileFormView, AdvancedRecipeSearchView, BulkChangeView, BulkChangeSearchView, bulk_change_edit_view, bulk_change_patch_view, BulkChangeDeleteView, RecipeDetailView, RedirectParamsView, ClassicRecipeSearchView, ClassicRecipeDetailView, ClassicRecipeStatsView, LayerUpdateDetailView, UpdateListView, UpdateDetailView, StatsView, publish_view, LayerCheckListView, BBClassCheckListView from layerindex.models import LayerItem, Recipe, RecipeChangeset from rest_framework import routers from . import restviews @@ -154,5 +154,9 @@ urlpatterns = [ LayerCheckListView.as_view( template_name='layerindex/layerchecklist.html'), name='layer_checklist'), + url(r'^ajax/classchecklist/(?P[-\w]+)/$', + BBClassCheckListView.as_view( + template_name='layerindex/classchecklist.html'), + name='class_checklist'), url(r'.*', page_not_found, kwargs={'exception': Exception("Page not Found")}) ] diff --git a/layerindex/views.py b/layerindex/views.py index f2274f8..93eae8e 100644 --- a/layerindex/views.py +++ b/layerindex/views.py @@ -947,6 +947,98 @@ class LayerCheckListView(ListView): _check_url_branch(self.kwargs) return LayerBranch.objects.filter(branch__name=self.kwargs['branch']).filter(layer__status__in=['P', 'X']).order_by('layer__name') +class BBClassCheckListView(ListView): + context_object_name = 'classes' + + def get_queryset(self): + _check_url_branch(self.kwargs) + nonrecipe_classes = ['archiver', + 'base', + 'buildhistory', + 'bugzilla', + 'buildstats', + 'buildstats-summary', + 'ccache', + 'chrpath', + 'copyleft_compliance', + 'copyleft_filter', + 'cve-check', + 'debian', + 'devshell', + 'devtool-source', + 'distrodata', + 'extrausers', + 'icecc', + 'image-buildinfo', + 'image-container', + 'image-combined-dbg', + 'image-live', + 'image-mklibs', + 'image-prelink', + 'image_types', + 'image_types_wic', + 'insane', + 'license', + 'license_image', + 'live-vm-common', + 'logging', + 'metadata_scm', + 'migrate_localcount', + 'mirrors', + 'multilib', + 'multilib_global', + 'multilib_header', + 'oelint', + 'own-mirrors', + 'package', + 'package_deb', + 'package_ipk', + 'package_rpm', + 'package_tar', + 'packagedata', + 'packagefeed-stability', + 'patch', + 'primport', + 'prexport', + 'recipe_sanity', + 'remove-libtool', + 'report-error', + 'reproducible_build', + 'reproducible_build_simple', + 'rm_work', + 'rm_work_and_downloads', + 'rootfs-postcommands', + 'rootfs_deb', + 'rootfs_ipk', + 'rootfs_rpm', + 'rootfsdebugfiles', + 'sanity', + 'sign_ipk', + 'sign_package_feed', + 'sign_rpm', + 'siteconfig', + 'siteinfo', + 'spdx', + 'sstate', + 'staging', + 'syslinux', + 'systemd-boot', + 'terminal', + 'testexport', + 'testimage', + 'testimage-auto', + 'testsdk', + 'tinderclient', + 'toaster', + 'toolchain-scripts', + 'toolchain-scripts-base', + 'uninative', + 'useradd-staticids', + 'utility-tasks', + 'utils', + ] + return BBClass.objects.filter(layerbranch__branch__name=self.kwargs['branch']).filter(layerbranch__layer__name=settings.CORE_LAYER_NAME).exclude(name__in=nonrecipe_classes).order_by('name') + class ClassicRecipeSearchView(RecipeSearchView): def render_to_response(self, context, **kwargs): @@ -1028,6 +1120,10 @@ class ClassicRecipeSearchView(RecipeSearchView): init_rqs = Recipe.objects.filter(layerbranch__branch__name='master') if layer_ids: init_rqs = init_rqs.filter(layerbranch__layer__id__in=layer_ids) + excludeclasses_param = self.request.GET.get('excludeclasses', '') + if excludeclasses_param: + for inherit in excludeclasses_param.split(','): + init_rqs = init_rqs.exclude(inherits=inherit).exclude(inherits__startswith=inherit + ' ').exclude(inherits__endswith=' ' + inherit).exclude(inherits__contains=' %s ' % inherit) all_values = [] if filtered: if isinstance(qs, list): @@ -1078,6 +1174,14 @@ class ClassicRecipeSearchView(RecipeSearchView): layer_ids = [] context['selectedlayers_display'] = ' (any)' context['selectedlayers'] = layer_ids + + excludeclasses_param = self.request.GET.get('excludeclasses', '') + if excludeclasses_param: + context['excludeclasses_display'] = excludeclasses_param + context['excludeclasses'] = excludeclasses_param.split(',') + else: + context['excludeclasses_display'] = ' (none)' + context['excludeclasses'] = [] return context diff --git a/templates/layerindex/classchecklist.html b/templates/layerindex/classchecklist.html new file mode 100644 index 0000000..a3b1b6b --- /dev/null +++ b/templates/layerindex/classchecklist.html @@ -0,0 +1,21 @@ +{% comment %} + + layerindex-web - class check list AJAX template + + Copyright (C) 2018 Intel Corporation + Licensed under the MIT license, see COPYING.MIT for details + +{% endcomment %} + +{% autoescape on %} + + {% for classitem in classes %} + + + + + {% endfor %} +
+ +
+{% endautoescape %} diff --git a/templates/layerindex/classicrecipes.html b/templates/layerindex/classicrecipes.html index c22bb19..7a07216 100644 --- a/templates/layerindex/classicrecipes.html +++ b/templates/layerindex/classicrecipes.html @@ -87,7 +87,39 @@ {% endfor %} - + + + + + Exclude classes + + +
+ + ... +
+ + + + + + @@ -215,6 +247,17 @@ else $('#id_selectedlayers_display').val(' (any)') } + update_excludeclasses_display = function() { + classnames = []; + $('.filterclasscheckbox:checked').each(function() { + classnames.push($(this).attr('value')); + }); + if(classnames.length) + $('#id_excludeclasses_display').val(classnames) + else + $('#id_excludeclasses_display').val(' (none)'); + $('#id_excludeclasses').val(classnames) + } update_filters_enabled = function() { if( $('#id_reversed').is(":checked") ) { $('#id_reversed_fields').show() @@ -254,8 +297,40 @@ }); } } + select_excludeclass_checkboxes = function() { + $('.filterclasscheckbox').attr('checked', false); + excludeclasses = $('#id_excludeclasses').val().split(','); + for(i in excludeclasses) { + $('#id_classcheckbox_' + excludeclasses[i]).attr('checked', true); + } + } + setup_excludeclass_list = function() { + if( $.trim($('#id_excludeclassdialog_list').html()) ) { + select_excludeclass_checkboxes() + } + else { + $('#id_excludeclassdialog_list').html('Loading...'); + $('#id_excludeclassdialog_ok').prop('disabled', true) + $('#id_excludeclassdialog_ok').addClass('disabled') + $.ajax({ + url: '{% url 'class_checklist' 'master' %}', + dataType: 'html', + success: function( resp ) { + $('#id_excludeclassdialog_list').html(resp); + select_excludeclass_checkboxes() + $('#id_excludeclassdialog_ok').prop('disabled', false) + $('#id_excludeclassdialog_ok').removeClass('disabled') + }, + error: function( req, status, err ) { + $('#id_excludeclassdialog_list').html(err); + console.log( 'something went wrong', status, err ); + } + }); + } + } $(document).ready(function() { $('#id_selectedlayers_display').prop('readonly', true) + $('#id_excludeclasses_display').prop('readonly', true) update_filters_enabled() $('[data-toggle="tooltip"]').tooltip(); firstfield = $("#search-form input:text").first() @@ -274,6 +349,15 @@ $('#id_select_layers').click(function (e) { setup_layer_list() }); + $('#id_excludeclassdialog_select_none').click(function (e) { + $('.filterclasscheckbox').attr('checked', false); + }); + $('#id_excludeclassdialog_ok').click(function (e) { + update_excludeclasses_display() + }); + $('#id_select_excludeclasses').click(function (e) { + setup_excludeclass_list() + }); $('#id_reversed').click(function (e) { update_filters_enabled() });