diff options
Diffstat (limited to 'import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py')
-rw-r--r-- | import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py | 253 |
1 files changed, 144 insertions, 109 deletions
diff --git a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py index 2cc2f4eb7b..e2d23c1e81 100644 --- a/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py +++ b/import-layers/yocto-poky/bitbake/lib/toaster/toastergui/tables.py @@ -22,7 +22,7 @@ from toastergui.widgets import ToasterTable from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project from orm.models import CustomImageRecipe, Package, Target, Build, LogMessage, Task -from orm.models import CustomImagePackage +from orm.models import CustomImagePackage, Package_DependencyManager from django.db.models import Q, Max, Sum, Count, When, Case, Value, IntegerField from django.conf.urls import url from django.core.urlresolvers import reverse, resolve @@ -114,28 +114,37 @@ class LayersTable(ToasterTable): git_url_template = ''' <a href="{% url 'layerdetails' extra.pid data.id %}"> + {% if data.layer.local_source_dir %} + <code>{{data.layer.local_source_dir}}</code> + {% else %} <code>{{data.layer.vcs_url}}</code> </a> + {% endif %} {% if data.get_vcs_link_url %} <a target="_blank" href="{{ data.get_vcs_link_url }}"> - <i class="icon-share get-info"></i> + <span class="glyphicon glyphicon-new-window"></span> </a> {% endif %} ''' - self.add_column(title="Git repository URL", - help_text="The Git repository for the layer source code", + self.add_column(title="Layer source code location", + help_text="A Git repository or an absolute path to a directory", hidden=True, static_data_name="layer__vcs_url", static_data_template=git_url_template) git_dir_template = ''' + {% if data.layer.local_source_dir %} + <span class="text-muted">Not applicable</span> + <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.layer.name}} is not in a Git repository, so there is no subdirectory associated with it"> </span> + {% else %} <a href="{% url 'layerdetails' extra.pid data.id %}"> <code>{{data.dirpath}}</code> </a> + {% endif %} {% if data.dirpath and data.get_vcs_dirpath_link_url %} <a target="_blank" href="{{ data.get_vcs_dirpath_link_url }}"> - <i class="icon-share get-info"></i> + <span class="glyphicon glyphicon-new-window"></span> </a> {% endif %}''' @@ -146,16 +155,14 @@ class LayersTable(ToasterTable): static_data_template=git_dir_template) revision_template = ''' - {% load projecttags %} - {% with vcs_ref=data.get_vcs_reference %} - {% if vcs_ref|is_shaid %} - <a class="btn" data-content="<ul class='unstyled'> <li>{{vcs_ref}}</li> </ul>"> - {{vcs_ref|truncatechars:10}} - </a> + {% if data.layer.local_source_dir %} + <span class="text-muted">Not applicable</span> + <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.layer.name}} is not in a Git repository, so there is no revision associated with it"> </span> {% else %} - {{vcs_ref}} - {% endif %} + {% with vcs_ref=data.get_vcs_reference %} + {% include 'snippets/gitrev_popover.html' %} {% endwith %} + {% endif %} ''' self.add_column(title="Git revision", @@ -166,8 +173,8 @@ class LayersTable(ToasterTable): deps_template = ''' {% with ods=data.dependencies.all%} {% if ods.count %} - <a class="btn" title="<a href='{% url "layerdetails" extra.pid data.id %}'>{{data.layer.name}}</a> dependencies" - data-content="<ul class='unstyled'> + <a class="btn btn-default" title="<a href='{% url "layerdetails" extra.pid data.id %}'>{{data.layer.name}}</a> dependencies" + data-content="<ul class='list-unstyled'> {% for i in ods%} <li><a href='{% url "layerdetails" extra.pid i.depends_on.pk %}'>{{i.depends_on.layer.name}}</a></li> {% endfor %} @@ -190,24 +197,13 @@ class LayersTable(ToasterTable): static_data_name="add-del-layers", static_data_template='{% include "layer_btn.html" %}') - project = Project.objects.get(pk=kwargs['pid']) - self.add_column(title="LayerDetailsUrl", - displayable = False, - field_name="layerdetailurl", - computation = lambda x: reverse('layerdetails', args=(project.id, x.id))) - - self.add_column(title="name", - displayable = False, - field_name="name", - computation = lambda x: x.layer.name) - class MachinesTable(ToasterTable): """Table of Machines in Toaster""" def __init__(self, *args, **kwargs): super(MachinesTable, self).__init__(*args, **kwargs) - self.empty_state = "No machines maybe you need to do a build?" + self.empty_state = "Toaster has no machine information for this project. Sadly, machine information cannot be obtained from builds, so this page will remain empty." self.title = "Compatible machines" self.default_orderby = "name" @@ -275,7 +271,7 @@ class MachinesTable(ToasterTable): field_name="layer_version__get_vcs_reference") machine_file_template = '''<code>conf/machine/{{data.name}}.conf</code> - <a href="{{data.get_vcs_machine_file_link_url}}" target="_blank"><i class="icon-share get-info"></i></a>''' + <a href="{{data.get_vcs_machine_file_link_url}}" target="_blank"><span class="glyphicon glyphicon-new-window"></i></a>''' self.add_column(title="Machine file", hidden=True, @@ -318,7 +314,11 @@ class LayerMachinesTable(MachinesTable): self.add_column(title="Description", field_name="description") - select_btn_template = '<a href="{% url "project" extra.pid %}?setMachine={{data.name}}" class="btn btn-block select-machine-btn" {% if extra.in_prj == 0%}disabled="disabled"{%endif%}>Select machine</a>' + select_btn_template = ''' + <a href="{% url "project" extra.pid %}?setMachine={{data.name}}" + class="btn btn-default btn-block select-machine-btn + {% if extra.in_prj == 0%}disabled{%endif%}">Select machine</a> + ''' self.add_column(title="Select machine", static_data_name="add-del-layers", @@ -330,10 +330,10 @@ class RecipesTable(ToasterTable): def __init__(self, *args, **kwargs): super(RecipesTable, self).__init__(*args, **kwargs) - self.empty_state = "Toaster has no recipe information. To generate recipe information you can configure a layer source then run a build." + self.empty_state = "Toaster has no recipe information. To generate recipe information you need to run a build." build_col = { 'title' : "Build", - 'help_text' : "Add or delete recipes to and from your project", + 'help_text' : "Before building a recipe, you might need to add the corresponding layer to your project", 'hideable' : False, 'filter_name' : "in_current_project", 'static_data_name' : "add-del-layers", @@ -344,8 +344,7 @@ class RecipesTable(ToasterTable): context = super(RecipesTable, self).get_context_data(**kwargs) context['project'] = project - - context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project'])) + context['projectlayers'] = [player.layercommit.id for player in ProjectLayer.objects.filter(project=context['project'])] return context @@ -395,7 +394,7 @@ class RecipesTable(ToasterTable): recipe_file_template = ''' <code>{{data.file_path}}</code> <a href="{{data.get_vcs_recipe_file_link_url}}" target="_blank"> - <i class="icon-share get-info"></i> + <span class="glyphicon glyphicon-new-window"></i> </a> ''' @@ -428,9 +427,19 @@ class RecipesTable(ToasterTable): orderable=True, field_name="license") + revision_link_template = ''' + {% if data.layer_version.layer.local_source_dir %} + <span class="text-muted">Not applicable</span> + <span class="glyphicon glyphicon-question-sign get-help" data-original-title="" title="The source code of {{data.layer_version.layer.name}} is not in a Git repository, so there is no revision associated with it"> </span> + {% else %} + {{data.layer_version.get_vcs_reference}} + {% endif %} + ''' + self.add_column(title="Git revision", hidden=True, - field_name="layer_version__get_vcs_reference") + static_data_name="layer_version__get_vcs_reference", + static_data_template=revision_link_template) class LayerRecipesTable(RecipesTable): @@ -466,7 +475,11 @@ class LayerRecipesTable(RecipesTable): self.add_column(title="Description", field_name="get_description_or_summary") - build_recipe_template ='<button class="btn btn-block build-recipe-btn" data-recipe-name="{{data.name}}" {%if extra.in_prj == 0 %}disabled="disabled"{%endif%}>Build recipe</button>' + build_recipe_template = ''' + <a class="btn btn-default btn-block build-recipe-btn + {% if extra.in_prj == 0 %}disabled{% endif %}" + data-recipe-name="{{data.name}}">Build recipe</a> + ''' self.add_column(title="Build recipe", static_data_name="add-del-layers", @@ -481,7 +494,16 @@ class CustomImagesTable(ToasterTable): def get_context_data(self, **kwargs): context = super(CustomImagesTable, self).get_context_data(**kwargs) + + empty_state_template = ''' + You have not created any custom images yet. + <a href="{% url 'newcustomimage' data.pid %}"> + Create your first custom image</a> + ''' + context['empty_state'] = self.render_static_data(empty_state_template, + kwargs) project = Project.objects.get(pk=kwargs['pid']) + # TODO put project into the ToasterTable base class context['project'] = project return context @@ -507,29 +529,31 @@ class CustomImagesTable(ToasterTable): static_data_template=name_link_template) recipe_file_template = ''' + {% if data.get_base_recipe_file %} <code>{{data.name}}_{{data.version}}.bb</code> - <a href="{% url 'customrecipedownload' extra.pid data.pk %}"> - <i class="icon-download-alt" data-original-title="Download recipe - file"></i> - </a>''' + <a href="{% url 'customrecipedownload' extra.pid data.pk %}" + class="glyphicon glyphicon-download-alt get-help" title="Download recipe file"></a> + {% endif %}''' self.add_column(title="Recipe file", static_data_name='recipe_file_download', static_data_template=recipe_file_template) approx_packages_template = ''' + {% if data.get_all_packages.count > 0 %} <a href="{% url 'customrecipe' extra.pid data.id %}"> {{data.get_all_packages.count}} - </a>''' + </a> + {% endif %}''' - self.add_column(title="Approx packages", + self.add_column(title="Packages", static_data_name='approx_packages', static_data_template=approx_packages_template) build_btn_template = ''' <button data-recipe-name="{{data.name}}" - class="btn btn-block build-recipe-btn" style="margin-top: 5px;" > + class="btn btn-default btn-block build-recipe-btn"> Build </button>''' @@ -695,6 +719,7 @@ class PackagesTable(ToasterTable): def setup_queryset(self, *args, **kwargs): recipe = Recipe.objects.get(pk=kwargs['recipe_id']) + self.static_context_extra['target_name'] = recipe.name self.queryset = self.create_package_list(recipe, kwargs['pid']) self.queryset = self.queryset.order_by('name') @@ -711,13 +736,15 @@ class PackagesTable(ToasterTable): self.add_column(title="Approx Size", orderable=True, + field_name="size", static_data_name="size", static_data_template="{% load projecttags %} \ {{data.size|filtered_filesizeformat}}") self.add_column(title="License", field_name="license", - orderable=True) + orderable=True, + hidden=True) self.add_column(title="Dependencies", @@ -764,7 +791,19 @@ class SelectPackagesTable(PackagesTable): self.queryset = self.queryset.order_by('name') + # This target is the target used to work out which group of dependences + # to display, if we've built the custom image we use it otherwise we + # can use the based recipe instead + if prj.build_set.filter(target__target=self.cust_recipe.name).count()\ + > 0: + self.static_context_extra['target_name'] = self.cust_recipe.name + else: + self.static_context_extra['target_name'] =\ + Package_DependencyManager.TARGET_LATEST + self.static_context_extra['recipe_id'] = kwargs['custrecipeid'] + + self.static_context_extra['current_packages'] = \ current_packages.values_list('pk', flat=True) @@ -860,26 +899,22 @@ class ProjectsTable(ToasterTable): last_activity_on_template = ''' {% load project_url_tag %} <span data-project-field="updated"> - <a href="{% project_url data %}"> {{data.updated | date:"d/m/y H:i"}} - </a> </span> ''' release_template = ''' <span data-project-field="release"> {% if data.release %} - <a href="{% url 'project' data.id %}#project-details"> - {{data.release.name}} - </a> + {{data.release.name}} {% elif data.is_default %} - <span class="muted">Not applicable</span> - <i class="icon-question-sign get-help hover-help" - data-original-title="This project does not have a release set. + <span class="text-muted">Not applicable</span> + <span class="glyphicon glyphicon-question-sign get-help hover-help" + title="This project does not have a release set. It simply collects information about the builds you start from the command line while Toaster is running" style="visibility: hidden;"> - </i> + </span> {% else %} No release available {% endif %} @@ -889,16 +924,14 @@ class ProjectsTable(ToasterTable): machine_template = ''' <span data-project-field="machine"> {% if data.is_default %} - <span class="muted">Not applicable</span> - <i class="icon-question-sign get-help hover-help" - data-original-title="This project does not have a machine + <span class="text-muted">Not applicable</span> + <span class="glyphicon glyphicon-question-sign get-help hover-help" + title="This project does not have a machine set. It simply collects information about the builds you start from the command line while Toaster is running" - style="visibility: hidden;"></i> + style="visibility: hidden;"></span> {% else %} - <a href="{% url 'project' data.id %}#machine-distro"> - {{data.get_current_machine_name}} - </a> + {{data.get_current_machine_name}} {% endif %} </span> ''' @@ -908,20 +941,16 @@ class ProjectsTable(ToasterTable): <a href="{% url 'projectbuilds' data.id %}"> {{data.get_number_of_builds}} </a> - {% else %} - <span class="muted">0</span> {% endif %} ''' last_build_outcome_template = ''' {% if data.get_number_of_builds > 0 %} - <a href="{% url 'builddashboard' data.get_last_build_id %}"> - {% if data.get_last_outcome == extra.Build.SUCCEEDED %} - <i class="icon-ok-sign success"></i> - {% elif data.get_last_outcome == extra.Build.FAILED %} - <i class="icon-minus-sign error"></i> - {% endif %} - </a> + {% if data.get_last_outcome == extra.Build.SUCCEEDED %} + <span class="glyphicon glyphicon-ok-circle"></span> + {% elif data.get_last_outcome == extra.Build.FAILED %} + <span class="glyphicon glyphicon-minus-sign"></span> + {% endif %} {% endif %} ''' @@ -935,7 +964,7 @@ class ProjectsTable(ToasterTable): errors_template = ''' {% if data.get_number_of_builds > 0 and data.get_last_errors > 0 %} - <a class="errors.count error" + <a class="errors.count text-danger" href="{% url "builddashboard" data.get_last_build_id %}#errors"> {{data.get_last_errors}} error{{data.get_last_errors | pluralize}} </a> @@ -944,7 +973,7 @@ class ProjectsTable(ToasterTable): warnings_template = ''' {% if data.get_number_of_builds > 0 and data.get_last_warnings > 0 %} - <a class="warnings.count warning" + <a class="warnings.count text-warning" href="{% url "builddashboard" data.get_last_build_id %}#warnings"> {{data.get_last_warnings}} warning{{data.get_last_warnings | pluralize}} </a> @@ -953,9 +982,7 @@ class ProjectsTable(ToasterTable): image_files_template = ''' {% if data.get_number_of_builds > 0 and data.get_last_outcome == extra.Build.SUCCEEDED %} - <a href="{% url "builddashboard" data.get_last_build_id %}#images"> - {{data.get_last_build_extensions}} - </a> + {{data.get_last_build_extensions}} {% endif %} ''' @@ -991,7 +1018,7 @@ class ProjectsTable(ToasterTable): static_data_name='machine', static_data_template=machine_template) - self.add_column(title='Number of builds', + self.add_column(title='Builds', help_text='The number of builds which have been run \ for the project', hideable=False, @@ -1121,19 +1148,17 @@ class BuildsTable(ToasterTable): def setup_columns(self, *args, **kwargs): outcome_template = ''' - <a href="{% url "builddashboard" data.id %}"> - {% if data.outcome == data.SUCCEEDED %} - <i class="icon-ok-sign success"></i> - {% elif data.outcome == data.FAILED %} - <i class="icon-minus-sign error"></i> - {% endif %} - </a> + {% if data.outcome == data.SUCCEEDED %} + <span class="glyphicon glyphicon-ok-circle"></span> + {% elif data.outcome == data.FAILED %} + <span class="glyphicon glyphicon-minus-sign"></span> + {% endif %} {% if data.cooker_log_path %} <a href="{% url "build_artifact" data.id "cookerlog" data.id %}"> - <i class="icon-download-alt get-help" - data-original-title="Download build log"></i> + <span class="glyphicon glyphicon-download-alt get-help" + data-original-title="Download build log"></span> </a> {% endif %} ''' @@ -1148,45 +1173,39 @@ class BuildsTable(ToasterTable): ''' machine_template = ''' - <a href="{% url "builddashboard" data.id %}"> - {{data.machine}} - </a> + {{data.machine}} ''' started_on_template = ''' - <a href="{% url "builddashboard" data.id %}"> - {{data.started_on | date:"d/m/y H:i"}} - </a> + {{data.started_on | date:"d/m/y H:i"}} ''' completed_on_template = ''' - <a href="{% url "builddashboard" data.id %}"> - {{data.completed_on | date:"d/m/y H:i"}} - </a> + {{data.completed_on | date:"d/m/y H:i"}} ''' failed_tasks_template = ''' {% if data.failed_tasks.count == 1 %} - <a href="{% url "task" data.id data.failed_tasks.0.id %}"> - <span class="error"> - {{data.failed_tasks.0.recipe.name}}.{{data.failed_tasks.0.task_name}} + <a class="text-danger" href="{% url "task" data.id data.failed_tasks.0.id %}"> + <span> + {{data.failed_tasks.0.recipe.name}} {{data.failed_tasks.0.task_name}} </span> </a> <a href="{% url "build_artifact" data.id "tasklogfile" data.failed_tasks.0.id %}"> - <i class="icon-download-alt" - data-original-title="Download task log file"> - </i> + <span class="glyphicon glyphicon-download-alt get-help" + title="Download task log file"> + </span> </a> {% elif data.failed_tasks.count > 1 %} <a href="{% url "tasks" data.id %}?filter=outcome%3A{{extra.Task.OUTCOME_FAILED}}"> - <span class="error">{{data.failed_tasks.count}} tasks</span> + <span class="text-danger">{{data.failed_tasks.count}} tasks</span> </a> {% endif %} ''' errors_template = ''' {% if data.errors_no %} - <a class="errors.count error" href="{% url "builddashboard" data.id %}#errors"> + <a class="errors.count text-danger" href="{% url "builddashboard" data.id %}#errors"> {{data.errors_no}} error{{data.errors_no|pluralize}} </a> {% endif %} @@ -1194,7 +1213,7 @@ class BuildsTable(ToasterTable): warnings_template = ''' {% if data.warnings_no %} - <a class="warnings.count warning" href="{% url "builddashboard" data.id %}#warnings"> + <a class="warnings.count text-warning" href="{% url "builddashboard" data.id %}#warnings"> {{data.warnings_no}} warning{{data.warnings_no|pluralize}} </a> {% endif %} @@ -1202,16 +1221,18 @@ class BuildsTable(ToasterTable): time_template = ''' {% load projecttags %} - <a href="{% url "buildtime" data.id %}"> + {% if data.outcome == extra.Build.SUCCEEDED %} + <a href="{% url "buildtime" data.id %}"> + {{data.timespent_seconds | sectohms}} + </a> + {% else %} {{data.timespent_seconds | sectohms}} - </a> + {% endif %} ''' image_files_template = ''' {% if data.outcome == extra.Build.SUCCEEDED %} - <a href="{% url "builddashboard" data.id %}#images"> {{data.get_image_file_extensions}} - </a> {% endif %} ''' @@ -1429,10 +1450,10 @@ class AllBuildsTable(BuildsTable): {{data.project.name}} </a> {% if data.project.is_default %} - <i class="icon-question-sign get-help hover-help" title="" + <span class="glyphicon glyphicon-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> + running" style="visibility: hidden;"></span> {% endif %} ''' @@ -1482,7 +1503,6 @@ class ProjectBuildsTable(BuildsTable): """ 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) @@ -1496,8 +1516,23 @@ class ProjectBuildsTable(BuildsTable): self.project_id = kwargs['pid'] context = super(ProjectBuildsTable, self).get_context_data(**kwargs) + empty_state_template = ''' + This project has no builds. + <a href="{% url 'projectimagerecipes' data.pid %}"> + Choose a recipe to build</a> + ''' + context['empty_state'] = self.render_static_data(empty_state_template, + kwargs) + project = Project.objects.get(pk=self.project_id) context['mru'] = Build.get_recent(project) context['project'] = project + self.setup_queryset(**kwargs) + if self.queryset.count() == 0 and \ + project.build_set.filter(outcome=Build.IN_PROGRESS).count() > 0: + context['build_in_progress_none_completed'] = True + else: + context['build_in_progress_none_completed'] = False + return context |