summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster
diff options
context:
space:
mode:
authorDavid Reyna <David.Reyna@windriver.com>2017-06-27 13:44:30 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-06-28 16:02:15 +0100
commit4f2baebf362d71351db044c0646f9bc6e8a39c49 (patch)
treebcbb07afbe24816f35d0c9d616ac5ea1fcca7f17 /bitbake/lib/toaster
parent43aaa802c35ecc9d972f3b9adcd060033de1d9de (diff)
downloadpoky-4f2baebf362d71351db044c0646f9bc6e8a39c49.tar.gz
bitbake: toaster: Add distro selection support
Add the ability to select a distro in the project page, based on values from the Layer Index. Add a distro selection page with the add layer feature, based on the add machine page. [YOCTO #10632] (Bitbake rev: a156a4eff67cdc3943494f5be72b96e3db656250) Signed-off-by: David Reyna <David.Reyna@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster')
-rw-r--r--bitbake/lib/toaster/orm/management/commands/lsupdates.py19
-rw-r--r--bitbake/lib/toaster/orm/migrations/0017_distro_clone.py25
-rw-r--r--bitbake/lib/toaster/orm/models.py31
-rw-r--r--bitbake/lib/toaster/toastergui/api.py13
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/projectpage.js73
-rw-r--r--bitbake/lib/toaster/toastergui/tables.py91
-rw-r--r--bitbake/lib/toaster/toastergui/templates/base.html1
-rw-r--r--bitbake/lib/toaster/toastergui/templates/baseprojectpage.html1
-rw-r--r--bitbake/lib/toaster/toastergui/templates/distro_btn.html20
-rw-r--r--bitbake/lib/toaster/toastergui/templates/project.html16
-rw-r--r--bitbake/lib/toaster/toastergui/typeaheads.py30
-rw-r--r--bitbake/lib/toaster/toastergui/urls.py8
12 files changed, 325 insertions, 3 deletions
diff --git a/bitbake/lib/toaster/orm/management/commands/lsupdates.py b/bitbake/lib/toaster/orm/management/commands/lsupdates.py
index 90f07c9dc5..0b0d4ff8f9 100644
--- a/bitbake/lib/toaster/orm/management/commands/lsupdates.py
+++ b/bitbake/lib/toaster/orm/management/commands/lsupdates.py
@@ -23,6 +23,7 @@ from django.core.management.base import BaseCommand
23 23
24from orm.models import LayerSource, Layer, Release, Layer_Version 24from orm.models import LayerSource, Layer, Release, Layer_Version
25from orm.models import LayerVersionDependency, Machine, Recipe 25from orm.models import LayerVersionDependency, Machine, Recipe
26from orm.models import Distro
26 27
27import os 28import os
28import sys 29import sys
@@ -249,6 +250,24 @@ class Command(BaseCommand):
249 depends_on=lvd) 250 depends_on=lvd)
250 self.mini_progress("Layer version dependencies", i, total) 251 self.mini_progress("Layer version dependencies", i, total)
251 252
253 # update Distros
254 logger.info("Fetching distro information")
255 distros_info = _get_json_response(
256 apilinks['distros'] + "?filter=layerbranch__branch__name:%s" %
257 "OR".join(whitelist_branch_names))
258
259 total = len(distros_info)
260 for i, di in enumerate(distros_info):
261 distro, created = Distro.objects.get_or_create(
262 name=di['name'],
263 layer_version=Layer_Version.objects.get(
264 pk=li_layer_branch_id_to_toaster_lv_id[di['layerbranch']]))
265 distro.up_date = di['updated']
266 distro.name = di['name']
267 distro.description = di['description']
268 distro.save()
269 self.mini_progress("distros", i, total)
270
252 # update machines 271 # update machines
253 logger.info("Fetching machine information") 272 logger.info("Fetching machine information")
254 machines_info = _get_json_response( 273 machines_info = _get_json_response(
diff --git a/bitbake/lib/toaster/orm/migrations/0017_distro_clone.py b/bitbake/lib/toaster/orm/migrations/0017_distro_clone.py
new file mode 100644
index 0000000000..d3c5901275
--- /dev/null
+++ b/bitbake/lib/toaster/orm/migrations/0017_distro_clone.py
@@ -0,0 +1,25 @@
1# -*- coding: utf-8 -*-
2from __future__ import unicode_literals
3
4from django.db import migrations, models
5
6class Migration(migrations.Migration):
7
8 dependencies = [
9 ('orm', '0016_clone_progress'),
10 ]
11
12 operations = [
13 migrations.CreateModel(
14 name='Distro',
15 fields=[
16 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
17 ('up_id', models.IntegerField(default=None, null=True)),
18 ('up_date', models.DateTimeField(default=None, null=True)),
19 ('name', models.CharField(max_length=255)),
20 ('description', models.CharField(max_length=255)),
21 ('layer_version', models.ForeignKey(to='orm.Layer_Version')),
22 ],
23 ),
24 ]
25
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 13bd11704a..5c14727a70 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -321,6 +321,22 @@ class Project(models.Model):
321 321
322 return queryset 322 return queryset
323 323
324 def get_available_distros(self):
325 """ Returns QuerySet of all Distros which are provided by the
326 Layers currently added to the Project """
327 queryset = Distro.objects.filter(
328 layer_version__in=self.get_project_layer_versions())
329
330 return queryset
331
332 def get_all_compatible_distros(self):
333 """ Returns QuerySet of all the compatible Wind River distros available to the
334 project including ones from Layers not currently added """
335 queryset = Distro.objects.filter(
336 layer_version__in=self.get_all_compatible_layer_versions())
337
338 return queryset
339
324 def get_available_recipes(self): 340 def get_available_recipes(self):
325 """ Returns QuerySet of all the recipes that are provided by layers 341 """ Returns QuerySet of all the recipes that are provided by layers
326 added to this project """ 342 added to this project """
@@ -1795,6 +1811,21 @@ def signal_runbuilds():
1795 except FileNotFoundError: 1811 except FileNotFoundError:
1796 logger.info("Stopping existing runbuilds: no current process found") 1812 logger.info("Stopping existing runbuilds: no current process found")
1797 1813
1814class Distro(models.Model):
1815 search_allowed_fields = ["name", "description", "layer_version__layer__name"]
1816 up_date = models.DateTimeField(null = True, default = None)
1817
1818 layer_version = models.ForeignKey('Layer_Version')
1819 name = models.CharField(max_length=255)
1820 description = models.CharField(max_length=255)
1821
1822 def get_vcs_distro_file_link_url(self):
1823 path = self.name+'.conf'
1824 return self.layer_version.get_vcs_file_link_url(path)
1825
1826 def __unicode__(self):
1827 return "Distro " + self.name + "(" + self.description + ")"
1828
1798django.db.models.signals.post_save.connect(invalidate_cache) 1829django.db.models.signals.post_save.connect(invalidate_cache)
1799django.db.models.signals.post_delete.connect(invalidate_cache) 1830django.db.models.signals.post_delete.connect(invalidate_cache)
1800django.db.models.signals.m2m_changed.connect(invalidate_cache) 1831django.db.models.signals.m2m_changed.connect(invalidate_cache)
diff --git a/bitbake/lib/toaster/toastergui/api.py b/bitbake/lib/toaster/toastergui/api.py
index 5b035505c2..88d6aa7f68 100644
--- a/bitbake/lib/toaster/toastergui/api.py
+++ b/bitbake/lib/toaster/toastergui/api.py
@@ -874,6 +874,12 @@ class XhrProject(View):
874 machinevar.value = request.POST['machineName'] 874 machinevar.value = request.POST['machineName']
875 machinevar.save() 875 machinevar.save()
876 876
877 # Distro name change
878 if 'distroName' in request.POST:
879 distrovar = prj.projectvariable_set.get(name="DISTRO")
880 distrovar.value = request.POST['distroName']
881 distrovar.save()
882
877 return JsonResponse({"error": "ok"}) 883 return JsonResponse({"error": "ok"})
878 884
879 def get(self, request, *args, **kwargs): 885 def get(self, request, *args, **kwargs):
@@ -960,10 +966,11 @@ class XhrProject(View):
960 except ProjectVariable.DoesNotExist: 966 except ProjectVariable.DoesNotExist:
961 data["machine"] = None 967 data["machine"] = None
962 try: 968 try:
963 data["distro"] = project.projectvariable_set.get( 969 data["distro"] = {"name":
964 name="DISTRO").value 970 project.projectvariable_set.get(
971 name="DISTRO").value}
965 except ProjectVariable.DoesNotExist: 972 except ProjectVariable.DoesNotExist:
966 data["distro"] = "-- not set yet" 973 data["distro"] = None
967 974
968 data['error'] = "ok" 975 data['error'] = "ok"
969 976
diff --git a/bitbake/lib/toaster/toastergui/static/js/projectpage.js b/bitbake/lib/toaster/toastergui/static/js/projectpage.js
index 21adf816c6..506471e091 100644
--- a/bitbake/lib/toaster/toastergui/static/js/projectpage.js
+++ b/bitbake/lib/toaster/toastergui/static/js/projectpage.js
@@ -15,6 +15,13 @@ function projectPageInit(ctx) {
15 var machineInputForm = $("#machine-input-form"); 15 var machineInputForm = $("#machine-input-form");
16 var invalidMachineNameHelp = $("#invalid-machine-name-help"); 16 var invalidMachineNameHelp = $("#invalid-machine-name-help");
17 17
18 var distroChangeInput = $("#distro-change-input");
19 var distroChangeBtn = $("#distro-change-btn");
20 var distroForm = $("#select-distro-form");
21 var distroChangeFormToggle = $("#change-distro-toggle");
22 var distroNameTitle = $("#project-distro-name");
23 var distroChangeCancel = $("#cancel-distro-change");
24
18 var freqBuildBtn = $("#freq-build-btn"); 25 var freqBuildBtn = $("#freq-build-btn");
19 var freqBuildList = $("#freq-build-list"); 26 var freqBuildList = $("#freq-build-list");
20 27
@@ -26,6 +33,7 @@ function projectPageInit(ctx) {
26 33
27 var currentLayerAddSelection; 34 var currentLayerAddSelection;
28 var currentMachineAddSelection = ""; 35 var currentMachineAddSelection = "";
36 var currentDistroAddSelection = "";
29 37
30 var urlParams = libtoaster.parseUrlParams(); 38 var urlParams = libtoaster.parseUrlParams();
31 39
@@ -45,6 +53,17 @@ function projectPageInit(ctx) {
45 updateMachineName(prjInfo.machine.name); 53 updateMachineName(prjInfo.machine.name);
46 } 54 }
47 55
56 /* If we're receiving a distro set from the url and it's different from
57 * our current distro then activate set machine sequence.
58 */
59 if (urlParams.hasOwnProperty('setDistro') &&
60 urlParams.setDistro !== prjInfo.distro.name){
61 distroChangeInput.val(urlParams.setDistro);
62 distroChangeBtn.click();
63 } else {
64 updateDistroName(prjInfo.distro.name);
65 }
66
48 /* Now we're really ready show the page */ 67 /* Now we're really ready show the page */
49 $("#project-page").show(); 68 $("#project-page").show();
50 69
@@ -278,6 +297,60 @@ function projectPageInit(ctx) {
278 }); 297 });
279 298
280 299
300 /* Change distro functionality */
301
302 distroChangeFormToggle.click(function(){
303 distroForm.slideDown();
304 distroNameTitle.hide();
305 $(this).hide();
306 });
307
308 distroChangeCancel.click(function(){
309 distroForm.slideUp(function(){
310 distroNameTitle.show();
311 distroChangeFormToggle.show();
312 });
313 });
314
315 function updateDistroName(distroName){
316 distroChangeInput.val(distroName);
317 distroNameTitle.text(distroName);
318 }
319
320 libtoaster.makeTypeahead(distroChangeInput,
321 libtoaster.ctx.distrosTypeAheadUrl,
322 { }, function(item){
323 currentDistroAddSelection = item.name;
324 distroChangeBtn.removeAttr("disabled");
325 });
326
327 distroChangeBtn.click(function(e){
328 e.preventDefault();
329 /* We accept any value regardless of typeahead selection or not */
330 if (distroChangeInput.val().length === 0)
331 return;
332
333 currentDistroAddSelection = distroChangeInput.val();
334
335 libtoaster.editCurrentProject(
336 { distroName : currentDistroAddSelection },
337 function(){
338 /* Success machine changed */
339 updateDistroName(currentDistroAddSelection);
340 distroChangeCancel.click();
341
342 /* Show the alert message */
343 var message = $('<span>You have changed the distro to: <strong><span id="notify-machine-name"></span></strong></span>');
344 message.find("#notify-machine-name").text(currentDistroAddSelection);
345 libtoaster.showChangeNotification(message);
346 },
347 function(){
348 /* Failed machine changed */
349 console.warn("Failed to change distro");
350 });
351 });
352
353
281 /* Change release functionality */ 354 /* Change release functionality */
282 function updateProjectRelease(release){ 355 function updateProjectRelease(release){
283 releaseTitle.text(release.description); 356 releaseTitle.text(release.description);
diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py
index e2d23c1e81..dca2fa2913 100644
--- a/bitbake/lib/toaster/toastergui/tables.py
+++ b/bitbake/lib/toaster/toastergui/tables.py
@@ -23,6 +23,7 @@ from toastergui.widgets import ToasterTable
23from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project 23from orm.models import Recipe, ProjectLayer, Layer_Version, Machine, Project
24from orm.models import CustomImageRecipe, Package, Target, Build, LogMessage, Task 24from orm.models import CustomImageRecipe, Package, Target, Build, LogMessage, Task
25from orm.models import CustomImagePackage, Package_DependencyManager 25from orm.models import CustomImagePackage, Package_DependencyManager
26from orm.models import Distro
26from django.db.models import Q, Max, Sum, Count, When, Case, Value, IntegerField 27from django.db.models import Q, Max, Sum, Count, When, Case, Value, IntegerField
27from django.conf.urls import url 28from django.conf.urls import url
28from django.core.urlresolvers import reverse, resolve 29from django.core.urlresolvers import reverse, resolve
@@ -1536,3 +1537,93 @@ class ProjectBuildsTable(BuildsTable):
1536 context['build_in_progress_none_completed'] = False 1537 context['build_in_progress_none_completed'] = False
1537 1538
1538 return context 1539 return context
1540
1541
1542class DistrosTable(ToasterTable):
1543 """Table of Distros in Toaster"""
1544
1545 def __init__(self, *args, **kwargs):
1546 super(DistrosTable, self).__init__(*args, **kwargs)
1547 self.empty_state = "Toaster has no distro information for this project. Sadly, distro information cannot be obtained from builds, so this page will remain empty."
1548 self.title = "Compatible Distros"
1549 self.default_orderby = "name"
1550
1551 def get_context_data(self, **kwargs):
1552 context = super(DistrosTable, self).get_context_data(**kwargs)
1553 context['project'] = Project.objects.get(pk=kwargs['pid'])
1554 return context
1555
1556 def setup_filters(self, *args, **kwargs):
1557 project = Project.objects.get(pk=kwargs['pid'])
1558
1559 in_current_project_filter = TableFilter(
1560 "in_current_project",
1561 "Filter by project Distros"
1562 )
1563
1564 in_project_action = TableFilterActionToggle(
1565 "in_project",
1566 "Distro provided by layers added to this project",
1567 ProjectFilters.in_project(self.project_layers)
1568 )
1569
1570 not_in_project_action = TableFilterActionToggle(
1571 "not_in_project",
1572 "Distros provided by layers not added to this project",
1573 ProjectFilters.not_in_project(self.project_layers)
1574 )
1575
1576 in_current_project_filter.add_action(in_project_action)
1577 in_current_project_filter.add_action(not_in_project_action)
1578 self.add_filter(in_current_project_filter)
1579
1580 def setup_queryset(self, *args, **kwargs):
1581 prj = Project.objects.get(pk = kwargs['pid'])
1582 self.queryset = prj.get_all_compatible_distros()
1583 self.queryset = self.queryset.order_by(self.default_orderby)
1584
1585 self.static_context_extra['current_layers'] = \
1586 self.project_layers = \
1587 prj.get_project_layer_versions(pk=True)
1588
1589 def setup_columns(self, *args, **kwargs):
1590
1591 self.add_column(title="Distro",
1592 hideable=False,
1593 orderable=True,
1594 field_name="name")
1595
1596 self.add_column(title="Description",
1597 field_name="description")
1598
1599 layer_link_template = '''
1600 <a href="{% url 'layerdetails' extra.pid data.layer_version.id %}">
1601 {{data.layer_version.layer.name}}</a>
1602 '''
1603
1604 self.add_column(title="Layer",
1605 static_data_name="layer_version__layer__name",
1606 static_data_template=layer_link_template,
1607 orderable=True)
1608
1609 self.add_column(title="Git revision",
1610 help_text="The Git branch, tag or commit. For the layers from the OpenEmbedded layer source, the revision is always the branch compatible with the Yocto Project version you selected for this project",
1611 hidden=True,
1612 field_name="layer_version__get_vcs_reference")
1613
1614 wrtemplate_file_template = '''<code>conf/machine/{{data.name}}.conf</code>
1615 <a href="{{data.get_vcs_machine_file_link_url}}" target="_blank"><span class="glyphicon glyphicon-new-window"></i></a>'''
1616
1617 self.add_column(title="Distro file",
1618 hidden=True,
1619 static_data_name="templatefile",
1620 static_data_template=wrtemplate_file_template)
1621
1622
1623 self.add_column(title="Select",
1624 help_text="Sets the selected distro to the project",
1625 hideable=False,
1626 filter_name="in_current_project",
1627 static_data_name="add-del-layers",
1628 static_data_template='{% include "distro_btn.html" %}')
1629
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index 11c6f91260..0fbe17b5d8 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -49,6 +49,7 @@
49 recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}}, 49 recipesTypeAheadUrl: {% url 'xhr_recipestypeahead' project.id as paturl%}{{paturl|json}},
50 layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}}, 50 layersTypeAheadUrl: {% url 'xhr_layerstypeahead' project.id as paturl%}{{paturl|json}},
51 machinesTypeAheadUrl: {% url 'xhr_machinestypeahead' project.id as paturl%}{{paturl|json}}, 51 machinesTypeAheadUrl: {% url 'xhr_machinestypeahead' project.id as paturl%}{{paturl|json}},
52 distrosTypeAheadUrl: {% url 'xhr_distrostypeahead' project.id as paturl%}{{paturl|json}},
52 projectBuildsUrl: {% url 'projectbuilds' project.id as pburl %}{{pburl|json}}, 53 projectBuildsUrl: {% url 'projectbuilds' project.id as pburl %}{{pburl|json}},
53 xhrCustomRecipeUrl : "{% url 'xhr_customrecipe' %}", 54 xhrCustomRecipeUrl : "{% url 'xhr_customrecipe' %}",
54 projectId : {{project.id}}, 55 projectId : {{project.id}},
diff --git a/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html b/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
index 8427d25210..f2bb2ebf63 100644
--- a/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
+++ b/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
@@ -32,6 +32,7 @@ $(document).ready(function(){
32 <li><a href="{% url 'projectsoftwarerecipes' project.id %}">Software recipes</a></li> 32 <li><a href="{% url 'projectsoftwarerecipes' project.id %}">Software recipes</a></li>
33 <li><a href="{% url 'projectmachines' project.id %}">Machines</a></li> 33 <li><a href="{% url 'projectmachines' project.id %}">Machines</a></li>
34 <li><a href="{% url 'projectlayers' project.id %}">Layers</a></li> 34 <li><a href="{% url 'projectlayers' project.id %}">Layers</a></li>
35 <li><a href="{% url 'projectdistros' project.id %}">Distros</a></li>
35 <li class="nav-header">Extra configuration</li> 36 <li class="nav-header">Extra configuration</li>
36 <li><a href="{% url 'projectconf' project.id %}">BitBake variables</a></li> 37 <li><a href="{% url 'projectconf' project.id %}">BitBake variables</a></li>
37 38
diff --git a/bitbake/lib/toaster/toastergui/templates/distro_btn.html b/bitbake/lib/toaster/toastergui/templates/distro_btn.html
new file mode 100644
index 0000000000..fac79472cc
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/templates/distro_btn.html
@@ -0,0 +1,20 @@
1<a href="{% url 'project' extra.pid %}?setDistro={{data.name}}" class="btn btn-default btn-block layer-exists-{{data.layer_version.id}}"
2 {% if data.layer_version.pk not in extra.current_layers %}
3 style="display:none;"
4 {% endif %}>
5 Set distro</a>
6<a class="btn btn-default btn-block layerbtn layer-add-{{data.layer_version.id}}" data-layer='{
7 "id": {{data.layer_version.id}},
8 "name": "{{data.layer_version.layer.name}}",
9 "xhrLayerUrl": "{% url "xhr_layer" extra.pid data.pk %}",
10 "layerdetailurl": "{%url 'layerdetails' extra.pid data.layer_version.id %}"
11 }' data-directive="add"
12 {% if data.layer_version.pk in extra.current_layers %}
13 style="display:none;"
14 {% endif %}
15>
16 <span class="glyphicon glyphicon-plus"></span>
17 Add layer
18 <span class="glyphicon glyphicon-question-sign get-help" title="To select this distro, you must first add the {{data.layer_version.layer.name}} layer to your project"></i>
19</a>
20
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html
index ab7e665b64..11603d1e12 100644
--- a/bitbake/lib/toaster/toastergui/templates/project.html
+++ b/bitbake/lib/toaster/toastergui/templates/project.html
@@ -77,6 +77,22 @@
77 </form> 77 </form>
78 </div> 78 </div>
79 79
80 <div class="well well-transparent" id="distro-section">
81 <h3>Distro</h3>
82
83 <p class="lead"><span id="project-distro-name"></span> <span class="glyphicon glyphicon-edit" id="change-distro-toggle"></span></p>
84
85 <form id="select-distro-form" style="display:none;" class="form-inline">
86 <span class="help-block">Distro suggestions come from the Layer Index</a></span>
87 <div class="form-group">
88 <input class="form-control" id="distro-change-input" autocomplete="off" value="" data-provide="typeahead" data-minlength="1" data-autocomplete="off" type="text">
89 </div>
90 <button id="distro-change-btn" class="btn btn-default" type="button">Save</button>
91 <a href="#" id="cancel-distro-change" class="btn btn-link">Cancel</a>
92 <p class="form-link"><a href="{% url 'projectdistros' project.id %}">View compatible distros</a></p>
93 </form>
94 </div>
95
80 <div class="well well-transparent"> 96 <div class="well well-transparent">
81 <h3>Most built recipes</h3> 97 <h3>Most built recipes</h3>
82 98
diff --git a/bitbake/lib/toaster/toastergui/typeaheads.py b/bitbake/lib/toaster/toastergui/typeaheads.py
index 58c650f8fc..5aa0f8d889 100644
--- a/bitbake/lib/toaster/toastergui/typeaheads.py
+++ b/bitbake/lib/toaster/toastergui/typeaheads.py
@@ -100,6 +100,36 @@ class MachinesTypeAhead(ToasterTypeAhead):
100 return results 100 return results
101 101
102 102
103class DistrosTypeAhead(ToasterTypeAhead):
104 """ Typeahead for all the distros available in the current project's
105 configuration """
106 def __init__(self):
107 super(DistrosTypeAhead, self).__init__()
108
109 def apply_search(self, search_term, prj, request):
110 distros = prj.get_available_distros()
111 distros = distros.order_by("name")
112
113 primary_results = distros.filter(name__istartswith=search_term)
114 secondary_results = distros.filter(name__icontains=search_term).exclude(pk__in=primary_results)
115 tertiary_results = distros.filter(layer_version__layer__name__icontains=search_term).exclude(pk__in=primary_results).exclude(pk__in=secondary_results)
116
117 results = []
118
119 for distro in list(primary_results) + list(secondary_results) + list(tertiary_results):
120
121 detail = "[ %s ]" % (distro.layer_version.layer.name)
122 needed_fields = {
123 'id' : distro.pk,
124 'name' : distro.name,
125 'detail' : detail,
126 }
127
128 results.append(needed_fields)
129
130 return results
131
132
103class RecipesTypeAhead(ToasterTypeAhead): 133class RecipesTypeAhead(ToasterTypeAhead):
104 """ Typeahead for all the recipes available in the current project's 134 """ Typeahead for all the recipes available in the current project's
105 configuration """ 135 configuration """
diff --git a/bitbake/lib/toaster/toastergui/urls.py b/bitbake/lib/toaster/toastergui/urls.py
index 1ad79a4dd3..6aebc3f833 100644
--- a/bitbake/lib/toaster/toastergui/urls.py
+++ b/bitbake/lib/toaster/toastergui/urls.py
@@ -158,6 +158,11 @@ urlpatterns = [
158 name=tables.LayerMachinesTable.__name__.lower()), 158 name=tables.LayerMachinesTable.__name__.lower()),
159 159
160 160
161 url(r'^project/(?P<pid>\d+)/distros/$',
162 tables.DistrosTable.as_view(template_name="generic-toastertable-page.html"),
163 name="projectdistros"),
164
165
161 url(r'^project/(?P<pid>\d+)/customrecipe/(?P<custrecipeid>\d+)/selectpackages/$', 166 url(r'^project/(?P<pid>\d+)/customrecipe/(?P<custrecipeid>\d+)/selectpackages/$',
162 tables.SelectPackagesTable.as_view(), name="recipeselectpackages"), 167 tables.SelectPackagesTable.as_view(), name="recipeselectpackages"),
163 168
@@ -187,6 +192,9 @@ urlpatterns = [
187 typeaheads.GitRevisionTypeAhead.as_view(), 192 typeaheads.GitRevisionTypeAhead.as_view(),
188 name='xhr_gitrevtypeahead'), 193 name='xhr_gitrevtypeahead'),
189 194
195 url(r'^xhr_typeahead/(?P<pid>\d+)/distros$',
196 typeaheads.DistrosTypeAhead.as_view(), name='xhr_distrostypeahead'),
197
190 url(r'^xhr_testreleasechange/(?P<pid>\d+)$', views.xhr_testreleasechange, 198 url(r'^xhr_testreleasechange/(?P<pid>\d+)$', views.xhr_testreleasechange,
191 name='xhr_testreleasechange'), 199 name='xhr_testreleasechange'),
192 url(r'^xhr_configvaredit/(?P<pid>\d+)$', views.xhr_configvaredit, 200 url(r'^xhr_configvaredit/(?P<pid>\d+)$', views.xhr_configvaredit,