diff options
Diffstat (limited to 'bitbake/lib/toaster/toastergui/tables.py')
-rw-r--r-- | bitbake/lib/toaster/toastergui/tables.py | 149 |
1 files changed, 124 insertions, 25 deletions
diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py index 7b335c8870..6c167a9f4d 100644 --- a/bitbake/lib/toaster/toastergui/tables.py +++ b/bitbake/lib/toaster/toastergui/tables.py | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | from toastergui.widgets import ToasterTable | 22 | from toastergui.widgets import ToasterTable |
23 | from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project | 23 | from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project |
24 | from orm.models import CustomImageRecipe, Package, Build, LogMessage, Task | 24 | from orm.models import CustomImageRecipe, Package, Target, Build, LogMessage, Task |
25 | from orm.models import ProjectTarget | 25 | from orm.models import ProjectTarget |
26 | from django.db.models import Q, Max, Count, When, Case, Value, IntegerField | 26 | from django.db.models import Q, Max, Count, When, Case, Value, IntegerField |
27 | from django.conf.urls import url | 27 | from django.conf.urls import url |
@@ -483,8 +483,8 @@ class CustomImagesTable(ToasterTable): | |||
483 | def get_context_data(self, **kwargs): | 483 | def get_context_data(self, **kwargs): |
484 | context = super(CustomImagesTable, self).get_context_data(**kwargs) | 484 | context = super(CustomImagesTable, self).get_context_data(**kwargs) |
485 | project = Project.objects.get(pk=kwargs['pid']) | 485 | project = Project.objects.get(pk=kwargs['pid']) |
486 | # TODO put project into the ToasterTable base class | ||
486 | context['project'] = project | 487 | context['project'] = project |
487 | context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project'])) | ||
488 | return context | 488 | return context |
489 | 489 | ||
490 | def setup_queryset(self, *args, **kwargs): | 490 | def setup_queryset(self, *args, **kwargs): |
@@ -502,22 +502,31 @@ class CustomImagesTable(ToasterTable): | |||
502 | 502 | ||
503 | self.add_column(title="Custom image", | 503 | self.add_column(title="Custom image", |
504 | hideable=False, | 504 | hideable=False, |
505 | orderable=True, | ||
506 | field_name="name", | ||
505 | static_data_name="name", | 507 | static_data_name="name", |
506 | static_data_template=name_link_template) | 508 | static_data_template=name_link_template) |
507 | 509 | ||
508 | self.add_column(title="Recipe file", | 510 | self.add_column(title="Recipe file", |
509 | static_data_name='recipe_file', | 511 | static_data_name='recipe_file', |
510 | static_data_template='') | 512 | static_data_template='', |
513 | field_name='local_path') | ||
514 | |||
515 | approx_packages_template = ''' | ||
516 | <a href="{% url 'customrecipe' extra.pid data.id %}"> | ||
517 | {{data.package_set.all|length}} | ||
518 | </a>''' | ||
511 | 519 | ||
512 | approx_packages_template = '<a href="#imagedetails">{{data.packages.all|length}}</a>' | ||
513 | self.add_column(title="Approx packages", | 520 | self.add_column(title="Approx packages", |
514 | static_data_name='approx_packages', | 521 | static_data_name='approx_packages', |
515 | static_data_template=approx_packages_template) | 522 | static_data_template=approx_packages_template) |
516 | 523 | ||
517 | 524 | ||
518 | build_btn_template = '''<button data-recipe-name="{{data.name}}" | 525 | build_btn_template = ''' |
526 | <button data-recipe-name="{{data.name}}" | ||
519 | class="btn btn-block build-recipe-btn" style="margin-top: 5px;" > | 527 | class="btn btn-block build-recipe-btn" style="margin-top: 5px;" > |
520 | Build</button>''' | 528 | Build |
529 | </button>''' | ||
521 | 530 | ||
522 | self.add_column(title="Build", | 531 | self.add_column(title="Build", |
523 | hideable=False, | 532 | hideable=False, |
@@ -540,12 +549,19 @@ class ImageRecipesTable(RecipesTable): | |||
540 | 549 | ||
541 | 550 | ||
542 | def setup_columns(self, *args, **kwargs): | 551 | def setup_columns(self, *args, **kwargs): |
552 | |||
553 | name_link_template = ''' | ||
554 | <a href="{% url 'recipedetails' extra.pid data.pk %}">{{data.name}}</a> | ||
555 | ''' | ||
556 | |||
543 | self.add_column(title="Image recipe", | 557 | self.add_column(title="Image recipe", |
544 | help_text="When you build an image recipe, you get an " | 558 | help_text="When you build an image recipe, you get an " |
545 | "image: a root file system you can" | 559 | "image: a root file system you can" |
546 | "deploy to a machine", | 560 | "deploy to a machine", |
547 | hideable=False, | 561 | hideable=False, |
548 | orderable=True, | 562 | orderable=True, |
563 | static_data_name="name", | ||
564 | static_data_template=name_link_template, | ||
549 | field_name="name") | 565 | field_name="name") |
550 | 566 | ||
551 | super(ImageRecipesTable, self).setup_columns(*args, **kwargs) | 567 | super(ImageRecipesTable, self).setup_columns(*args, **kwargs) |
@@ -609,8 +625,96 @@ class SoftwareRecipesTable(RecipesTable): | |||
609 | 625 | ||
610 | self.add_column(**RecipesTable.build_col) | 626 | self.add_column(**RecipesTable.build_col) |
611 | 627 | ||
628 | class PackagesTable(ToasterTable): | ||
629 | """ Table to display the packages in a recipe from it's last successful | ||
630 | build""" | ||
631 | |||
632 | def __init__(self, *args, **kwargs): | ||
633 | super(PackagesTable, self).__init__(*args, **kwargs) | ||
634 | self.title = "Packages included" | ||
635 | self.packages = None | ||
636 | self.default_orderby = "name" | ||
637 | |||
638 | def create_package_list(self, recipe, project_id): | ||
639 | """Creates a list of packages for the specified recipe by looking for | ||
640 | the last SUCCEEDED build of ther recipe""" | ||
641 | |||
642 | target = Target.objects.filter(Q(target=recipe.name) & | ||
643 | Q(build__project_id=project_id) & | ||
644 | Q(build__outcome=Build.SUCCEEDED) | ||
645 | ).last() | ||
646 | |||
647 | if target: | ||
648 | return target.build.package_set.all() | ||
649 | |||
650 | # Target/recipe never successfully built so empty queryset | ||
651 | return Package.objects.none() | ||
652 | |||
653 | def get_context_data(self, **kwargs): | ||
654 | """Context for rendering the sidebar and other items on the recipe | ||
655 | details page """ | ||
656 | context = super(PackagesTable, self).get_context_data(**kwargs) | ||
657 | |||
658 | recipe = Recipe.objects.get(pk=kwargs['recipe_id']) | ||
659 | project = Project.objects.get(pk=kwargs['pid']) | ||
660 | |||
661 | in_project = (recipe.layer_version.pk in | ||
662 | project.get_project_layer_versions(pk=True)) | ||
663 | |||
664 | packages = self.create_package_list(recipe, project.pk) | ||
665 | |||
666 | context.update({'project': project, | ||
667 | 'recipe' : recipe, | ||
668 | 'packages': packages, | ||
669 | 'approx_pkg_size' : packages.aggregate(Sum('size')), | ||
670 | 'in_project' : in_project, | ||
671 | }) | ||
672 | |||
673 | return context | ||
674 | |||
675 | def setup_queryset(self, *args, **kwargs): | ||
676 | recipe = Recipe.objects.get(pk=kwargs['recipe_id']) | ||
677 | |||
678 | self.queryset = self.create_package_list(recipe, kwargs['pid']) | ||
679 | self.queryset = self.queryset.order_by('name') | ||
680 | |||
681 | def setup_columns(self, *args, **kwargs): | ||
682 | self.add_column(title="Package", | ||
683 | hideable=False, | ||
684 | orderable=True, | ||
685 | field_name="name") | ||
686 | |||
687 | self.add_column(title="Package Version", | ||
688 | field_name="version", | ||
689 | hideable=False) | ||
690 | |||
691 | self.add_column(title="Approx Size", | ||
692 | orderable=True, | ||
693 | static_data_name="size", | ||
694 | static_data_template="{% load projecttags %} \ | ||
695 | {{data.size|filtered_filesizeformat}}") | ||
696 | |||
697 | self.add_column(title="License", | ||
698 | field_name="license", | ||
699 | orderable=True) | ||
700 | |||
701 | |||
702 | self.add_column(title="Dependencies", | ||
703 | static_data_name="dependencies", | ||
704 | static_data_template='\ | ||
705 | {% include "snippets/pkg_dependencies_popover.html" %}') | ||
706 | |||
707 | self.add_column(title="Recipe", | ||
708 | field_name="recipe__name", | ||
709 | orderable=True, | ||
710 | hidden=True) | ||
711 | |||
712 | self.add_column(title="Recipe version", | ||
713 | field_name="recipe__version", | ||
714 | hidden=True) | ||
715 | |||
612 | 716 | ||
613 | class SelectPackagesTable(ToasterTable): | 717 | class SelectPackagesTable(PackagesTable): |
614 | """ Table to display the packages to add and remove from an image """ | 718 | """ Table to display the packages to add and remove from an image """ |
615 | 719 | ||
616 | def __init__(self, *args, **kwargs): | 720 | def __init__(self, *args, **kwargs): |
@@ -637,29 +741,25 @@ class SelectPackagesTable(ToasterTable): | |||
637 | self.static_context_extra['current_packages'] = \ | 741 | self.static_context_extra['current_packages'] = \ |
638 | cust_recipe.packages.values_list('pk', flat=True) | 742 | cust_recipe.packages.values_list('pk', flat=True) |
639 | 743 | ||
640 | def setup_columns(self, *args, **kwargs): | 744 | def get_context_data(self, **kwargs): |
641 | self.add_column(title="Package", | 745 | context = super(SelectPackagesTable, self).get_context_data(**kwargs) |
642 | hideable=False, | 746 | custom_recipe = CustomImageRecipe.objects.get(pk=kwargs['recipe_id']) |
643 | orderable=True, | ||
644 | field_name="name") | ||
645 | 747 | ||
646 | self.add_column(title="Package Version", | 748 | context['recipe'] = custom_recipe |
647 | field_name="version") | 749 | context['approx_pkg_size'] = custom_recipe.package_set.aggregate(Sum('size')) |
750 | return context | ||
648 | 751 | ||
649 | self.add_column(title="Approx Size", | 752 | |
650 | orderable=True, | 753 | def setup_columns(self, *args, **kwargs): |
651 | static_data_name="size", | 754 | super(SelectPackagesTable, self).setup_columns(*args, **kwargs) |
652 | static_data_template="{% load projecttags %} \ | ||
653 | {{data.size|filtered_filesizeformat}}") | ||
654 | self.add_column(title="summary", | ||
655 | field_name="summary") | ||
656 | 755 | ||
657 | self.add_column(title="Add | Remove", | 756 | self.add_column(title="Add | Remove", |
757 | hideable=False, | ||
658 | help_text="Use the add and remove buttons to modify " | 758 | help_text="Use the add and remove buttons to modify " |
659 | "the package content of you custom image", | 759 | "the package content of you custom image", |
660 | static_data_name="add_rm_pkg_btn", | 760 | static_data_name="add_rm_pkg_btn", |
661 | static_data_template='{% include "pkg_add_rm_btn.html" %}', | 761 | static_data_template='{% include "pkg_add_rm_btn.html" %}', |
662 | static_data_template='{% include "pkg_add_rm_btn.html" %}' | 762 | filter_name="in_current_image" |
663 | ) | 763 | ) |
664 | 764 | ||
665 | def setup_filters(self, *args, **kwargs): | 765 | def setup_filters(self, *args, **kwargs): |
@@ -681,12 +781,11 @@ class SelectPackagesTable(ToasterTable): | |||
681 | self.filter_not_in_image) | 781 | self.filter_not_in_image) |
682 | ]) | 782 | ]) |
683 | 783 | ||
684 | def filter_in_image(self, count_only=False): | 784 | def filter_in_image(self): |
685 | return self.queryset.filter( | 785 | return self.queryset.filter( |
686 | pk__in=self.static_context_extra['current_packages']) | 786 | pk__in=self.static_context_extra['current_packages']) |
687 | 787 | ||
688 | 788 | def filter_not_in_image(self): | |
689 | def filter_not_in_image(self, count_only=False): | ||
690 | return self.queryset.exclude( | 789 | return self.queryset.exclude( |
691 | pk__in=self.static_context_extra['current_packages']) | 790 | pk__in=self.static_context_extra['current_packages']) |
692 | 791 | ||