aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2015-06-03 12:36:30 +0100
committerAlexandru DAMIAN <alexandru.damian@intel.com>2015-06-10 15:31:12 +0100
commit1778dac9fd39dae75c55bf2cf836cdd488dbc265 (patch)
tree99765f72b1e3e131818a9f10b474201bcd1d9f7e
parent7a6eb36b82c5f2e342777e479d9c401ded42453d (diff)
downloadbitbake-1778dac9fd39dae75c55bf2cf836cdd488dbc265.tar.gz
toaster: toastertables REST refactoring
This patch refactors the ToasterTables to bring them in line with REST principles - - all table pages now support the "format=json" GET parameter that returns the data in JSON format - the tables themselves This cleans up the URL namespace by aleviating the need to have two URLS for each table (one for the template and one for the data loading), and fixes minor things in the ToasterTable implementation. Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
-rw-r--r--lib/toaster/toastergui/static/js/table.js5
-rw-r--r--lib/toaster/toastergui/tables.py84
-rw-r--r--lib/toaster/toastergui/templates/layerdetails.html2
-rw-r--r--lib/toaster/toastergui/templates/toastertable-simple.html2
-rw-r--r--lib/toaster/toastergui/templates/toastertable.html2
-rw-r--r--lib/toaster/toastergui/urls.py30
-rw-r--r--lib/toaster/toastergui/widgets.py47
7 files changed, 102 insertions, 70 deletions
diff --git a/lib/toaster/toastergui/static/js/table.js b/lib/toaster/toastergui/static/js/table.js
index 2e35e3871..7588a4ab9 100644
--- a/lib/toaster/toastergui/static/js/table.js
+++ b/lib/toaster/toastergui/static/js/table.js
@@ -383,12 +383,13 @@ function tableInit(ctx){
*/
var params = {
'name' : filterName,
- 'search': tableParams.search
+ 'search': tableParams.search,
+ 'cmd': 'filterinfo',
};
$.ajax({
type: "GET",
- url: ctx.url + 'filterinfo',
+ url: ctx.url,
data: params,
headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
success: function (filterData) {
diff --git a/lib/toaster/toastergui/tables.py b/lib/toaster/toastergui/tables.py
index 9a93ff9aa..b75e56524 100644
--- a/lib/toaster/toastergui/tables.py
+++ b/lib/toaster/toastergui/tables.py
@@ -19,7 +19,7 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-from widgets import ToasterTable
+from toastergui.widgets import ToasterTable
from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project
from django.db.models import Q, Max
from django.conf.urls import url
@@ -29,9 +29,19 @@ class LayersTable(ToasterTable):
"""Table of layers in Toaster"""
def __init__(self, *args, **kwargs):
- ToasterTable.__init__(self)
+ super(LayersTable, self).__init__(*args, **kwargs)
self.default_orderby = "layer__name"
+ def get_context_data(self, **kwargs):
+ context = super(LayersTable, self).get_context_data(**kwargs)
+
+ context['project'] = Project.objects.get(pk=kwargs['pid'])
+
+ context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project']))
+
+ return context
+
+
def setup_queryset(self, *args, **kwargs):
prj = Project.objects.get(pk = kwargs['pid'])
compatible_layers = prj.compatible_layerversions()
@@ -132,14 +142,31 @@ class LayersTable(ToasterTable):
static_data_name="add-del-layers",
static_data_template='{% include "layer_btn.html" %}')
+class LayerDetails(TemplateView):
+ def get_context_data(self, **kwargs):
+ context = super(LayerDetails, self).get_context_data(**kwargs)
+
+ context['project'] = Project.objects.get(pk=kwargs['pid'])
+ context['layerversion'] = Layer_Version.objects.get(pk=kwargs['layerid'])
+ context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project']))
+
+ return context
+
class MachinesTable(ToasterTable):
"""Table of Machines in Toaster"""
def __init__(self, *args, **kwargs):
- ToasterTable.__init__(self)
+ super(MachinesTable, self).__init__(*args, **kwargs)
self.empty_state = "No machines maybe you need to do a build?"
self.default_orderby = "name"
+ def get_context_data(self, **kwargs):
+ context = super(MachinesTable, self).get_context_data(**kwargs)
+ context['project'] = Project.objects.get(pk=kwargs['pid'])
+ context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project']))
+ return context
+
+
def setup_queryset(self, *args, **kwargs):
prj = Project.objects.get(pk = kwargs['pid'])
compatible_layers = prj.compatible_layerversions()
@@ -191,7 +218,13 @@ class LayerMachinesTable(MachinesTable):
""" Smaller version of the Machines table for use in layer details """
def __init__(self, *args, **kwargs):
- MachinesTable.__init__(self)
+ super(LayerMachinesTable, self).__init__(*args, **kwargs)
+
+ def get_context_data(self, **kwargs):
+ context = super(LayerMachinesTable, self).get_context_data(**kwargs)
+ context['layerversion'] = Layer_Version.objects.get(pk=kwargs['layerid'])
+ return context
+
def setup_queryset(self, *args, **kwargs):
MachinesTable.setup_queryset(self, *args, **kwargs)
@@ -219,10 +252,20 @@ class RecipesTable(ToasterTable):
"""Table of Recipes in Toaster"""
def __init__(self, *args, **kwargs):
- ToasterTable.__init__(self)
+ super(RecipesTable, self).__init__(*args, **kwargs)
self.empty_state = "Toaster has no recipe information. To generate recipe information you can configure a layer source then run a build."
self.default_orderby = "name"
+ def get_context_data(self, **kwargs):
+ context = super(RecipesTable, self).get_context_data(**kwargs)
+
+ context['project'] = Project.objects.get(pk=kwargs['pid'])
+
+ context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project']))
+
+ return context
+
+
def setup_queryset(self, *args, **kwargs):
prj = Project.objects.get(pk = kwargs['pid'])
@@ -293,10 +336,16 @@ class RecipesTable(ToasterTable):
static_data_template='{% include "recipe_btn.html" %}')
class LayerRecipesTable(RecipesTable):
- """ Smaller version of the Machines table for use in layer details """
+ """ Smaller version of the Recipes table for use in layer details """
def __init__(self, *args, **kwargs):
- RecipesTable.__init__(self)
+ super(LayerRecipesTable, self).__init__(*args, **kwargs)
+
+ def get_context_data(self, **kwargs):
+ context = super(LayerRecipesTable, self).get_context_data(**kwargs)
+ context['layerversion'] = Layer_Version.objects.get(pk=kwargs['layerid'])
+ return context
+
def setup_queryset(self, *args, **kwargs):
RecipesTable.setup_queryset(self, *args, **kwargs)
@@ -320,24 +369,3 @@ class LayerRecipesTable(RecipesTable):
self.add_column(title="Build recipe",
static_data_name="add-del-layers",
static_data_template=build_recipe_template)
-
-
-
-# This needs to be staticaly defined here as django reads the url patterns
-# on start up
-urlpatterns = (
- url(r'^machines/(?P<cmd>\w+)*', MachinesTable.as_view(),
- name=MachinesTable.__name__.lower()),
- url(r'^layers/(?P<cmd>\w+)*', LayersTable.as_view(),
- name=LayersTable.__name__.lower()),
- url(r'^recipes/(?P<cmd>\w+)*', RecipesTable.as_view(),
- name=RecipesTable.__name__.lower()),
-
- # layer details tables
- url(r'^layer/(?P<layerid>\d+)/recipes/(?P<cmd>\w+)*',
- LayerRecipesTable.as_view(),
- name=LayerRecipesTable.__name__.lower()),
- url(r'^layer/(?P<layerid>\d+)/machines/(?P<cmd>\w+)*',
- LayerMachinesTable.as_view(),
- name=LayerMachinesTable.__name__.lower()),
-)
diff --git a/lib/toaster/toastergui/templates/layerdetails.html b/lib/toaster/toastergui/templates/layerdetails.html
index 259a59ea0..c27d259a8 100644
--- a/lib/toaster/toastergui/templates/layerdetails.html
+++ b/lib/toaster/toastergui/templates/layerdetails.html
@@ -33,7 +33,7 @@
$(document).ready(function (){
var ctx = {
- projectBuildUrl : "{% url 'xhr_build' %}",
+ projectBuildUrl : "{% url 'xhr_projectbuild' project.id %}",
layerDetailsUrl : "{% url 'base_layerdetails' project.id %}",
xhrUpdateLayerUrl : "{% url 'xhr_updatelayer' %}",
layerVersion : {
diff --git a/lib/toaster/toastergui/templates/toastertable-simple.html b/lib/toaster/toastergui/templates/toastertable-simple.html
index 23a75260a..ea7b38e13 100644
--- a/lib/toaster/toastergui/templates/toastertable-simple.html
+++ b/lib/toaster/toastergui/templates/toastertable-simple.html
@@ -10,7 +10,7 @@
var ctx = {
tableName : "{{table_name}}",
- url : "{{ xhr_table_url }}",
+ url : "{{ xhr_table_url }}?format=json",
title : "{{title}}",
projectLayers : {{projectlayers|json}},
};
diff --git a/lib/toaster/toastergui/templates/toastertable.html b/lib/toaster/toastergui/templates/toastertable.html
index 5c79ab4ae..c7c7a84bf 100644
--- a/lib/toaster/toastergui/templates/toastertable.html
+++ b/lib/toaster/toastergui/templates/toastertable.html
@@ -10,7 +10,7 @@
var ctx = {
tableName : "{{table_name}}",
- url : "{{ xhr_table_url }}",
+ url : "{{ xhr_table_url }}?format=json",
title : "{{title}}",
projectLayers : {{projectlayers|json}},
};
diff --git a/lib/toaster/toastergui/urls.py b/lib/toaster/toastergui/urls.py
index 4e328dae1..e10e0bb15 100644
--- a/lib/toaster/toastergui/urls.py
+++ b/lib/toaster/toastergui/urls.py
@@ -20,8 +20,7 @@ from django.conf.urls import patterns, include, url
from django.views.generic import RedirectView, TemplateView
from django.http import HttpResponseBadRequest
-import tables
-from widgets import ToasterTemplateView
+from toastergui import tables
urlpatterns = patterns('toastergui.views',
# landing page
@@ -81,32 +80,46 @@ urlpatterns = patterns('toastergui.views',
url(r'^project/(?P<pid>\d+)/configuration$', 'projectconf', name='projectconf'),
url(r'^project/(?P<pid>\d+)/builds/$', 'projectbuilds', name='projectbuilds'),
- url(r'^project/(?P<pid>\d+)/layer/(?P<layerid>\d+)$',
- ToasterTemplateView.as_view(template_name='layerdetails.html'),
- name='layerdetails'),
url(r'^project/(?P<pid>\d+)/layer/$', lambda x,pid: HttpResponseBadRequest(), name='base_layerdetails'),
# the import layer is a project-specific functionality;
url(r'^project/(?P<pid>\d+)/importlayer$', 'importlayer', name='importlayer'),
+
+ # the table pages that have been converted to ToasterTable widget
url(r'^project/(?P<pid>\d+)/machines/$',
- ToasterTemplateView.as_view(template_name="generic-toastertable-page.html"),
+ tables.MachinesTable.as_view(template_name="generic-toastertable-page.html"),
{ 'table_name': tables.MachinesTable.__name__.lower(),
'title' : 'All compatible machines' },
name="all-machines"),
url(r'^project/(?P<pid>\d+)/recipes/$',
- ToasterTemplateView.as_view(template_name="generic-toastertable-page.html"),
+ tables.RecipesTable.as_view(template_name="generic-toastertable-page.html"),
{ 'table_name': tables.RecipesTable.__name__.lower(),
'title' : 'All compatible recipes' },
name="all-targets"),
url(r'^project/(?P<pid>\d+)/layers/$',
- ToasterTemplateView.as_view(template_name="generic-toastertable-page.html"),
+ tables.LayersTable.as_view(template_name="generic-toastertable-page.html"),
{ 'table_name': tables.LayersTable.__name__.lower(),
'title' : 'All compatible layers' },
name="all-layers"),
+ url(r'^project/(?P<pid>\d+)/layer/(?P<layerid>\d+)$',
+ tables.LayerDetails.as_view(template_name='layerdetails.html'),
+ name='layerdetails'),
+
+ url(r'^project/(?P<pid>\d+)/layer/(?P<layerid>\d+)/recipes/$',
+ tables.LayerRecipesTable.as_view(template_name="generic-toastertable-page.html"),
+ { 'table_name': tables.LayerRecipesTable.__name__.lower(),
+ 'title' : 'All recipes in layer' },
+ name=tables.LayerRecipesTable.__name__.lower()),
+
+ url(r'^project/(?P<pid>\d+)/layer/(?P<layerid>\d+)/machines/$',
+ tables.LayerMachinesTable.as_view(template_name="generic-toastertable-page.html"),
+ { 'table_name': tables.LayerMachinesTable.__name__.lower(),
+ 'title' : 'All machines in layer' },
+ name=tables.LayerMachinesTable.__name__.lower()),
url(r'^xhr_projectbuild/(?P<pid>\d+)$', 'xhr_projectbuild', name='xhr_projectbuild'),
url(r'^xhr_projectinfo/$', 'xhr_projectinfo', name='xhr_projectinfo'),
@@ -116,7 +129,6 @@ urlpatterns = patterns('toastergui.views',
url(r'^xhr_datatypeahead/(?P<pid>\d+)$', 'xhr_datatypeahead', name='xhr_datatypeahead'),
url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'),
url(r'^xhr_updatelayer/$', 'xhr_updatelayer', name='xhr_updatelayer'),
- url(r'^xhr_tables/project/(?P<pid>\d+)/', include('toastergui.tables')),
# dashboard for failed build requests
url(r'^project/(?P<pid>\d+)/buildrequest/(?P<brid>\d+)$', 'buildrequestdetails', name='buildrequestdetails'),
diff --git a/lib/toaster/toastergui/widgets.py b/lib/toaster/toastergui/widgets.py
index 8cf6e1bc2..4347a3f08 100644
--- a/lib/toaster/toastergui/widgets.py
+++ b/lib/toaster/toastergui/widgets.py
@@ -32,29 +32,17 @@ from django.core.serializers.json import DjangoJSONEncoder
from django.core.exceptions import FieldError
from django.conf.urls import url, patterns
-import urls
import types
import json
import collections
import operator
-class ToasterTemplateView(TemplateView):
- def get_context_data(self, **kwargs):
- context = super(ToasterTemplateView, self).get_context_data(**kwargs)
- if 'pid' in kwargs:
- context['project'] = Project.objects.get(pk=kwargs['pid'])
-
- context['projectlayers'] = map(lambda prjlayer: prjlayer.layercommit.id, ProjectLayer.objects.filter(project=context['project']))
-
- if 'layerid' in kwargs:
- context['layerversion'] = Layer_Version.objects.get(pk=kwargs['layerid'])
-
- return context
-
-
-class ToasterTable(View):
- def __init__(self):
+class ToasterTable(TemplateView):
+ def __init__(self, *args, **kwargs):
+ super(ToasterTable, self).__init__()
+ if 'template_name' in kwargs:
+ self.template_name = kwargs['template_name']
self.title = None
self.queryset = None
self.columns = []
@@ -66,20 +54,23 @@ class ToasterTable(View):
self.default_orderby = ""
def get(self, request, *args, **kwargs):
- self.setup_queryset(*args, **kwargs)
+ if request.GET.get('format', None) == 'json':
- # Put the project id into the context for the static_data_template
- if 'pid' in kwargs:
- self.static_context_extra['pid'] = kwargs['pid']
+ self.setup_queryset(*args, **kwargs)
+ # Put the project id into the context for the static_data_template
+ if 'pid' in kwargs:
+ self.static_context_extra['pid'] = kwargs['pid']
- cmd = kwargs['cmd']
- if cmd and 'filterinfo' in cmd:
- data = self.get_filter_info(request)
- else:
- # If no cmd is specified we give you the table data
- data = self.get_data(request, **kwargs)
+ cmd = request.GET.get('cmd', None)
+ if cmd and 'filterinfo' in cmd:
+ data = self.get_filter_info(request)
+ else:
+ # If no cmd is specified we give you the table data
+ data = self.get_data(request, **kwargs)
+
+ return HttpResponse(data, content_type="application/json")
- return HttpResponse(data, content_type="application/json")
+ return super(ToasterTable, self).get(request, *args, **kwargs)
def get_filter_info(self, request):
data = None