Apologies, the email below should have gone to the mailing list too, not just the person who submitted the patch.
On 09/05/2016 11:56, "Barros Pena, Belen" <[email protected]> wrote: > >>This is the table that displays all the packages built in the build. >>Build -> Packages > >This is mostly working. Just a couple of small issues: > >1. Something is not quite right with the default sorting. When you load >the table, the 'Package' column shows as the selected sorting criteria, >but the first package shown for my build is "qemuwrapper-cross-dev". >That's not quite right: the first package in that table given the sorting >criteria should be "base-files". Clicking on the heading sorts properly. > >2. In the dependencies and reverse dependencies popovers, the package name >in the popover title needs to be a link to the applicable information in >the package details page (dependencies or reverse dependencies). Each >package listed in the popover content should be a link to the >corresponding package details pages. You can see an example in the >'packages included' table. > > >3. We have a small issue with the 'Size' sorting: on the first click, >packages should be sorted in descending order (i.e. biggest package on >top). Just bringing it up for completeness: we have an issue in Bugzilla >for this (https://bugzilla.yoctoproject.org/show_bug.cgi?id=8859) so no >need to fix as part of this series. > >Thanks! > >Belén > >> >>Signed-off-by: Michael Wood <[email protected]> >>--- >> bitbake/lib/toaster/toastergui/buildtables.py | 77 >>+++++++++++++++++ >> bitbake/lib/toaster/toastergui/tables.py | 1 + >> .../lib/toaster/toastergui/templates/bpackage.html | 97 >>++++------------------ >> bitbake/lib/toaster/toastergui/urls.py | 7 +- >> bitbake/lib/toaster/toastergui/views.py | 90 >>-------------------- >> 5 files changed, 99 insertions(+), 173 deletions(-) >> create mode 100644 bitbake/lib/toaster/toastergui/buildtables.py >> >>diff --git a/bitbake/lib/toaster/toastergui/buildtables.py >>b/bitbake/lib/toaster/toastergui/buildtables.py >>new file mode 100644 >>index 0000000..365fd5c >>--- /dev/null >>+++ b/bitbake/lib/toaster/toastergui/buildtables.py >>@@ -0,0 +1,77 @@ >>+# >>+# ex:ts=4:sw=4:sts=4:et >>+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- >>+# >>+# BitBake Toaster Implementation >>+# >>+# Copyright (C) 2016 Intel Corporation >>+# >>+# This program is free software; you can redistribute it and/or modify >>+# it under the terms of the GNU General Public License version 2 as >>+# published by the Free Software Foundation. >>+# >>+# This program is distributed in the hope that it will be useful, >>+# but WITHOUT ANY WARRANTY; without even the implied warranty of >>+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >>+# GNU General Public License for more details. >>+# >>+# You should have received a copy of the GNU General Public License >>along >>+# with this program; if not, write to the Free Software Foundation, >>Inc., >>+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >>+ >>+from orm.models import Build >>+import toastergui.tables as tables >>+ >>+class BuiltPackagesTable(tables.PackagesTable): >>+ def __init__(self, *args, **kwargs): >>+ super(BuiltPackagesTable, self).__init__(*args, **kwargs) >>+ self.title = "Packages built" >>+ >>+ def setup_queryset(self, *args, **kwargs): >>+ build = Build.objects.get(pk=kwargs['build_id']) >>+ self.static_context_extra['build'] = build >>+ self.queryset = build.package_set.all().exclude(recipe=None) >>+ >>+ def get_context_data(self, **kwargs): >>+ # Chain up to ToasterTable as we don't need anything from >>+ # PackagesTable >>+ context = super(tables.PackagesTable, >>self).get_context_data(**kwargs) >>+ context['build'] = Build.objects.get(pk=kwargs['build_id']) >>+ return context >>+ >>+ def setup_columns(self, *args, **kwargs): >>+ super(BuiltPackagesTable, self).setup_columns(**kwargs) >>+ >>+ add_pkg_link_to = ['name', 'version', 'size', 'license'] >>+ add_recipe_link_to = ['recipe__name', 'recipe__version'] >>+ >>+ def get_link_value(column): >>+ >>+ column['static_data_name'] = column['field_name'] >>+ >>+ if column['static_data_template']: >>+ # Make sure any existing template is used >>+ return column['static_data_template'] >>+ else: >>+ # convert to the template style of variable >>+ return ('{{data.%s}}' % >>+ column['field_name'].replace('__', '.')) >>+ >>+ for column in self.columns: >>+ if column['field_name'] in add_pkg_link_to: >>+ column['static_data_template'] = ''' >>+ <a href=" >>+ {%% url "package_built_detail" extra.build.pk data.pk >>%%} >>+ ">%s</a> >>+ ''' % get_link_value(column) >>+ >>+ elif column['field_name'] in add_recipe_link_to: >>+ column['static_data_template'] = (''' >>+ {%% if data.recipe %%} >>+ <a href=" >>+ {%% url "recipe" extra.build.pk data.recipe.pk %%} >>+ ">%(value)s</a> >>+ {%% else %%} >>+ %(value)s >>+ {%% endif %%} >>+ ''') % {'value': get_link_value(column)} >>diff --git a/bitbake/lib/toaster/toastergui/tables.py >>b/bitbake/lib/toaster/toastergui/tables.py >>index 29b68de..94d757b 100644 >>--- a/bitbake/lib/toaster/toastergui/tables.py >>+++ b/bitbake/lib/toaster/toastergui/tables.py >>@@ -699,6 +699,7 @@ 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}}") >>diff --git a/bitbake/lib/toaster/toastergui/templates/bpackage.html >>b/bitbake/lib/toaster/toastergui/templates/bpackage.html >>index 81973cb..a27586e 100644 >>--- a/bitbake/lib/toaster/toastergui/templates/bpackage.html >>+++ b/bitbake/lib/toaster/toastergui/templates/bpackage.html >>@@ -14,95 +14,28 @@ >> {% block buildinfomain %} >> <div class="span10"> >> >>-{% if not request.GET.filter and not request.GET.search and not >>objects.paginator.count %} >>- >>-<!-- Empty - no data in database --> >>-<div class="page-header"> >>+ {% if build.package_set.count == 0 %} >>+ <!-- Empty - no data in database --> >>+ <div class="page-header"> >> <h1> >>- Packages >>+ Packages >> </h1> >>-</div> >>-<div class="alert alert-info lead"> >>+ </div> >>+ <div class="alert alert-info lead"> >> <strong>No packages were built.</strong> How did this happen? Well, >>BitBake reuses as much stuff as possible. >> If all of the packages needed were already built and available in >>your build infrastructure, BitBake >> will not rebuild any of them. This might be slightly confusing, but >>it does make everything faster. >>-</div> >>- >>-{% else %} >>- >>-<div class="page-header"> >>- <h1> >>- {% if request.GET.search and objects.paginator.count > 0 %} >>- {{objects.paginator.count}} >>package{{objects.paginator.count|pluralize}} found >>- {%elif request.GET.search and objects.paginator.count == 0%} >>- No packages found >>- {%else%} >>- Packages >>- {%endif%} >>- </h1> >>-</div> >>- >>- {% if objects.paginator.count == 0 %} >>- <div class="row-fluid"> >>- <div class="alert"> >>- <form class="no-results input-append" id="searchform"> >>- <input id="search" name="search" class="input-xxlarge" >>type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a >>href="javascript:$('#search').val('');searchform.submit()" class="add-on >>btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} >>- <button class="btn" type="submit" >>value="Search">Search</button> >>- <button class="btn btn-link" >>onclick="javascript:$('#search').val('');searchform.submit()">Show all >>packages</button> >>- </form> >>- </div> >> </div> >> >> {% else %} >>- {% include "basetable_top.html" %} >>- >>- {% for package in objects %} >> >>- <tr class="data"> >>- >>- <!-- Package --> >>- <td class="package_name"><a href="{% url "package_built_detail" >>build.pk package.pk %}">{{package.name}}</a></td> >>- <!-- Package Version --> >>- <td class="package_version">{%if package.version%}<a href="{% >>url "package_built_detail" build.pk package.pk >>%}">{{package.version}}-{{package.revision}}</a>{%endif%}</td> >>- <!-- Package Size --> >>- <td class="size >>sizecol">{{package.size|filtered_filesizeformat}}</td> >>- <!-- License --> >>- <td class="license">{{package.license}}</td> >>- >>- {%if package.recipe%} >>- <!-- Recipe --> >>- <td class="recipe__name"><a href="{% url "recipe" build.pk >>package.recipe.pk %}">{{package.recipe.name}}</a></td> >>- <!-- Recipe Version --> >>- <td class="recipe__version"><a href="{% url "recipe" >>build.pk package.recipe.pk %}">{{package.recipe.version}}</a></td> >>- >>- <!-- Layer --> >>- <td >>class="recipe__layer_version__layer__name">{{package.recipe.layer_version >>. >>layer.name}}</td> >>- <!-- Layer branch --> >>- <td >>class="recipe__layer_version__branch">{{package.recipe.layer_version.bran >>c >>h}}</td> >>- <!-- Layer commit --> >>- <td class="recipe__layer_version__layer__commit"> >>- <a class="btn" >>- data-content="<ul class='unstyled'> >>- <li>{{package.recipe.layer_version.commit}}</li> >>- </ul>"> >>- >>{{package.recipe.layer_version.commit|truncatechars:13}} >>- </a> >>- </td> >>- <!-- Layer directory --> >>- {%else%} >>- <td class="recipe__name"></td> >>- <td class="recipe__version"></td> >>- <td class="recipe__layer_version__layer__name"></td> >>- <td class="recipe__layer_version__branch"></td> >>- <td class="recipe__layer_version__layer__commit"></td> >>- <td class="recipe__layer_version__local_path"></td> >>- {%endif%} >>- >>- </tr> >>- {% endfor %} >>- >>- {% include "basetable_bottom.html" %} >>- {% endif %} {# objects.paginator.count #} >>-{% endif %} {# Empty #} >>-</div> >>+ {% url 'builtpackagestable' build.id as xhr_table_url %} >>+ <div class="page-header"> >>+ <h1> >>+ {{title}} (<span class="table-count-{{table_name}}">0</span>) >></h2> >>+ </h1> >>+ </div> >>+ {% include "toastertable.html" %} >>+ {% endif %} {# end if packages #} >>+ </div> >> {% endblock %} >>diff --git a/bitbake/lib/toaster/toastergui/urls.py >>b/bitbake/lib/toaster/toastergui/urls.py >>index 27b0baa..b4c7e0e 100644 >>--- a/bitbake/lib/toaster/toastergui/urls.py >>+++ b/bitbake/lib/toaster/toastergui/urls.py >>@@ -21,6 +21,7 @@ from django.views.generic import RedirectView, >>TemplateView >> >> from django.http import HttpResponseBadRequest >> from toastergui import tables >>+from toastergui import buildtables >> from toastergui import typeaheads >> from toastergui import api >> >>@@ -44,7 +45,11 @@ urlpatterns = patterns('toastergui.views', >> url(r'^build/(?P<build_id>\d+)/recipe/(?P<recipe_id>\d+)$', >>'recipe', name='recipe'), >> >>url(r'^build/(?P<build_id>\d+)/recipe_packages/(?P<recipe_id>\d+)$', >>'recipe_packages', name='recipe_packages'), >> >>- url(r'^build/(?P<build_id>\d+)/packages/$', 'bpackage', >>name='packages'), >>+ url(r'^build/(?P<build_id>\d+)/packages/$', >>+ buildtables.BuiltPackagesTable.as_view( >>+ template_name="bpackage.html"), >>+ name='packages'), >>+ >> url(r'^build/(?P<build_id>\d+)/package/(?P<package_id>\d+)$', >>'package_built_detail', >> name='package_built_detail'), >> >>url(r'^build/(?P<build_id>\d+)/package_built_dependencies/(?P<package_id> >>\ >>d+)$', >>diff --git a/bitbake/lib/toaster/toastergui/views.py >>b/bitbake/lib/toaster/toastergui/views.py >>index bd5bf63..6e34008 100755 >>--- a/bitbake/lib/toaster/toastergui/views.py >>+++ b/bitbake/lib/toaster/toastergui/views.py >>@@ -1474,96 +1474,6 @@ def configvars(request, build_id): >> _set_parameters_values(pagesize, orderby, request) >> return response >> >>-def bpackage(request, build_id): >>- template = 'bpackage.html' >>- (pagesize, orderby) = _get_parameters_values(request, 100, 'name:+') >>- mandatory_parameters = { 'count' : pagesize, 'page' : 1, 'orderby' >>: orderby } >>- retval = _verify_parameters( request.GET, mandatory_parameters ) >>- if retval: >>- return _redirect_parameters( 'packages', request.GET, >>mandatory_parameters, build_id = build_id) >>- (filter_string, search_term, ordering_string) = >>_search_tuple(request, Package) >>- queryset = Package.objects.filter(build = >>build_id).filter(size__gte=0) >>- queryset = _get_queryset(Package, queryset, filter_string, >>search_term, ordering_string, 'name') >>- >>- packages = _build_page_range(Paginator(queryset, >>pagesize),request.GET.get('page', 1)) >>- >>- build = Build.objects.get( pk = build_id ) >>- >>- context = { >>- 'objectname': 'packages built', >>- 'build': build, >>- 'project': build.project, >>- 'objects' : packages, >>- 'default_orderby' : 'name:+', >>- 'tablecols':[ >>- { >>- 'name':'Package', >>- 'qhelp':'Packaged output resulting from building a >>recipe', >>- 'orderfield': _get_toggle_order(request, "name"), >>- 'ordericon':_get_toggle_order_icon(request, "name"), >>- }, >>- { >>- 'name':'Package version', >>- 'qhelp':'The package version and revision', >>- }, >>- { >>- 'name':'Size', >>- 'qhelp':'The size of the package', >>- 'orderfield': _get_toggle_order(request, "size", True), >>- 'ordericon':_get_toggle_order_icon(request, "size"), >>- 'orderkey' : 'size', >>- 'clclass': 'size', 'hidden': 0, >>- 'dclass' : 'span2', >>- }, >>- { >>- 'name':'License', >>- 'qhelp':'The license under which the package is >>distributed. Multiple license names separated by the pipe character >>indicates a choice between licenses. Multiple license names separated by >>the ampersand character indicates multiple licenses exist that cover >>different parts of the source', >>- 'orderfield': _get_toggle_order(request, "license"), >>- 'ordericon':_get_toggle_order_icon(request, "license"), >>- 'orderkey' : 'license', >>- 'clclass': 'license', 'hidden': 1, >>- }, >>- { >>- 'name':'Recipe', >>- 'qhelp':'The name of the recipe building the package', >>- 'orderfield': _get_toggle_order(request, >>"recipe__name"), >>- 'ordericon':_get_toggle_order_icon(request, >>"recipe__name"), >>- 'orderkey' : 'recipe__name', >>- 'clclass': 'recipe__name', 'hidden': 0, >>- }, >>- { >>- 'name':'Recipe version', >>- 'qhelp':'Version and revision of the recipe building the >>package', >>- 'clclass': 'recipe__version', 'hidden': 1, >>- }, >>- { >>- 'name':'Layer', >>- 'qhelp':'The name of the layer providing the recipe that >>builds the package', >>- 'orderfield': _get_toggle_order(request, >>"recipe__layer_version__layer__name"), >>- 'ordericon':_get_toggle_order_icon(request, >>"recipe__layer_version__layer__name"), >>- 'orderkey' : 'recipe__layer_version__layer__name', >>- 'clclass': 'recipe__layer_version__layer__name', >>'hidden': 1, >>- }, >>- { >>- 'name':'Layer branch', >>- 'qhelp':'The Git branch of the layer providing the >>recipe that builds the package', >>- 'orderfield': _get_toggle_order(request, >>"recipe__layer_version__branch"), >>- 'ordericon':_get_toggle_order_icon(request, >>"recipe__layer_version__branch"), >>- 'orderkey' : 'recipe__layer_version__branch', >>- 'clclass': 'recipe__layer_version__branch', 'hidden': 1, >>- }, >>- { >>- 'name':'Layer commit', >>- 'qhelp':'The Git commit of the layer providing the >>recipe that builds the package', >>- 'clclass': 'recipe__layer_version__layer__commit', >>'hidden': 1, >>- }, >>- ] >>- } >>- >>- response = render(request, template, context) >>- _set_parameters_values(pagesize, orderby, request) >>- return response >>- >> def bfile(request, build_id, package_id): >> template = 'bfile.html' >> files = Package_File.objects.filter(package = package_id) >>-- >>2.7.4 >> >>-- >>_______________________________________________ >>toaster mailing list >>[email protected] >>https://lists.yoctoproject.org/listinfo/toaster > -- _______________________________________________ toaster mailing list [email protected] https://lists.yoctoproject.org/listinfo/toaster
