Hi Marius,

Your patches passed functional testing, but I need you to re-do them a bit
to get them merged -

- Can you please rebase your patchset on top of origin/master ? I have
conflicts.
- Please do not use Tab, but instead 4-spaces in the files; this is the
current whitespace standard we use.

Thanks,
Alex


On Fri, Aug 29, 2014 at 1:51 PM, Marius Avram <[email protected]>
wrote:

> Until now cookies were used to save which columns were shown and which
> were hidden in toaster tables. The tables from the templates also have
> functionalities like sorting the entries on a certain column and
> limiting the number of entries displayed on a page. The later however
> were not saved using cookies. This patch brings this new feature.
>
> The cookies are not saved only in the front-end. They are saved both
> in the frontend in case the user uses the inputs/buttons to change
> a parameter and also in the backend in case the user specifies manually
> using GET variables the value of the parameters.
>
> When no GET parameters are given the views will redirect the url to one
> containg the parameters saved as cookies. When no cookies exist, default
> values will be used.
>
> [YOCTO #6126]
>
> Signed-off-by: Marius Avram <[email protected]>
> ---
>  .../toastergui/templates/basetable_bottom.html     |   15 ++-
>  .../toastergui/templates/basetable_top.html        |   11 +-
>  bitbake/lib/toaster/toastergui/views.py            |  122
> +++++++++++++-------
>  3 files changed, 102 insertions(+), 46 deletions(-)
>
> diff --git
> a/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
> b/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
> index ac14363..cbdc164 100644
> --- a/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
> +++ b/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html
> @@ -26,7 +26,7 @@
>                              <span class="help-inline"
> style="padding-top:5px;">Show rows:</span>
>                              <select
> style="margin-top:5px;margin-bottom:0px;" class="pagesize">
>    {% with "2 5 10 25 50 100" as list%}
> -    {% for i in list.split %}<option{%if i == request.GET.count %}
> selected{%endif%}>{{i}}</option>
> +    {% for i in list.split %}<option value="{{i}}">{{i}}</option>
>      {% endfor %}
>    {% endwith %}
>                              </select>
> @@ -56,6 +56,14 @@
>      }
>      }
>
> +    // load cookie for number of entries to be displayed on page
> +    pagesize = $.cookie('count');
> +    if (!pagesize)
> +        pagesize = 10;
> +    $('.pagesize option').prop('selected', false)
> +                         .filter('[value="' + pagesize + '"]')
> +                         .attr('selected', true);
> +
>      $('.chbxtoggle').each(function () {
>          showhideTableColumn($(this).attr('id'), $(this).is(':checked'))
>      });
> @@ -72,8 +80,9 @@
>      $('.progress, .lead span').tooltip({container:'table',
> placement:'top'});
>
>      $(".pagesize").change(function () {
> -        console.log("page size change");
> -        reload_params({"count":$(this).val()}); ;
> +        reload_params({"count":$(this).val()});
> +        // save cookie with pagesize
> +        $.cookie("count", $(this).val(), { path :
> $(location).attr('pathname') });
>      });
>  });
>  </script>
> diff --git a/bitbake/lib/toaster/toastergui/templates/basetable_top.html
> b/bitbake/lib/toaster/toastergui/templates/basetable_top.html
> index 1231e1f..037554b 100644
> --- a/bitbake/lib/toaster/toastergui/templates/basetable_top.html
> +++ b/bitbake/lib/toaster/toastergui/templates/basetable_top.html
> @@ -156,6 +156,13 @@
>          showhideImmediateTableAction( clname, sh, orderkey );
>      }
>
> +    //
> +    // saves a cookie with selected order field
> +    //
> +    function saveOrderCookie( orderfield ) {
> +        $.cookie("orderby", orderfield, { path:
> $(location).attr('pathname') });
> +    }
> +
>      </script>
>
>  <!-- control header -->
> @@ -205,7 +212,7 @@
>                  <span class="help-inline" style="padding-top:5px;">Show
> rows:</span>
>                  <select style="margin-top:5px;margin-bottom:0px;"
> class="pagesize">
>    {% with "2 5 10 25 50 100" as list%}
> -{% for i in list.split %}                    <option{%if i ==
> request.GET.count %} selected{%endif%}>{{i}}</option>
> +{% for i in list.split %}                    <option
> value="{{i}}">{{i}}</option>
>      {% endfor %}
>    {% endwith %}
>                  </select>
> @@ -221,7 +228,7 @@
>          <tr>
>              {% for tc in tablecols %}<th class="{{tc.dclass}}
> {{tc.clclass}}">
>                  {%if tc.qhelp%}<i class="icon-question-sign get-help"
> title="{{tc.qhelp}}"></i>{%endif%}
> -                {%if tc.orderfield%}<a {%if tc.ordericon%} class="sorted"
> {%endif%}href="javascript:reload_params({'page': 1, 'orderby' :
> '{{tc.orderfield}}' })" >{{tc.name}}</a>{%else%}<span class="muted">{{
> tc.name}}</span>{%endif%}
> +                {%if tc.orderfield%}<a {%if tc.ordericon%} class="sorted"
> {%endif%}href="javascript:reload_params({'page': 1, 'orderby' :
> '{{tc.orderfield}}' })" onclick="saveOrderCookie('{{tc.orderfield}}')">{{
> tc.name}}</a>{%else%}<span class="muted">{{tc.name}}</span>{%endif%}
>                  {%if tc.ordericon%} <i
> class="icon-caret-{{tc.ordericon}}"></i>{%endif%}
>                  {%if tc.filter%}<div class="btn-group pull-right">
>                      <a href="#filter_{{tc.filter.class}}" role="button"
> class="btn btn-mini {%if
> request.GET.filter%}{{tc.filter.options|filtered_icon:request.GET.filter}}
> {%endif%}" {%if request.GET.filter and
> tc.filter.options|filtered_tooltip:request.GET.filter %}
> title="<p>{{tc.filter.options|filtered_tooltip:request.GET.filter}}</p><p><a
> class='btn btn-small btn-primary'
> href=javascript:reload_params({'filter':''})>Show all {% if
> filter_search_display %}{{filter_search_display}}{% else %}{{objectname}}{%
> endif %}</a></p>" {%endif%} data-toggle="modal"> <i class="icon-filter
> filtered"></i> </a>
> diff --git a/bitbake/lib/toaster/toastergui/views.py
> b/bitbake/lib/toaster/toastergui/views.py
> index bd65c08..d60b2f5 100755
> --- a/bitbake/lib/toaster/toastergui/views.py
> +++ b/bitbake/lib/toaster/toastergui/views.py
> @@ -20,6 +20,7 @@
>  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>
>  import operator,re
> +import HTMLParser
>
>  from django.db.models import Q, Sum
>  from django.db import IntegrityError
> @@ -32,6 +33,7 @@ from django.core.urlresolvers import reverse
>  from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
>  from django.http import HttpResponseBadRequest, HttpResponseNotFound
>  from django.utils import timezone
> +from django.utils.html import escape
>  from datetime import timedelta
>  from django.utils import formats
>  import json
> @@ -200,6 +202,22 @@ def _get_queryset(model, queryset, filter_string,
> search_term, ordering_string,
>      # insure only distinct records (e.g. from multiple search hits) are
> returned
>      return queryset.distinct()
>
> +# returns the value of entries per page and the name of the applied
> sorting field.
> +# if the value is given explicitly as a GET parameter it will be the
> first selected,
> +# otherwise the cookie value will be used.
> +def _get_parameters_values(request, default_count, default_order):
> +    pagesize = request.GET.get('count', request.COOKIES.get('count',
> default_count))
> +    orderby = request.GET.get('orderby', request.COOKIES.get('orderby',
> default_order))
> +    return (pagesize, orderby)
> +
> +
> +# set cookies for parameters. this is usefull in case parameters are set
> +# manually from the GET values of the link
> +def _save_parameters_cookies(response, pagesize, orderby, request):
> +    html_parser = HTMLParser.HTMLParser()
> +    response.set_cookie(key='count', value=pagesize, path=request.path)
> +    response.set_cookie(key='orderby',
> value=html_parser.unescape(orderby), path=request.path)
> +    return response
>
>  # shows the "all builds" page
>  def builds(request):
> @@ -207,7 +225,8 @@ def builds(request):
>      # define here what parameters the view needs in the GET portion in
> order to
>      # be able to display something.  'count' and 'page' are mandatory for
> all views
>      # that use paginators.
> -    mandatory_parameters = { 'count': 10,  'page' : 1, 'orderby' :
> 'completed_on:-' };
> +    (pagesize, orderby) = _get_parameters_values(request, 10,
> 'completed_on:-')
> +    mandatory_parameters = { 'count': pagesize,  'page' : 1, 'orderby' :
> orderby }
>      retval = _verify_parameters( request.GET, mandatory_parameters )
>      if retval:
>          return _redirect_parameters( 'all-builds', request.GET,
> mandatory_parameters)
> @@ -220,7 +239,7 @@ def builds(request):
>      queryset = _get_queryset(Build, queryset_all, filter_string,
> search_term, ordering_string, '-completed_on')
>
>      # retrieve the objects that will be displayed in the table; builds a
> paginator and gets a page range to display
> -    build_info = _build_page_range(Paginator(queryset,
> request.GET.get('count', 10)),request.GET.get('page', 1))
> +    build_info = _build_page_range(Paginator(queryset, pagesize),
> request.GET.get('page', 1))
>
>      # build view-specific information; this is rendered specifically in
> the builds page, at the top of the page (i.e. Recent builds)
>      build_mru =
> Build.objects.filter(completed_on__gte=(timezone.now()-timedelta(hours=24))).order_by("-started_on")[:3]
> @@ -379,7 +398,9 @@ def builds(request):
>                  ]
>              }
>
> -    return render(request, template, context)
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>
>  ##
> @@ -548,8 +569,8 @@ def recipe(request, build_id, recipe_id):
>
>  def target_common( request, build_id, target_id, variant ):
>      template = "target.html"
> -    default_orderby = 'name:+';
> -    mandatory_parameters = { 'count': 25,  'page' : 1,
> 'orderby':'name:+'};
> +    (pagesize, orderby) = _get_parameters_values(request, 25, 'name:+')
> +    mandatory_parameters = { 'count': pagesize,  'page' : 1, 'orderby':
> orderby }
>      retval = _verify_parameters( request.GET, mandatory_parameters )
>      if retval:
>          return _redirect_parameters(
> @@ -565,8 +586,7 @@ def target_common( request, build_id, target_id,
> variant ):
>      packages_sum =  queryset.aggregate( Sum( 'installed_size' ))
>      queryset = _get_queryset(
>              Package, queryset, filter_string, search_term,
> ordering_string, 'name' )
> -    packages = _build_page_range( Paginator(
> -            queryset, request.GET.get( 'count', 25 )),request.GET.get(
> 'page', 1 ))
> +    packages = _build_page_range( Paginator(queryset, pagesize),
> request.GET.get( 'page', 1 ))
>
>      # bring in package dependencies
>      for p in packages.object_list:
> @@ -690,7 +710,7 @@ his package',
>          'objects'              : packages,
>          'packages_sum'         : packages_sum[ 'installed_size__sum' ],
>          'object_search_display': "packages included",
> -        'default_orderby'      : default_orderby,
> +        'default_orderby'      : orderby,
>          'tablecols'            : [
>                      tc_package,
>                      tc_packageVersion,
> @@ -707,7 +727,10 @@ his package',
>                      tc_layerDir,
>                  ]
>          }
> -    return( render( request, template, context ))
> +
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>  def target( request, build_id, target_id ):
>      return( target_common( request, build_id, target_id, "target" ))
> @@ -889,26 +912,25 @@ def tasks_common(request, build_id, variant,
> task_anchor):
>          title_variant='Time'
>          object_search_display="time data"
>          filter_search_display="tasks"
> -        mandatory_parameters = { 'count': 25,  'page' : 1,
> 'orderby':'elapsed_time:-'};
> -        default_orderby = 'elapsed_time:-';
> +        (pagesize, orderby) = _get_parameters_values(request, 25,
> 'elapsed_time:-')
>      elif 'diskio'    == variant:
>          title_variant='Disk I/O'
>          object_search_display="disk I/O data"
>          filter_search_display="tasks"
> -        mandatory_parameters = { 'count': 25,  'page' : 1,
> 'orderby':'disk_io:-'};
> -        default_orderby = 'disk_io:-';
> +        (pagesize, orderby) = _get_parameters_values(request, 25,
> 'disk_io:-')
>      elif 'cpuusage'  == variant:
>          title_variant='CPU usage'
>          object_search_display="CPU usage data"
>          filter_search_display="tasks"
> -        mandatory_parameters = { 'count': 25,  'page' : 1,
> 'orderby':'cpu_usage:-'};
> -        default_orderby = 'cpu_usage:-';
> +        (pagesize, orderby) = _get_parameters_values(request, 25,
> 'cpu_usage:-')
>      else :
>          title_variant='Tasks'
>          object_search_display="tasks"
>          filter_search_display="tasks"
> -        mandatory_parameters = { 'count': 25,  'page' : 1,
> 'orderby':'order:+'};
> -        default_orderby = 'order:+';
> +        (pagesize, orderby) = _get_parameters_values(request, 25,
> 'order:+')
> +
> +
> +    mandatory_parameters = { 'count': pagesize,  'page' : 1, 'orderby':
> orderby }
>
>      template = 'tasks.html'
>      retval = _verify_parameters( request.GET, mandatory_parameters )
> @@ -934,7 +956,7 @@ def tasks_common(request, build_id, variant,
> task_anchor):
>          del request.GET['anchor']
>          i=0
>          a=int(anchor)
> -               count_per_page=int(request.GET.get('count', 100))
> +               count_per_page=int(pagesize)
>          for task in queryset.iterator():
>              if a == task.order:
>                                 new_page= (i / count_per_page ) + 1
> @@ -943,7 +965,7 @@ def tasks_common(request, build_id, variant,
> task_anchor):
>                                 return _redirect_parameters( variant,
> request.GET, mandatory_parameters, build_id = build_id)
>              i += 1
>
> -    tasks = _build_page_range(Paginator(queryset,
> request.GET.get('count', 100)),request.GET.get('page', 1))
> +    tasks = _build_page_range(Paginator(queryset,
> pagesize),request.GET.get('page', 1))
>
>      # define (and modify by variants) the 'tablecols' members
>      tc_order={
> @@ -1074,7 +1096,7 @@ def tasks_common(request, build_id, variant,
> task_anchor):
>                  'title': title_variant,
>                  'build': Build.objects.filter(pk=build_id)[0],
>                  'objects': tasks,
> -                'default_orderby' : default_orderby,
> +                'default_orderby' : orderby,
>                  'search_term': search_term,
>                  'total_count': queryset_with_search.count(),
>                  'tablecols':[
> @@ -1091,7 +1113,9 @@ def tasks_common(request, build_id, variant,
> task_anchor):
>                      tc_log,
>                  ]}
>
> -    return render(request, template, context)
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>  def tasks(request, build_id):
>      return tasks_common(request, build_id, 'tasks', '')
> @@ -1111,7 +1135,8 @@ def cpuusage(request, build_id):
>
>  def recipes(request, build_id):
>      template = 'recipes.html'
> -    mandatory_parameters = { 'count': 100,  'page' : 1,
> 'orderby':'name:+'};
> +    (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( 'recipes', request.GET,
> mandatory_parameters, build_id = build_id)
> @@ -1119,7 +1144,7 @@ def recipes(request, build_id):
>      queryset =
> Recipe.objects.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id))
>      queryset = _get_queryset(Recipe, queryset, filter_string,
> search_term, ordering_string, 'name')
>
> -    recipes = _build_page_range(Paginator(queryset,
> request.GET.get('count', 100)),request.GET.get('page', 1))
> +    recipes = _build_page_range(Paginator(queryset,
> pagesize),request.GET.get('page', 1))
>
>      # prefetch the forward and reverse recipe dependencies
>      deps = { }; revs = { }
> @@ -1218,8 +1243,9 @@ def recipes(request, build_id):
>              ]
>          }
>
> -    return render(request, template, context)
> -
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>  def configuration(request, build_id):
>      template = 'configuration.html'
> @@ -1258,7 +1284,8 @@ def configuration(request, build_id):
>
>  def configvars(request, build_id):
>      template = 'configvars.html'
> -    mandatory_parameters = { 'count': 100,  'page' : 1,
> 'orderby':'variable_name:+', 'filter':'description__regex:.+'};
> +    (pagesize, orderby) = _get_parameters_values(request, 100,
> 'variable_name:+')
> +    mandatory_parameters = { 'count': pagesize,  'page' : 1, 'orderby' :
> orderby, 'filter' : 'description__regex:.+' }
>      retval = _verify_parameters( request.GET, mandatory_parameters )
>      (filter_string, search_term, ordering_string) =
> _search_tuple(request, Variable)
>      if retval:
> @@ -1273,7 +1300,7 @@ def configvars(request, build_id):
>      # remove records where the value is empty AND there are no history
> files
>      queryset =
> queryset.exclude(variable_value='',vhistory__file_name__isnull=True)
>
> -    variables = _build_page_range(Paginator(queryset,
> request.GET.get('count', 50)), request.GET.get('page', 1))
> +    variables = _build_page_range(Paginator(queryset, pagesize),
> request.GET.get('page', 1))
>
>      # show all matching files (not just the last one)
>      file_filter= search_term + ":"
> @@ -1339,12 +1366,14 @@ def configvars(request, build_id):
>                  ],
>              }
>
> -    return render(request, template, context)
> -
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>  def bpackage(request, build_id):
>      template = 'bpackage.html'
> -    mandatory_parameters = { 'count': 100,  'page' : 1,
> 'orderby':'name:+'};
> +    (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)
> @@ -1352,7 +1381,7 @@ def bpackage(request, build_id):
>      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,
> request.GET.get('count', 100)),request.GET.get('page', 1))
> +    packages = _build_page_range(Paginator(queryset,
> pagesize),request.GET.get('page', 1))
>
>      context = {
>          'objectname': 'packages built',
> @@ -1432,7 +1461,9 @@ def bpackage(request, build_id):
>              ]
>          }
>
> -    return render(request, template, context)
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>  def bfile(request, build_id, package_id):
>      template = 'bfile.html'
> @@ -1587,7 +1618,8 @@ def package_built_detail(request, build_id,
> package_id):
>
>      # follow convention for pagination w/ search although not used for
> this view
>      queryset = Package_File.objects.filter(package_id__exact=package_id)
> -    mandatory_parameters = { 'count': 25,  'page' : 1,
> 'orderby':'path:+'};
> +    (pagesize, orderby) = _get_parameters_values(request, 25, 'path:+')
> +    mandatory_parameters = { 'count': pagesize,  'page' : 1, 'orderby' :
> orderby }
>      retval = _verify_parameters( request.GET, mandatory_parameters )
>      if retval:
>          return _redirect_parameters( 'package_built_detail', request.GET,
> mandatory_parameters, build_id = build_id, package_id = package_id)
> @@ -1618,7 +1650,10 @@ def package_built_detail(request, build_id,
> package_id):
>      }
>      if paths.all().count() < 2:
>          context['disable_sort'] = True;
> -    return render(request, template, context)
> +
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>  def package_built_dependencies(request, build_id, package_id):
>      template = "package_built_dependencies.html"
> @@ -1643,9 +1678,9 @@ def package_included_detail(request, build_id,
> target_id, package_id):
>      if Build.objects.filter(pk=build_id).count() == 0 :
>          return redirect(builds)
>
> -
>      # follow convention for pagination w/ search although not used for
> this view
> -    mandatory_parameters = { 'count': 25,  'page' : 1,
> 'orderby':'path:+'};
> +    (pagesize, orderby) = _get_parameters_values(request, 25, 'path:+')
> +    mandatory_parameters = { 'count': pagesize,  'page' : 1, 'orderby' :
> orderby }
>      retval = _verify_parameters( request.GET, mandatory_parameters )
>      if retval:
>          return _redirect_parameters( 'package_included_detail',
> request.GET, mandatory_parameters, build_id = build_id, target_id =
> target_id, package_id = package_id)
> @@ -1680,8 +1715,10 @@ def package_included_detail(request, build_id,
> target_id, package_id):
>              ]
>      }
>      if paths.all().count() < 2:
> -        context['disable_sort'] = True;
> -    return render(request, template, context)
> +        context['disable_sort'] = True
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>  def package_included_dependencies(request, build_id, target_id,
> package_id):
>      template = "package_included_dependencies.html"
> @@ -1710,7 +1747,8 @@ def package_included_reverse_dependencies(request,
> build_id, target_id, package_
>      if Build.objects.filter(pk=build_id).count() == 0 :
>          return redirect(builds)
>
> -    mandatory_parameters = { 'count': 25,  'page' : 1,
> 'orderby':'package__name:+'};
> +    (pagesize, orderby) = _get_parameters_values(request, 25,
> 'package__name:+')
> +    mandatory_parameters = { 'count': pagesize,  'page' : 1, 'orderby':
> orderby }
>      retval = _verify_parameters( request.GET, mandatory_parameters )
>      if retval:
>          return _redirect_parameters(
> 'package_included_reverse_dependencies', request.GET, mandatory_parameters,
> build_id = build_id, target_id = target_id, package_id = package_id)
> @@ -1752,8 +1790,10 @@ def package_included_reverse_dependencies(request,
> build_id, target_id, package_
>              ]
>      }
>      if objects.all().count() < 2:
> -        context['disable_sort'] = True;
> -    return render(request, template, context)
> +        context['disable_sort'] = True
> +    response = render(request, template, context)
> +    _save_parameters_cookies(response, pagesize, orderby, request)
> +    return response
>
>  def image_information_dir(request, build_id, target_id, packagefile_id):
>      # stubbed for now
> --
> 1.7.9.5
>
> --
> _______________________________________________
> toaster mailing list
> [email protected]
> https://lists.yoctoproject.org/listinfo/toaster
>



-- 
Alex Damian
Yocto Project
SSG / OTC
-- 
_______________________________________________
toaster mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/toaster

Reply via email to