All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/3] toaster: toastertables: Clean up and fix up a number of items
@ 2016-05-13 10:56 Michael Wood
  2016-05-13 10:56 ` [PATCH v2 2/3] toaster: toastergui tests Fix toastertable tests Michael Wood
  2016-05-13 10:56 ` [PATCH v2 3/3] toaster: toastertables port table for Built packages Michael Wood
  0 siblings, 2 replies; 4+ messages in thread
From: Michael Wood @ 2016-05-13 10:56 UTC (permalink / raw)
  To: toaster

 - Remove the unused 'computation' field
 - Remove the code to try to make the tables behave like an api
 - Remove custom JSON encoder in favour of DjangoJSONEncoder
 - Simplify get_data and add comments
 - Add exception type instead of using generic Exception
 - Clean up python style warnings

Signed-off-by: Michael Wood <michael.g.wood@intel.com>
---
 bitbake/lib/toaster/toastergui/static/js/table.js |  21 +---
 bitbake/lib/toaster/toastergui/tables.py          |  11 --
 bitbake/lib/toaster/toastergui/widgets.py         | 127 ++++++++++++----------
 3 files changed, 72 insertions(+), 87 deletions(-)

diff --git a/bitbake/lib/toaster/toastergui/static/js/table.js b/bitbake/lib/toaster/toastergui/static/js/table.js
index f738144..7f76f55 100644
--- a/bitbake/lib/toaster/toastergui/static/js/table.js
+++ b/bitbake/lib/toaster/toastergui/static/js/table.js
@@ -101,27 +101,8 @@ function tableInit(ctx){
       var row = $("<tr></tr>");
       column_index = -1;
       for (var key_j in tableData.rows[i]){
-
-        /* if we have a static: version of a key, prefer the static: version for rendering */
-        var orig_key_j = key_j;
-
-        if (key_j.indexOf("static:") === 0) {
-          if (key_j.substr("static:".length) in tableData.rows[i]) {
-            continue;
-          }
-          orig_key_j = key_j.substr("static:".length)
-        } else if (("static:" + key_j) in tableData.rows[i]) {
-          key_j = "static:" + key_j;
-        }
-
-        /* we skip over un-displayable column entries */
-        column_index += 1;
-        if (! tableData.columns[column_index].displayable) {
-          continue;
-        }
-
         var td = $("<td></td>");
-        td.prop("class", orig_key_j);
+        td.prop("class", key_j);
         if (tableData.rows[i][key_j]){
           td.html(tableData.rows[i][key_j]);
         }
diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py
index eb876ec..29b68de 100644
--- a/bitbake/lib/toaster/toastergui/tables.py
+++ b/bitbake/lib/toaster/toastergui/tables.py
@@ -190,17 +190,6 @@ 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"""
diff --git a/bitbake/lib/toaster/toastergui/widgets.py b/bitbake/lib/toaster/toastergui/widgets.py
index d2ef5d3..4117031 100644
--- a/bitbake/lib/toaster/toastergui/widgets.py
+++ b/bitbake/lib/toaster/toastergui/widgets.py
@@ -43,9 +43,12 @@ import urllib
 import logging
 logger = logging.getLogger("toaster")
 
-from toastergui.views import objtojson
 from toastergui.tablefilter import TableFilterMap
 
+
+class NoFieldOrDataNme(Exception):
+    pass
+
 class ToasterTable(TemplateView):
     def __init__(self, *args, **kwargs):
         super(ToasterTable, self).__init__()
@@ -63,25 +66,19 @@ class ToasterTable(TemplateView):
         self.empty_state = "Sorry - no data found"
         self.default_orderby = ""
 
-        # add the "id" column, undisplayable, by default
-        self.add_column(title="Id",
-                        displayable=False,
-                        orderable=True,
-                        field_name="id")
-
     # prevent HTTP caching of table data
-    @cache_control(must_revalidate=True, max_age=0, no_store=True, no_cache=True)
+    @cache_control(must_revalidate=True,
+                   max_age=0, no_store=True, no_cache=True)
     def dispatch(self, *args, **kwargs):
         return super(ToasterTable, self).dispatch(*args, **kwargs)
 
     def get_context_data(self, **kwargs):
         context = super(ToasterTable, self).get_context_data(**kwargs)
         context['title'] = self.title
-        context['table_name'] =  type(self).__name__.lower()
+        context['table_name'] = type(self).__name__.lower()
 
         return context
 
-
     def get(self, request, *args, **kwargs):
         if request.GET.get('format', None) == 'json':
 
@@ -102,8 +99,6 @@ class ToasterTable(TemplateView):
         return super(ToasterTable, self).get(request, *args, **kwargs)
 
     def get_filter_info(self, request, **kwargs):
-        data = None
-
         self.setup_filters(**kwargs)
 
         search = request.GET.get("search", None)
@@ -117,13 +112,18 @@ class ToasterTable(TemplateView):
                           cls=DjangoJSONEncoder)
 
     def setup_columns(self, *args, **kwargs):
-        """ function to implement in the subclass which sets up the columns """
+        """ function to implement in the subclass which sets up
+        the columns """
         pass
+
     def setup_filters(self, *args, **kwargs):
-        """ function to implement in the subclass which sets up the filters """
+        """ function to implement in the subclass which sets up the
+        filters """
         pass
+
     def setup_queryset(self, *args, **kwargs):
-        """ function to implement in the subclass which sets up the queryset"""
+        """ function to implement in the subclass which sets up the
+        queryset"""
         pass
 
     def add_filter(self, table_filter):
@@ -137,7 +137,6 @@ class ToasterTable(TemplateView):
     def add_column(self, title="", help_text="",
                    orderable=False, hideable=True, hidden=False,
                    field_name="", filter_name=None, static_data_name=None,
-                   displayable=True, computation=None,
                    static_data_template=None):
         """Add a column to the table.
 
@@ -155,18 +154,15 @@ class ToasterTable(TemplateView):
                 as data
         """
 
-        self.columns.append({'title' : title,
-                             'help_text' : help_text,
-                             'orderable' : orderable,
-                             'hideable' : hideable,
-                             'hidden' : hidden,
-                             'field_name' : field_name,
-                             'filter_name' : filter_name,
+        self.columns.append({'title': title,
+                             'help_text': help_text,
+                             'orderable': orderable,
+                             'hideable': hideable,
+                             'hidden': hidden,
+                             'field_name': field_name,
+                             'filter_name': filter_name,
                              'static_data_name': static_data_name,
-                             'static_data_template': static_data_template,
-                             'displayable': displayable,
-                             'computation': computation,
-                            })
+                             'static_data_template': static_data_template})
 
     def set_column_hidden(self, title, hidden):
         """
@@ -190,8 +186,8 @@ class ToasterTable(TemplateView):
         """Utility function to render the static data template"""
 
         context = {
-          'extra' : self.static_context_extra,
-          'data' : row,
+          'extra': self.static_context_extra,
+          'data': row,
         }
 
         context = Context(context)
@@ -241,7 +237,7 @@ class ToasterTable(TemplateView):
 
         if not hasattr(self.queryset.model, 'search_allowed_fields'):
             raise Exception("Search fields aren't defined in the model %s"
-                           % self.queryset.model)
+                            % self.queryset.model)
 
         search_queries = []
         for st in search_term.split(" "):
@@ -254,7 +250,6 @@ class ToasterTable(TemplateView):
 
         self.queryset = self.queryset.filter(search_queries)
 
-
     def get_data(self, request, **kwargs):
         """
         Returns the data for the page requested with the specified
@@ -262,7 +257,8 @@ class ToasterTable(TemplateView):
 
         filters: filter and action name, e.g. "outcome:build_succeeded"
         filter_value: value to pass to the named filter+action, e.g. "on"
-        (for a toggle filter) or "2015-12-11,2015-12-12" (for a date range filter)
+        (for a toggle filter) or "2015-12-11,2015-12-12"
+        (for a date range filter)
         """
 
         page_num = request.GET.get("page", 1)
@@ -313,16 +309,16 @@ class ToasterTable(TemplateView):
             page = paginator.page(1)
 
         data = {
-            'total' : self.queryset.count(),
-            'default_orderby' : self.default_orderby,
-            'columns' : self.columns,
-            'rows' : [],
-            'error' : "ok",
+            'total': self.queryset.count(),
+            'default_orderby': self.default_orderby,
+            'columns': self.columns,
+            'rows': [],
+            'error': "ok",
         }
 
         try:
-            for row in page.object_list:
-                #Use collection to maintain the order
+            for model_obj in page.object_list:
+                # Use collection to maintain the order
                 required_data = collections.OrderedDict()
 
                 for col in self.columns:
@@ -330,38 +326,57 @@ class ToasterTable(TemplateView):
                     if not field:
                         field = col['static_data_name']
                     if not field:
-                        raise Exception("Must supply a field_name or static_data_name for column %s.%s" % (self.__class__.__name__,col))
+                        raise NoFieldOrDataNme("Must supply a field_name or"
+                                               "static_data_name for column"
+                                               "%s.%s" %
+                                               (self.__class__.__name__, col))
+
                     # Check if we need to process some static data
                     if "static_data_name" in col and col['static_data_name']:
-                        required_data["static:%s" % col['static_data_name']] = self.render_static_data(col['static_data_template'], row)
-
                         # Overwrite the field_name with static_data_name
                         # so that this can be used as the html class name
-
                         col['field_name'] = col['static_data_name']
 
-                    # compute the computation on the raw data if needed
-                    model_data = row
-                    if col['computation']:
-                        model_data = col['computation'](row)
+                        # Render the template given
+                        required_data[col['static_data_name']] = \
+                            self.render_static_data(
+                                col['static_data_template'], model_obj)
                     else:
-                        # Traverse to any foriegn key in the object hierachy
-                        for subfield in field.split("__"):
-                            if hasattr(model_data, subfield):
-                                model_data = getattr(model_data, subfield)
-                        # The field could be a function on the model so check
-                        # If it is then call it
+                        # Traverse to any foriegn key in the field
+                        # e.g. recipe__layer_version__name
+                        model_data = None
+
+                        if "__" in field:
+                            for subfield in field.split("__"):
+                                if not model_data:
+                                    # The first iteration is always going to
+                                    # be on the actual model object instance.
+                                    # Subsequent ones are on the result of
+                                    # that. e.g. forieng key objects
+                                    model_data = getattr(model_obj,
+                                                         subfield)
+                                else:
+                                    model_data = getattr(model_data,
+                                                         subfield)
+
+                        else:
+                            model_data = getattr(model_obj,
+                                                 col['field_name'])
+
+                        # We might have a model function as the field so
+                        # call it to return the data needed
                         if isinstance(model_data, types.MethodType):
-                          model_data = model_data()
+                            model_data = model_data()
 
-                    required_data[col['field_name']] = model_data
+                        required_data[col['field_name']] = model_data
 
                 data['rows'].append(required_data)
 
         except FieldError:
             # pass  it to the user - programming-error here
             raise
-        data = json.dumps(data, indent=2, default=objtojson)
+
+        data = json.dumps(data, indent=2, cls=DjangoJSONEncoder)
         cache.set(cache_name, data, 60*30)
 
         return data
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/3] toaster: toastergui tests Fix toastertable tests
  2016-05-13 10:56 [PATCH v2 1/3] toaster: toastertables: Clean up and fix up a number of items Michael Wood
@ 2016-05-13 10:56 ` Michael Wood
  2016-05-13 10:56 ` [PATCH v2 3/3] toaster: toastertables port table for Built packages Michael Wood
  1 sibling, 0 replies; 4+ messages in thread
From: Michael Wood @ 2016-05-13 10:56 UTC (permalink / raw)
  To: toaster

After clean ups remove api assumptions. Our table data often contains
html snippets to display certain things such as dependency pop overs or
simply links to other parts of the UI. Take these into account when
testing the values of the table data.

Signed-off-by: Michael Wood <michael.g.wood@intel.com>
---
 bitbake/lib/toaster/toastergui/tests.py | 98 ++++++++++++++++++++++-----------
 1 file changed, 66 insertions(+), 32 deletions(-)

diff --git a/bitbake/lib/toaster/toastergui/tests.py b/bitbake/lib/toaster/toastergui/tests.py
index a4cab58..869c39d 100644
--- a/bitbake/lib/toaster/toastergui/tests.py
+++ b/bitbake/lib/toaster/toastergui/tests.py
@@ -83,8 +83,12 @@ class ViewTests(TestCase):
         self.assertEqual(data["error"], "ok")
         self.assertTrue("rows" in data)
 
-        self.assertTrue(self.project.name in [x["name"] for x in data["rows"]])
-        self.assertTrue("id" in data["rows"][0])
+        name_found = False
+        for row in data["rows"]:
+            name_found = row['name'].find(self.project.name)
+
+        self.assertTrue(name_found,
+                        "project name not found in projects table")
 
     def test_typeaheads(self):
         """Test typeahead ReST API"""
@@ -322,22 +326,24 @@ class ViewTests(TestCase):
         self.assertEqual(response.status_code, 200, 'should be 200 OK status')
 
         # check other columns have been populated correctly
-        self.assertEqual(row1['name'], self.recipe1.name)
-        self.assertEqual(row1['version'], self.recipe1.version)
-        self.assertEqual(row1['get_description_or_summary'],
-                         self.recipe1.description)
-        self.assertEqual(row1['layer_version__layer__name'],
-                         self.recipe1.layer_version.layer.name)
-        self.assertEqual(row2['name'], self.recipe2.name)
-        self.assertEqual(row2['version'], self.recipe2.version)
-        self.assertEqual(row2['get_description_or_summary'],
-                         self.recipe2.description)
-        self.assertEqual(row2['layer_version__layer__name'],
-                         self.recipe2.layer_version.layer.name)
+        self.assertTrue(self.recipe1.name in row1['name'])
+        self.assertTrue(self.recipe1.version in row1['version'])
+        self.assertTrue(self.recipe1.description in
+                        row1['get_description_or_summary'])
+
+        self.assertTrue(self.recipe1.layer_version.layer.name in
+                        row1['layer_version__layer__name'])
+
+        self.assertTrue(self.recipe2.name in row2['name'])
+        self.assertTrue(self.recipe2.version in row2['version'])
+        self.assertTrue(self.recipe2.description in
+                        row2['get_description_or_summary'])
+
+        self.assertTrue(self.recipe2.layer_version.layer.name in
+                        row2['layer_version__layer__name'])
 
     def test_toaster_tables(self):
         """Test all ToasterTables instances"""
-        current_recipes = self.project.get_available_recipes()
 
         def get_data(table, options={}):
             """Send a request and parse the json response"""
@@ -354,12 +360,30 @@ class ViewTests(TestCase):
                     'layerid': self.lver.pk,
                     'recipeid': self.recipe1.pk,
                     'recipe_id': image_recipe.pk,
-                    'custrecipeid': self.customr.pk
-                   }
+                    'custrecipeid': self.customr.pk}
 
             response = table.get(request, **args)
             return json.loads(response.content)
 
+        def get_text_from_td(td):
+            """If we have html in the td then extract the text portion"""
+            # just so we don't waste time parsing non html
+            if "<" not in td:
+                ret = td
+            else:
+                ret = BeautifulSoup(td).text
+
+            # We change the td into ascii as a way to remove characters
+            # such as \xa0 (non break space) which mess with the ordering
+            # comparisons
+            ret.strip().encode('ascii',
+                               errors='replace').replace('?', ' ')
+            # Case where the td is empty
+            if len(ret):
+                return "0"
+            else:
+                return ret
+
         # Get a list of classes in tables module
         tables = inspect.getmembers(toastergui.tables, inspect.isclass)
 
@@ -379,8 +403,10 @@ class ViewTests(TestCase):
                             "Cannot test on a %s table with < 1 row" % name)
 
             if table.default_orderby:
-                row_one = all_data['rows'][0][table.default_orderby.strip("-")]
-                row_two = all_data['rows'][1][table.default_orderby.strip("-")]
+                row_one = get_text_from_td(
+                    all_data['rows'][0][table.default_orderby.strip("-")])
+                row_two = get_text_from_td(
+                    all_data['rows'][1][table.default_orderby.strip("-")])
 
                 if '-' in table.default_orderby:
                     self.assertTrue(row_one >= row_two,
@@ -399,28 +425,36 @@ class ViewTests(TestCase):
                     # If a column is orderable test it in both order
                     # directions ordering on the columns field_name
                     ascending = get_data(table_cls(),
-                                         {"orderby" : column['field_name']})
+                                         {"orderby": column['field_name']})
 
-                    row_one = ascending['rows'][0][column['field_name']]
-                    row_two = ascending['rows'][1][column['field_name']]
+                    row_one = get_text_from_td(
+                        ascending['rows'][0][column['field_name']])
+                    row_two = get_text_from_td(
+                        ascending['rows'][1][column['field_name']])
 
                     self.assertTrue(row_one <= row_two,
-                                    "Ascending sort applied but row 0 is less "
-                                    "than row 1 %s %s " %
-                                    (column['field_name'], name))
-
+                                    "Ascending sort applied but row 0: \"%s\""
+                                    " is less than row 1: \"%s\" "
+                                    "%s %s " %
+                                    (row_one, row_two,
+                                     column['field_name'], name))
 
                     descending = get_data(table_cls(),
-                                          {"orderby" :
+                                          {"orderby":
                                            '-'+column['field_name']})
 
-                    row_one = descending['rows'][0][column['field_name']]
-                    row_two = descending['rows'][1][column['field_name']]
+                    row_one = get_text_from_td(
+                        descending['rows'][0][column['field_name']])
+                    row_two = get_text_from_td(
+                        descending['rows'][1][column['field_name']])
 
                     self.assertTrue(row_one >= row_two,
-                                    "Descending sort applied but row 0 is "
-                                    "greater than row 1 %s %s" %
-                                    (column['field_name'], name))
+                                    "Descending sort applied but row 0: %s"
+                                    "is greater than row 1: %s"
+                                    "field %s table %s" %
+                                    (row_one,
+                                     row_two,
+                                     column['field_name'], name))
 
                     # If the two start rows are the same we haven't actually
                     # changed the order
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 3/3] toaster: toastertables port table for Built packages
  2016-05-13 10:56 [PATCH v2 1/3] toaster: toastertables: Clean up and fix up a number of items Michael Wood
  2016-05-13 10:56 ` [PATCH v2 2/3] toaster: toastergui tests Fix toastertable tests Michael Wood
@ 2016-05-13 10:56 ` Michael Wood
  2016-05-16 10:09   ` Barros Pena, Belen
  1 sibling, 1 reply; 4+ messages in thread
From: Michael Wood @ 2016-05-13 10:56 UTC (permalink / raw)
  To: toaster

This is the table that displays all the packages built in the build.
Build -> Packages. Adds a template snippet for the git revision popover.

Signed-off-by: Michael Wood <michael.g.wood@intel.com>
---
 bitbake/lib/toaster/toastergui/buildtables.py      | 112 +++++++++++++++++++++
 bitbake/lib/toaster/toastergui/tables.py           |  10 +-
 .../lib/toaster/toastergui/templates/bpackage.html |  97 +++---------------
 .../templates/snippets/gitrev_popover.html         |   8 ++
 bitbake/lib/toaster/toastergui/urls.py             |   7 +-
 bitbake/lib/toaster/toastergui/views.py            |  90 -----------------
 6 files changed, 143 insertions(+), 181 deletions(-)
 create mode 100644 bitbake/lib/toaster/toastergui/buildtables.py
 create mode 100644 bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html

diff --git a/bitbake/lib/toaster/toastergui/buildtables.py b/bitbake/lib/toaster/toastergui/buildtables.py
new file mode 100644
index 0000000..4f338b9
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/buildtables.py
@@ -0,0 +1,112 @@
+#
+# 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"
+        self.default_orderby = "name"
+
+    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)
+        self.queryset = self.queryset.order_by(self.default_orderby)
+
+    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(*args, **kwargs)
+
+        def pkg_link_template(val):
+            """ return the template used for the link with the val as the
+            element value i.e. inside the <a></a>"""
+
+            return ('''
+                    <a href="
+                    {%% url "package_built_detail" extra.build.pk data.pk %%}
+                    ">%s</a>
+                    ''' % val)
+
+        def recipe_link_template(val):
+            return ('''
+                    {%% if data.recipe %%}
+                    <a href="
+                    {%% url "recipe" extra.build.pk data.recipe.pk %%}
+                    ">%(value)s</a>
+                    {%% else %%}
+                    %(value)s
+                    {%% endif %%}
+                    ''' % {'value': val})
+
+        add_pkg_link_to = ['name', 'version', 'size', 'license']
+        add_recipe_link_to = ['recipe__name', 'recipe__version']
+
+        # Add the recipe and pkg links to the required fields
+        for column in self.columns:
+            # Convert to template field style accessors
+            tmplv = column['field_name'].replace('__', '.')
+
+            if column['field_name'] in add_pkg_link_to:
+                column['static_data_template'] = pkg_link_template(tmplv)
+            elif column['field_name'] in add_recipe_link_to:
+                column['static_data_template'] = recipe_link_template(tmplv)
+
+        self.add_column(title="Layer",
+                        field_name="recipe__layer_version__layer__name",
+                        hidden=True,
+                        orderable=True)
+
+        self.add_column(title="Layer branch",
+                        field_name="recipe__layer_version__branch",
+                        hidden=True,
+                        orderable=True)
+
+        git_rev_template = '''
+        {% with vcs_ref=data.recipe.layer_version.commit %}
+        {% include 'snippets/gitrev_popover.html' %}
+        {% endwith %}
+        '''
+
+        self.add_column(title="Layer commit",
+                        static_data_name='vcs_ref',
+                        static_data_template=git_rev_template,
+                        hidden=True)
+
+        def remove_dep_cols(columns):
+            for column in columns:
+                # We don't need these fields
+                if column['static_data_name'] in ['reverse_dependencies',
+                                                  'dependencies']:
+                    continue
+
+                yield column
+
+        self.columns = list(remove_dep_cols(self.columns))
diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py
index 29b68de..39d3f93 100644
--- a/bitbake/lib/toaster/toastergui/tables.py
+++ b/bitbake/lib/toaster/toastergui/tables.py
@@ -146,15 +146,8 @@ 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>
-        {% else %}
-        {{vcs_ref}}
-        {% endif %}
+        {% include 'snippets/gitrev_popover.html' %}
         {% endwith %}
         '''
 
@@ -699,6 +692,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.branch}}</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/templates/snippets/gitrev_popover.html b/bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html
new file mode 100644
index 0000000..281a3bd
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html
@@ -0,0 +1,8 @@
+{% load projecttags  %}
+{% if vcs_ref|is_shaid %}
+<a class="btn" data-content="<ul class='unstyled'> <li>{{vcs_ref}}</li> </ul>">
+ {{vcs_ref|truncatechars:10}}
+</a>
+{% else %}
+{{vcs_ref}}
+{% endif %}
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 b7c674a..146502e 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



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 3/3] toaster: toastertables port table for Built packages
  2016-05-13 10:56 ` [PATCH v2 3/3] toaster: toastertables port table for Built packages Michael Wood
@ 2016-05-16 10:09   ` Barros Pena, Belen
  0 siblings, 0 replies; 4+ messages in thread
From: Barros Pena, Belen @ 2016-05-16 10:09 UTC (permalink / raw)
  To: Wood, Michael G, toaster

[-- Attachment #1: Type: text/plain, Size: 19752 bytes --]



On 13/05/2016 11:56, "toaster-bounces@yoctoproject.org on behalf of
Michael Wood" <toaster-bounces@yoctoproject.org on behalf of
michael.g.wood@intel.com> wrote:

>This is the table that displays all the packages built in the build.
>Build -> Packages. Adds a template snippet for the git revision popover.

Looking at this, seems the package size data no longer shows. The table
cells show "size" instead (see attached screenshot). Also, it should be
just 'Size', not 'Approx size'. Since we've built the package for that
specific build, shouldn't we be sure of the accuracy of the package size
reported?

Thanks!

Belén

>
>Signed-off-by: Michael Wood <michael.g.wood@intel.com>
>---
> bitbake/lib/toaster/toastergui/buildtables.py      | 112
>+++++++++++++++++++++
> bitbake/lib/toaster/toastergui/tables.py           |  10 +-
> .../lib/toaster/toastergui/templates/bpackage.html |  97
>+++---------------
> .../templates/snippets/gitrev_popover.html         |   8 ++
> bitbake/lib/toaster/toastergui/urls.py             |   7 +-
> bitbake/lib/toaster/toastergui/views.py            |  90
>-----------------
> 6 files changed, 143 insertions(+), 181 deletions(-)
> create mode 100644 bitbake/lib/toaster/toastergui/buildtables.py
> create mode 100644
>bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html
>
>diff --git a/bitbake/lib/toaster/toastergui/buildtables.py
>b/bitbake/lib/toaster/toastergui/buildtables.py
>new file mode 100644
>index 0000000..4f338b9
>--- /dev/null
>+++ b/bitbake/lib/toaster/toastergui/buildtables.py
>@@ -0,0 +1,112 @@
>+#
>+# 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"
>+        self.default_orderby = "name"
>+
>+    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)
>+        self.queryset = self.queryset.order_by(self.default_orderby)
>+
>+    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(*args, **kwargs)
>+
>+        def pkg_link_template(val):
>+            """ return the template used for the link with the val as the
>+            element value i.e. inside the <a></a>"""
>+
>+            return ('''
>+                    <a href="
>+                    {%% url "package_built_detail" extra.build.pk
>data.pk %%}
>+                    ">%s</a>
>+                    ''' % val)
>+
>+        def recipe_link_template(val):
>+            return ('''
>+                    {%% if data.recipe %%}
>+                    <a href="
>+                    {%% url "recipe" extra.build.pk data.recipe.pk %%}
>+                    ">%(value)s</a>
>+                    {%% else %%}
>+                    %(value)s
>+                    {%% endif %%}
>+                    ''' % {'value': val})
>+
>+        add_pkg_link_to = ['name', 'version', 'size', 'license']
>+        add_recipe_link_to = ['recipe__name', 'recipe__version']
>+
>+        # Add the recipe and pkg links to the required fields
>+        for column in self.columns:
>+            # Convert to template field style accessors
>+            tmplv = column['field_name'].replace('__', '.')
>+
>+            if column['field_name'] in add_pkg_link_to:
>+                column['static_data_template'] = pkg_link_template(tmplv)
>+            elif column['field_name'] in add_recipe_link_to:
>+                column['static_data_template'] =
>recipe_link_template(tmplv)
>+
>+        self.add_column(title="Layer",
>+                        field_name="recipe__layer_version__layer__name",
>+                        hidden=True,
>+                        orderable=True)
>+
>+        self.add_column(title="Layer branch",
>+                        field_name="recipe__layer_version__branch",
>+                        hidden=True,
>+                        orderable=True)
>+
>+        git_rev_template = '''
>+        {% with vcs_ref=data.recipe.layer_version.commit %}
>+        {% include 'snippets/gitrev_popover.html' %}
>+        {% endwith %}
>+        '''
>+
>+        self.add_column(title="Layer commit",
>+                        static_data_name='vcs_ref',
>+                        static_data_template=git_rev_template,
>+                        hidden=True)
>+
>+        def remove_dep_cols(columns):
>+            for column in columns:
>+                # We don't need these fields
>+                if column['static_data_name'] in ['reverse_dependencies',
>+                                                  'dependencies']:
>+                    continue
>+
>+                yield column
>+
>+        self.columns = list(remove_dep_cols(self.columns))
>diff --git a/bitbake/lib/toaster/toastergui/tables.py
>b/bitbake/lib/toaster/toastergui/tables.py
>index 29b68de..39d3f93 100644
>--- a/bitbake/lib/toaster/toastergui/tables.py
>+++ b/bitbake/lib/toaster/toastergui/tables.py
>@@ -146,15 +146,8 @@ 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>
>-        {% else %}
>-        {{vcs_ref}}
>-        {% endif %}
>+        {% include 'snippets/gitrev_popover.html' %}
>         {% endwith %}
>         '''
> 
>@@ -699,6 +692,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.branc
>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/templates/snippets/gitrev_popover.html
>b/bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html
>new file mode 100644
>index 0000000..281a3bd
>--- /dev/null
>+++ 
>b/bitbake/lib/toaster/toastergui/templates/snippets/gitrev_popover.html
>@@ -0,0 +1,8 @@
>+{% load projecttags  %}
>+{% if vcs_ref|is_shaid %}
>+<a class="btn" data-content="<ul class='unstyled'> <li>{{vcs_ref}}</li>
></ul>">
>+ {{vcs_ref|truncatechars:10}}
>+</a>
>+{% else %}
>+{{vcs_ref}}
>+{% endif %}
>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 b7c674a..146502e 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
>toaster@yoctoproject.org
>https://lists.yoctoproject.org/listinfo/toaster


[-- Attachment #2: packages-built.png --]
[-- Type: image/png, Size: 169397 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-05-16 10:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-13 10:56 [PATCH v2 1/3] toaster: toastertables: Clean up and fix up a number of items Michael Wood
2016-05-13 10:56 ` [PATCH v2 2/3] toaster: toastergui tests Fix toastertable tests Michael Wood
2016-05-13 10:56 ` [PATCH v2 3/3] toaster: toastertables port table for Built packages Michael Wood
2016-05-16 10:09   ` Barros Pena, Belen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.