summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Wood <michael.g.wood@intel.com>2015-09-28 21:45:23 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-09-29 14:11:37 +0100
commit37948cc5d0e9274a2ca0ec70a5b4788fa26e55e5 (patch)
tree76359d92d68c0e2fba1984b213b1dff3f976d6ce
parenta3ff4b28baa9f4cc76ec4993f862f2ed7bd20f65 (diff)
downloadpoky-37948cc5d0e9274a2ca0ec70a5b4788fa26e55e5.tar.gz
bitbake: toaster: Add ToasterTables for Image customisation feature
- Split up the recipes tables into Image recipes and Software Recipes - Add CustomImageRecipe table - Add SelectPackagesTable table - Add NewCustomImagesTable table (Bitbake rev: 4e5472e9ba6850081baa9d56fabc4ddb1aa24846) Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: brian avery <avery.brian@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/toaster/toastergui/tables.py222
1 files changed, 188 insertions, 34 deletions
diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py
index 70e4b6d782..1526d59004 100644
--- a/bitbake/lib/toaster/toastergui/tables.py
+++ b/bitbake/lib/toaster/toastergui/tables.py
@@ -21,6 +21,7 @@
21 21
22from toastergui.widgets import ToasterTable 22from toastergui.widgets import ToasterTable
23from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project 23from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project
24from orm.models import CustomImageRecipe, Package
24from django.db.models import Q, Max 25from django.db.models import Q, Max
25from django.conf.urls import url 26from django.conf.urls import url
26from django.core.urlresolvers import reverse 27from django.core.urlresolvers import reverse
@@ -310,13 +311,20 @@ class LayerMachinesTable(MachinesTable):
310 311
311 312
312class RecipesTable(ToasterTable, ProjectFiltersMixin): 313class RecipesTable(ToasterTable, ProjectFiltersMixin):
313 """Table of Recipes in Toaster""" 314 """Table of All Recipes in Toaster"""
314 315
315 def __init__(self, *args, **kwargs): 316 def __init__(self, *args, **kwargs):
316 super(RecipesTable, self).__init__(*args, **kwargs) 317 super(RecipesTable, self).__init__(*args, **kwargs)
317 self.empty_state = "Toaster has no recipe information. To generate recipe information you can configure a layer source then run a build." 318 self.empty_state = "Toaster has no recipe information. To generate recipe information you can configure a layer source then run a build."
318 self.default_orderby = "name" 319 self.default_orderby = "name"
319 320
321 build_col = { 'title' : "Build",
322 'help_text' : "Add or delete recipes to and from your project",
323 'hideable' : False,
324 'filter_name' : "in_current_project",
325 'static_data_name' : "add-del-layers",
326 'static_data_template' : '{% include "recipe_btn.html" %}'}
327
320 def get_context_data(self, **kwargs): 328 def get_context_data(self, **kwargs):
321 project = Project.objects.get(pk=kwargs['pid']) 329 project = Project.objects.get(pk=kwargs['pid'])
322 context = super(RecipesTable, self).get_context_data(**kwargs) 330 context = super(RecipesTable, self).get_context_data(**kwargs)
@@ -327,17 +335,6 @@ class RecipesTable(ToasterTable, ProjectFiltersMixin):
327 335
328 return context 336 return context
329 337
330 def setup_filters(self, *args, **kwargs):
331 project = Project.objects.get(pk=kwargs['pid'])
332 self.project_layers = project.projectlayer_equivalent_set()
333
334 self.add_filter(title="Filter by project recipes",
335 name="in_current_project",
336 filter_actions=[
337 self.make_filter_action("in_project", "Recipes provided by layers added to this project", self.filter_in_project),
338 self.make_filter_action("not_in_project", "Recipes provided by layers not added to this project", self.filter_not_in_project)
339 ])
340
341 338
342 def setup_queryset(self, *args, **kwargs): 339 def setup_queryset(self, *args, **kwargs):
343 prj = Project.objects.get(pk = kwargs['pid']) 340 prj = Project.objects.get(pk = kwargs['pid'])
@@ -348,12 +345,6 @@ class RecipesTable(ToasterTable, ProjectFiltersMixin):
348 345
349 def setup_columns(self, *args, **kwargs): 346 def setup_columns(self, *args, **kwargs):
350 347
351 self.add_column(title="Recipe",
352 help_text="Information about a single piece of software, including where to download the source, configuration options, how to compile the source files and how to package the compiled output",
353 hideable=False,
354 orderable=True,
355 field_name="name")
356
357 self.add_column(title="Recipe Version", 348 self.add_column(title="Recipe Version",
358 hidden=True, 349 hidden=True,
359 field_name="version") 350 field_name="version")
@@ -398,18 +389,6 @@ class RecipesTable(ToasterTable, ProjectFiltersMixin):
398 self.add_column(title="Revision", 389 self.add_column(title="Revision",
399 field_name="layer_version__get_vcs_reference") 390 field_name="layer_version__get_vcs_reference")
400 391
401 self.add_column(title="Build",
402 help_text="Add or delete recipes to and from your project",
403 hideable=False,
404 filter_name="in_current_project",
405 static_data_name="add-del-layers",
406 static_data_template='{% include "recipe_btn.html" %}')
407
408 project = Project.objects.get(pk=kwargs['pid'])
409 self.add_column(title="Project compatible Layer ID",
410 displayable = False,
411 field_name = "projectcompatible_layer",
412 computation = lambda x: (x.layer_version.get_equivalents_wpriority(project)[0]))
413 392
414class LayerRecipesTable(RecipesTable): 393class LayerRecipesTable(RecipesTable):
415 """ Smaller version of the Recipes table for use in layer details """ 394 """ Smaller version of the Recipes table for use in layer details """
@@ -446,10 +425,185 @@ class LayerRecipesTable(RecipesTable):
446 static_data_name="add-del-layers", 425 static_data_name="add-del-layers",
447 static_data_template=build_recipe_template) 426 static_data_template=build_recipe_template)
448 427
449class ProjectLayersRecipesTable(RecipesTable): 428class CustomImagesTable(ToasterTable):
450 """ Table that lists only recipes available for layers added to the project """ 429 """ Table to display your custom images """
430 def __init__(self, *args, **kwargs):
431 super(CustomImagesTable, self).__init__(*args, **kwargs)
432 self.title = "Custom images"
433
434 def get_context_data(self, **kwargs):
435 context = super(CustomImagesTable, self).get_context_data(**kwargs)
436 project = Project.objects.get(pk=kwargs['pid'])
437 context['project'] = project
438 context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project']))
439 return context
440
441 def setup_queryset(self, *args, **kwargs):
442 prj = Project.objects.get(pk = kwargs['pid'])
443 self.queryset = CustomImageRecipe.objects.filter(project=prj)
444 self.queryset = self.queryset.order_by('name')
445
446 def setup_columns(self, *args, **kwargs):
447
448 name_link_template = '''
449 <a href="{% url 'customrecipe' extra.pid data.id %}">
450 {{data.name}}
451 </a>
452 '''
453
454 self.add_column(title="Custom image",
455 hideable=False,
456 static_data_name="name",
457 static_data_template=name_link_template)
458
459 self.add_column(title="Recipe file",
460 static_data_name='recipe_file',
461 static_data_template='')
462
463 approx_packages_template = '<a href="#imagedetails">{{data.packages.all|length}}</a>'
464 self.add_column(title="Approx packages",
465 static_data_name='approx_packages',
466 static_data_template=approx_packages_template)
467
468
469 build_btn_template = '''<button data-recipe-name="{{data.name}}"
470 class="btn btn-block build-recipe-btn" style="margin-top: 5px;" >
471 Build</button>'''
472
473 self.add_column(title="Build",
474 hideable=False,
475 static_data_name='build_custom_img',
476 static_data_template=build_btn_template)
477
478class ImageRecipesTable(RecipesTable):
479 """ A subset of the recipes table which displayed just image recipes """
480
481 def __init__(self, *args, **kwargs):
482 super(ImageRecipesTable, self).__init__(*args, **kwargs)
483 self.title = "Compatible image recipes"
484
485 def setup_queryset(self, *args, **kwargs):
486 super(ImageRecipesTable, self).setup_queryset(*args, **kwargs)
487
488 self.queryset = self.queryset.filter(is_image=True)
489
490
491 def setup_columns(self, *args, **kwargs):
492 self.add_column(title="Image recipe",
493 help_text="When you build an image recipe, you get an "
494 "image: a root file system you can"
495 "deploy to a machine",
496 hideable=False,
497 orderable=True,
498 field_name="name")
499
500 super(ImageRecipesTable, self).setup_columns(*args, **kwargs)
501
502 self.add_column(**RecipesTable.build_col)
503
504
505class NewCustomImagesTable(ImageRecipesTable):
506 """ Table which displays Images recipes which can be customised """
507 def __init__(self, *args, **kwargs):
508 super(NewCustomImagesTable, self).__init__(*args, **kwargs)
509 self.title = "Select the image recipe you want to customise"
451 510
452 def setup_queryset(self, *args, **kwargs): 511 def setup_queryset(self, *args, **kwargs):
453 super(ProjectLayersRecipesTable, self).setup_queryset(*args, **kwargs) 512 super(ImageRecipesTable, self).setup_queryset(*args, **kwargs)
513
514 self.queryset = self.queryset.filter(is_image=True)
515
516 def setup_columns(self, *args, **kwargs):
517 self.add_column(title="Image recipe",
518 help_text="When you build an image recipe, you get an "
519 "image: a root file system you can"
520 "deploy to a machine",
521 hideable=False,
522 orderable=True,
523 field_name="recipe__name")
524
525 super(ImageRecipesTable, self).setup_columns(*args, **kwargs)
526
527 self.add_column(title="Customise",
528 hideable=False,
529 filter_name="in_current_project",
530 static_data_name="customise-or-add-recipe",
531 static_data_template='{% include "customise_btn.html" %}')
532
533
534class SoftwareRecipesTable(RecipesTable):
535 """ Displays just the software recipes """
536 def __init__(self, *args, **kwargs):
537 super(SoftwareRecipesTable, self).__init__(*args, **kwargs)
538 self.title = "Compatible software recipes"
539
540 def setup_queryset(self, *args, **kwargs):
541 super(SoftwareRecipesTable, self).setup_queryset(*args, **kwargs)
542
543 self.queryset = self.queryset.filter(is_image=False)
544
545
546 def setup_columns(self, *args, **kwargs):
547 self.add_column(title="Software recipe",
548 help_text="Information about a single piece of "
549 "software, including where to download the source, "
550 "configuration options, how to compile the source "
551 "files and how to package the compiled output",
552 hideable=False,
553 orderable=True,
554 field_name="name")
555
556 super(SoftwareRecipesTable, self).setup_columns(*args, **kwargs)
557
558 self.add_column(**RecipesTable.build_col)
559
560
561class SelectPackagesTable(ToasterTable):
562 """ Table to display the packages to add and remove from an image """
563
564 def __init__(self, *args, **kwargs):
565 super(SelectPackagesTable, self).__init__(*args, **kwargs)
566 self.title = "Add | Remove packages"
567
568 def setup_queryset(self, *args, **kwargs):
569 cust_recipe = CustomImageRecipe.objects.get(pk=kwargs['recipeid'])
454 prj = Project.objects.get(pk = kwargs['pid']) 570 prj = Project.objects.get(pk = kwargs['pid'])
455 self.queryset = self.queryset.filter(layer_version__in = prj.projectlayer_equivalent_set()) 571
572 current_packages = cust_recipe.packages.all()
573
574 # Get all the packages that are in the custom image
575 # Get all the packages built by builds in the current project
576 # but not those ones that are already in the custom image
577 self.queryset = Package.objects.filter(
578 Q(pk__in=current_packages) |
579 (Q(build__project=prj) &
580 ~Q(name__in=current_packages.values_list('name'))))
581
582 self.queryset = self.queryset.order_by('name')
583
584 self.static_context_extra['recipe_id'] = kwargs['recipeid']
585 self.static_context_extra['current_packages'] = \
586 cust_recipe.packages.values_list('pk', flat=True)
587
588 def setup_columns(self, *args, **kwargs):
589 self.add_column(title="Package",
590 hideable=False,
591 orderable=True,
592 field_name="name")
593
594 self.add_column(title="Package Version",
595 field_name="version")
596
597 self.add_column(title="Approx Size",
598 orderable=True,
599 static_data_name="size",
600 static_data_template="{% load projecttags %} \
601 {{data.size|filtered_filesizeformat}}")
602 self.add_column(title="summary",
603 field_name="summary")
604
605 self.add_column(title="Add | Remove",
606 help_text="Use the add and remove buttons to modify "
607 "the package content of you custom image",
608 static_data_name="add_rm_pkg_btn",
609 static_data_template='{% include "pkg_add_rm_btn.html" %}')