summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2014-08-29 16:41:59 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-09-01 08:51:32 +0100
commitacd4a1799d51a9f0b192d12b2c58387595b27bf7 (patch)
tree194260d1e025db5cfb94662c81fbef2488f1798e /bitbake
parentfd0398f2c1355597a95242e6c8400eae6ad60fa4 (diff)
downloadpoky-acd4a1799d51a9f0b192d12b2c58387595b27bf7.tar.gz
bitbake: toaster: add project pages for machines, targets, layers
We add new pages for the all-machines and all-targets project-related views. We update the existing template structure to create a base project view, similar to a base build view, that includes a breadcrumb. Updating existing all layers view to use the new structure. We update methods in the models to provide corrent information display. [YOCTO #6592] [YOCTO #6593] (Bitbake rev: 973f582a19441c1ec67061160e4c50ce03ed7b68) Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/toaster/orm/models.py131
-rw-r--r--[-rwxr-xr-x]bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html0
-rw-r--r--bitbake/lib/toaster/toastergui/templates/baseprojectpage.html43
-rw-r--r--[-rwxr-xr-x]bitbake/lib/toaster/toastergui/templates/layers.html9
-rw-r--r--bitbake/lib/toaster/toastergui/templates/machines.html63
-rw-r--r--bitbake/lib/toaster/toastergui/templates/project.html69
-rw-r--r--[-rwxr-xr-x]bitbake/lib/toaster/toastergui/templates/recipes.html0
-rw-r--r--bitbake/lib/toaster/toastergui/templates/targets.html186
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py173
9 files changed, 559 insertions, 115 deletions
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index bb921fc98e..77afe35861 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -402,6 +402,18 @@ class Recipe(models.Model):
402 bugtracker = models.URLField(blank=True) 402 bugtracker = models.URLField(blank=True)
403 file_path = models.FilePathField(max_length=255) 403 file_path = models.FilePathField(max_length=255)
404 404
405 def get_vcs_link_url(self):
406 if self.layer_version.layer.vcs_web_file_base_url is None:
407 return ""
408 return self.layer_version.layer.vcs_web_file_base_url.replace('%path%', self.file_path).replace('%branch%', self.layer_version.up_branch.name)
409
410 def get_layersource_view_url(self):
411 if self.layer_source is None:
412 return ""
413
414 url = self.layer_source.get_object_view(self.layer_version.up_branch, "recipes", self.name)
415 return url
416
405 def __unicode__(self): 417 def __unicode__(self):
406 return "Recipe " + self.name + ":" + self.version 418 return "Recipe " + self.name + ":" + self.version
407 419
@@ -508,6 +520,11 @@ class LayerIndexLayerSource(LayerSource):
508 super(LayerIndexLayerSource, self).__init__(args, kwargs) 520 super(LayerIndexLayerSource, self).__init__(args, kwargs)
509 self.sourcetype = LayerSource.TYPE_LAYERINDEX 521 self.sourcetype = LayerSource.TYPE_LAYERINDEX
510 522
523 def get_object_view(self, branch, objectype, upid):
524 if self != branch.layer_source:
525 raise Exception("Invalid branch specification")
526 return self.apiurl + "../branch/" + branch.name + "/" + objectype + "/?q=" + str(upid)
527
511 def update(self): 528 def update(self):
512 ''' 529 '''
513 Fetches layer, recipe and machine information from remote repository 530 Fetches layer, recipe and machine information from remote repository
@@ -538,99 +555,79 @@ class LayerIndexLayerSource(LayerSource):
538 return 555 return
539 556
540 # update branches; only those that we already have names listed in the database 557 # update branches; only those that we already have names listed in the database
541 whitelist_branch_names = self.branchnames.split(",") 558 whitelist_branch_names = map(lambda x: x.name, Branch.objects.all())
542 559
543 branches_info = _get_json_response(apilinks['branches'] 560 branches_info = _get_json_response(apilinks['branches']
544 + "?filter=name:%s" % "OR".join(whitelist_branch_names)) 561 + "?filter=name:%s" % "OR".join(whitelist_branch_names))
545 for bi in branches_info: 562 for bi in branches_info:
546 try: 563 b, created = Branch.objects.get_or_create(layer_source = self, name = bi['name'])
547 b = Branch.objects.get(layer_source = self, name = bi['name']) 564 b.up_id = bi['id']
548 b.up_id = bi['id'] 565 b.up_date = bi['updated']
549 b.up_date = bi['updated'] 566 b.name = bi['name']
550 b.name = bi['name'] 567 b.bitbake_branch = bi['bitbake_branch']
551 b.bitbake_branch = bi['bitbake_branch'] 568 b.short_description = bi['short_description']
552 b.short_description = bi['short_description'] 569 b.save()
553 b.save()
554 except Branch.DoesNotExist:
555 b = Branch.objects.create(
556 layer_source = self,
557 up_id = bi['id'],
558 up_date = bi['updated'],
559 name = bi['name'],
560 bitbake_branch = bi['bitbake_branch'],
561 short_description = bi['short_description']
562 )
563 570
564 # update layers 571 # update layers
565 layers_info = _get_json_response(apilinks['layerItems']) 572 layers_info = _get_json_response(apilinks['layerItems'])
566 for li in layers_info: 573 for li in layers_info:
567 try: 574 l, created = Layer.objects.get_or_create(layer_source = self, up_id = li['id'])
568 l = Layer.objects.get(layer_source = self, 575 l.up_date = li['updated']
569 up_id = li['id']) 576 l.name = li['name']
570 l.update( 577 l.vcs_url = li['vcs_url']
571 up_date = li['updated'], 578 l.vcs_web_file_base_url = li['vcs_web_file_base_url']
572 name = li['name'], 579 l.summary = li['summary']
573 vcs_url = li['vcs_url'], 580 l.description = li['description']
574 vcs_web_file_base_url = li['vcs_url'], 581 l.save()
575 summary = li['summary'],
576 description = li['description'])
577 except Layer.DoesNotExist:
578 Layer.objects.create(layer_source = self,
579 up_id = li['id'],
580 up_date = li['updated'],
581 name = li['name'],
582 vcs_url = li['vcs_url'],
583 vcs_web_file_base_url = li['vcs_url'],
584 summary = li['summary'],
585 description = li['description']
586 )
587 582
588 # update layerbranches/layer_versions 583 # update layerbranches/layer_versions
589 layerbranches_info = _get_json_response(apilinks['layerBranches'] 584 layerbranches_info = _get_json_response(apilinks['layerBranches']
590 + "?filter=branch:%s" % "OR".join(map(lambda x: str(x.up_id), Branch.objects.filter(layer_source = self))) 585 + "?filter=branch:%s" % "OR".join(map(lambda x: str(x.up_id), Branch.objects.filter(layer_source = self)))
591 ) 586 )
592 for lbi in layerbranches_info: 587 for lbi in layerbranches_info:
593 Layer_Version.objects.get_or_create(layer_source = self, 588 lv, created = Layer_Version.objects.get_or_create(layer_source = self, up_id = lbi['id'])
594 up_id = lbi['id'], 589
595 up_date = lbi['updated'], 590 lv.up_date = lbi['updated']
596 layer = Layer.objects.get(layer_source = self, up_id = lbi['layer']), 591 lv.layer = Layer.objects.get(layer_source = self, up_id = lbi['layer'])
597 up_branch = Branch.objects.get(layer_source = self, up_id = lbi['branch']), 592 lv.up_branch = Branch.objects.get(layer_source = self, up_id = lbi['branch'])
598 branch = lbi['actual_branch'], 593 lv.branch = lbi['actual_branch']
599 commit = lbi['vcs_last_rev'], 594 lv.commit = lbi['vcs_last_rev']
600 dirpath = lbi['vcs_subdir']) 595 lv.dirpath = lbi['vcs_subdir']
596 lv.save()
597
601 598
602 # update machines 599 # update machines
603 machines_info = _get_json_response(apilinks['machines'] 600 machines_info = _get_json_response(apilinks['machines']
604 + "?filter=layerbranch:%s" % "OR".join(map(lambda x: str(x.up_id), Layer_Version.objects.filter(layer_source = self))) 601 + "?filter=layerbranch:%s" % "OR".join(map(lambda x: str(x.up_id), Layer_Version.objects.filter(layer_source = self)))
605 ) 602 )
606 for mi in machines_info: 603 for mi in machines_info:
607 Machine.objects.get_or_create(layer_source = self, 604 mo, created = Machine.objects.get_or_create(layer_source = self, up_id = mi['id'])
608 up_id = mi['id'], 605 mo.up_date = mi['updated']
609 up_date = mi['updated'], 606 mo.layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch'])
610 layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch']), 607 mo.name = mi['name']
611 name = mi['name'], 608 mo.description = mi['description']
612 description = mi['description']) 609 mo.save()
613 610
614 # update recipes; paginate by layer version / layer branch 611 # update recipes; paginate by layer version / layer branch
615 recipes_info = _get_json_response(apilinks['recipes'] 612 recipes_info = _get_json_response(apilinks['recipes']
616 + "?filter=layerbranch:%s" % "OR".join(map(lambda x: str(x.up_id), Layer_Version.objects.filter(layer_source = self))) 613 + "?filter=layerbranch:%s" % "OR".join(map(lambda x: str(x.up_id), Layer_Version.objects.filter(layer_source = self)))
617 ) 614 )
618 for ri in recipes_info: 615 for ri in recipes_info:
619 Recipe.objects.get_or_create(layer_source = self, 616 ro, created = Recipe.objects.get_or_create(layer_source = self, up_id = ri['id'])
620 up_id = ri['id'], 617
621 up_date = ri['updated'], 618 ro.up_date = ri['updated']
622 layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch']), 619 ro.layer_version = Layer_Version.objects.get(layer_source = self, up_id = mi['layerbranch'])
623 620
624 name = ri['pn'], 621 ro.name = ri['pn']
625 version = ri['pv'], 622 ro.version = ri['pv']
626 summary = ri['summary'], 623 ro.summary = ri['summary']
627 description = ri['description'], 624 ro.description = ri['description']
628 section = ri['section'], 625 ro.section = ri['section']
629 license = ri['license'], 626 ro.license = ri['license']
630 homepage = ri['homepage'], 627 ro.homepage = ri['homepage']
631 bugtracker = ri['bugtracker'], 628 ro.bugtracker = ri['bugtracker']
632 file_path = ri['filepath'] + ri['filename'] 629 ro.file_path = ri['filepath'] + ri['filename']
633 ) 630 ro.save()
634 631
635 pass 632 pass
636 633
diff --git a/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html b/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html
index 5149768517..5149768517 100755..100644
--- a/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html
+++ b/bitbake/lib/toaster/toastergui/templates/basebuilddetailpage.html
diff --git a/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html b/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
new file mode 100644
index 0000000000..54edaaf27c
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/templates/baseprojectpage.html
@@ -0,0 +1,43 @@
1{% extends "base.html" %}
2{% load projecttags %}
3{% load humanize %}
4{% block pagecontent %}
5
6
7 <div class="">
8<!-- Breadcrumbs -->
9 <div class="section">
10 <ul class="breadcrumb" id="breadcrumb">
11 <li><a href="{% url 'all-builds' %}">All builds</a></li>
12 {% block parentbreadcrumb %}
13 {% if project %}
14 <li>
15 <a href="{%url 'project' project.id %}">{{project.name}}
16 </a>
17 </li>
18 {% endif %}
19 {% endblock %}
20 {% block localbreadcrumb %}{% endblock %}
21 </ul>
22 <script>
23 $( function () {
24 $('#breadcrumb > li').append("<span class=\"divider\">→</span>");
25 $('#breadcrumb > li:last').addClass("active");
26 $('#breadcrumb > li:last > span').remove();
27 });
28 </script>
29 </div>
30
31 <div class="row-fluid">
32
33 <!-- Begin right container -->
34 {% block projectinfomain %}{% endblock %}
35 <!-- End right container -->
36
37
38 </div>
39 </div>
40
41
42{% endblock %}
43
diff --git a/bitbake/lib/toaster/toastergui/templates/layers.html b/bitbake/lib/toaster/toastergui/templates/layers.html
index d7d159e1e6..bc6e5a3073 100755..100644
--- a/bitbake/lib/toaster/toastergui/templates/layers.html
+++ b/bitbake/lib/toaster/toastergui/templates/layers.html
@@ -1,7 +1,12 @@
1{% extends "base.html" %} 1{% extends "baseprojectpage.html" %}
2{% load projecttags %} 2{% load projecttags %}
3{% load humanize %} 3{% load humanize %}
4{% block pagecontent %} 4
5{% block localbreadcrumb %}
6<li>Layers</li>
7{% endblock %}
8
9{% block projectinfomain %}
5 <div class="page-header"> 10 <div class="page-header">
6 <h1> 11 <h1>
7 All layers 12 All layers
diff --git a/bitbake/lib/toaster/toastergui/templates/machines.html b/bitbake/lib/toaster/toastergui/templates/machines.html
new file mode 100644
index 0000000000..18e7485d50
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/templates/machines.html
@@ -0,0 +1,63 @@
1{% extends "baseprojectpage.html" %}
2{% load projecttags %}
3{% load humanize %}
4
5{% block localbreadcrumb %}
6<li>Machines</li>
7{% endblock %}
8
9{% block projectinfomain %}
10 <div class="page-header">
11 <h1>
12 All machines
13 <i class="icon-question-sign get-help heading-help" title="This page lists all the machines compatible with Yocto Project 1.7 'Dxxxx' that Toaster knows about. They include community-created targets suitable for use on top of OpenEmbedded Core and any targets you have imported"></i>
14 </h1>
15 </div>
16 <!--div class="alert">
17 <div class="input-append" style="margin-bottom:0px;">
18 <input class="input-xxlarge" type="text" placeholder="Search targets" value="browser" />
19 <a class="add-on btn">
20 <i class="icon-remove"></i>
21 </a>
22 <button class="btn" type="button">Search</button>
23 <a class="btn btn-link" href="#">Show all targets</a>
24 </div>
25 </div-->
26 <div id="target-added" class="alert alert-info lead" style="display:none;"></div>
27 <div id="target-removed" class="alert alert-info lead" style="display:none;">
28 <button type="button" class="close" data-dismiss="alert">&times;</button>
29 <strong>1</strong> target deleted from <a href="project-with-targets.html">your project</a>: <a href="#">meta-aarch64</a>
30 </div>
31
32
33{% include "basetable_top.html" %}
34 {% for o in objects %}
35 <tr class="data">
36 <td class="machine">
37 {{o.name}}
38 <a machine="_blank" href="http://layers.openembedded.org/layerindex/branch/master/machines/?q=3g-router-image"><i class="icon-share get-info"></i></a>
39 </td>
40 <td class="description">{{o.description}}</td>
41 <td class="machine-file">
42 <code>{{o.file_path}}</code>
43 <a href="http://github.com/embeddedgeeks/meta-embeddedgeeks/blob/master/machines-core/images/3g-router-image.bb" machine="_blank"><i class="icon-share get-info"></i></a>
44 </td>
45 <td class="layer"><a href="#">{{o.layer_version.layer.name}}</a></td>
46 <td class="source">{{o.layer_source.name}}</td>
47 <td class="branch">{{o.layer_version.commit}}</td>
48 <td class="build">
49 <a id="build-machine" href="project-with-machines.html?machine=3g-router-image" class="btn btn-block" style="display:none;">
50 Build machine
51 </a>
52 <a id="add-layer" href="#" class="btn btn-block nopop" title="1 layer added">
53 <i class="icon-plus"></i>
54 Add layer
55 <i class="icon-question-sign get-help" title="To build this machine, you must first add the meta-embeddedgeeks layer to your project"></i>
56 </a>
57 </td>
58 </tr>
59 {% endfor %}
60
61{% include "basetable_bottom.html" %}
62
63{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html
index 3c59fcf2ac..d7bfa2b9de 100644
--- a/bitbake/lib/toaster/toastergui/templates/project.html
+++ b/bitbake/lib/toaster/toastergui/templates/project.html
@@ -224,36 +224,14 @@ $(document).ready(function () {
224 <div id="dependency-alert" class="alert alert-info" style="display:none;"> 224 <div id="dependency-alert" class="alert alert-info" style="display:none;">
225 <p><strong>meta-tizen</strong> depends on the layers below. Check the ones you want to add: </p> 225 <p><strong>meta-tizen</strong> depends on the layers below. Check the ones you want to add: </p>
226 <ul class="unstyled"> 226 <ul class="unstyled">
227 <li> 227 {% for f in layer_dependency %}
228 <label class="checkbox">
229 <input checked="checked" type="checkbox">
230 meta-efl
231 </label>
232 </li>
233 <li>
234 <label class="checkbox">
235 <input checked="checked" type="checkbox">
236 meta-intel
237 </label>
238 </li>
239 <li>
240 <label class="checkbox">
241 <input checked="checked" type="checkbox">
242 meta-multimedia
243 </label>
244 </li>
245 <li>
246 <label class="checkbox">
247 <input checked="checked" type="checkbox">
248 meta-oe
249 </label>
250 </li>
251 <li> 228 <li>
252 <label class="checkbox"> 229 <label class="checkbox">
253 <input checked="checked" type="checkbox"> 230 <input checked="checked" type="checkbox">
254 meta-ruby 231 meta-ruby
255 </label> 232 </label>
256 </li> 233 </li>
234 {% endfor %}
257 </ul> 235 </ul>
258 <button id="add-layer-dependencies" class="btn btn-info add-layer">Add layers</button> 236 <button id="add-layer-dependencies" class="btn btn-info add-layer">Add layers</button>
259 </div> 237 </div>
@@ -315,27 +293,38 @@ $(document).ready(function () {
315 </div> 293 </div>
316 294
317 <div class="well well-transparent span4"> 295 <div class="well well-transparent span4">
296
318 <h3> 297 <h3>
319 Set machine 298 Project machine
320 <i data-original-title="The machine is the hardware for which you want to build. You can only set one machine per project" class="icon-question-sign get-help heading-help" title=""></i> 299 <i class="icon-question-sign get-help heading-help" title="The machine is the hardware for which you want to build. You can only set one machine per project"></i>
321 </h3> 300 </h3>
322 <p class="lead"> 301 <p class="lead" id="selected-machine"> {{machine}}
323 {{machine}} 302 <i id="change-machine" class="icon-pencil"></i>
324 <i title="" data-original-title="" class="icon-pencil"></i>
325 </p> 303 </p>
326 <h3> 304 <form id="select-machine">
327 Set distro 305 <div class="alert alert-info">
328 <i data-original-title="When you build an image using the Yocto Project and do not alter the distro, you are creating a Poky distribution" class="icon-question-sign get-help heading-help" title=""></i> 306 <strong>Machine changes have a big impact on build outcome.</strong>
329 </h3> 307 You cannot really compare the builds for the new machine with the previous ones.
330 <p class="lead"> 308 </div>
331 {{distro}} 309 <div class="input-append">
332 <i title="" data-original-title="" class="icon-pencil"></i> 310 <input type="text" id="machine" autocomplete="off" value="qemux86" data-provide="typeahead"
311 data-minLength="1"
312 data-autocomplete="off"
313 data-source='[
314 ]'>
315 <button id="apply-change-machine" class="btn" type="button">Save</button>
316 <a href="#" id="cancel-machine" class="btn btn-link">Cancel</a>
317 </div>
318 <p><a href="{% url 'machines' %}" class="link">View all machines</a></p>
319 </form>
320 <p class="link-action">
321 <a href="{% url 'projectconf' project.id %}" class="link">Edit configuration variables</a>
322 <i class="icon-question-sign get-help heading-help" title="You can set other project configuration options here. Each option, like everything else in the build system, is a variable - value pair"></i>
333 </p> 323 </p>
334 <p class="link-action"> 324
335 <a href="{% url 'projectconf' project.id %}" class="link">Edit configuration variables</a>
336 <i class="icon-question-sign get-help heading-help" title="You can set other project configuration options here. Each option, like everything else in the build system, is a variable - value pair"></i>
337 </p>
338 </div> 325 </div>
326
327
339 </div> 328 </div>
340 329
341 <h2>Project details</h2> 330 <h2>Project details</h2>
diff --git a/bitbake/lib/toaster/toastergui/templates/recipes.html b/bitbake/lib/toaster/toastergui/templates/recipes.html
index 791a487a81..791a487a81 100755..100644
--- a/bitbake/lib/toaster/toastergui/templates/recipes.html
+++ b/bitbake/lib/toaster/toastergui/templates/recipes.html
diff --git a/bitbake/lib/toaster/toastergui/templates/targets.html b/bitbake/lib/toaster/toastergui/templates/targets.html
new file mode 100644
index 0000000000..3afdf0a5e9
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/templates/targets.html
@@ -0,0 +1,186 @@
1{% extends "baseprojectpage.html" %}
2{% load projecttags %}
3{% load humanize %}
4
5{% block localbreadcrumb %}
6<li>Targets</li>
7{% endblock %}
8
9{% block projectinfomain %}
10 <div class="page-header">
11 <h1>
12 All targets
13 <i class="icon-question-sign get-help heading-help" title="This page lists all the targets compatible with Yocto Project 1.7 'Dxxxx' that Toaster knows about. They include community-created targets suitable for use on top of OpenEmbedded Core and any targets you have imported"></i>
14 </h1>
15 </div>
16 <!--div class="alert">
17 <div class="input-append" style="margin-bottom:0px;">
18 <input class="input-xxlarge" type="text" placeholder="Search targets" value="browser" />
19 <a class="add-on btn">
20 <i class="icon-remove"></i>
21 </a>
22 <button class="btn" type="button">Search</button>
23 <a class="btn btn-link" href="#">Show all targets</a>
24 </div>
25 </div-->
26 <div id="target-added" class="alert alert-info lead" style="display:none;"></div>
27 <div id="target-removed" class="alert alert-info lead" style="display:none;">
28 <button type="button" class="close" data-dismiss="alert">&times;</button>
29 <strong>1</strong> target deleted from <a href="project-with-targets.html">your project</a>: <a href="#">meta-aarch64</a>
30 </div>
31
32
33{% include "basetable_top.html" %}
34 {% for o in objects %}
35 <tr class="data">
36 <td class="target">
37 {{o.name}} ({{o.id}}, {{o.up_id}})
38 <a target="_blank" href="{{o.get_layersource_view_url}}"><i class="icon-share get-info"></i></a>
39 </td>
40 <td class="version">{{o.version}}</td>
41 <td class="description">{{o.description}}</td>
42 <td class="recipe-file">
43 <code>{{o.file_path}}</code>
44 <a href="{{o.get_vcs_link_url}}" target="_blank"><i class="icon-share get-info"></i></a>
45 </td>
46 <td class="target-section">{{o.section}}</td>
47 <td class="license">{{o.license}}</td>
48 <td class="layer"><a href="#">{{o.layer_version.layer.name}}</a></td>
49 <td class="source">{{o.layer_source.name}}</td>
50 <td class="branch">{{o.layer_version.commit}}</td>
51 <td class="build">
52 <a id="build-target" href="project-with-targets.html?target=3g-router-image" class="btn btn-block" style="display:none;">
53 Build target
54 </a>
55 <a id="add-layer" href="#" class="btn btn-block nopop" title="1 layer added">
56 <i class="icon-plus"></i>
57 Add layer
58 <i class="icon-question-sign get-help" title="To build this target, you must first add the meta-embeddedgeeks layer to your project"></i>
59 </a>
60 </td>
61 </tr>
62 {% endfor %}
63{% include "basetable_bottom.html" %}
64
65 <!-- Modals -->
66
67 <!-- 'Layer dependencies modal' -->
68 <div id="dependencies-message" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
69 <div class="modal-header">
70 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
71 <h3>meta-acer dependencies</h3>
72 </div>
73 <div class="modal-body">
74 <p><strong>meta-acer</strong> depends on some targets that are not added to your project. Select the ones you want to add:</p>
75 <ul class="unstyled">
76 <li>
77 <label class="checkbox">
78 <input type="checkbox" checked="checked">
79 meta-android
80 </label>
81 </li>
82 <li>
83 <label class="checkbox">
84 <input type="checkbox" checked="checked">
85 meta-oe
86 </label>
87 </li>
88 </ul>
89 </div>
90 <div class="modal-footer">
91 <button id="add-target-dependencies" type="submit" class="btn btn-primary" data-dismiss="modal" >Add targets</button>
92 <button class="btn" data-dismiss="modal">Cancel</button>
93 </div>
94 </div>
95
96 <script src="assets/js/jquery-1.9.1.min.js" type='text/javascript'></script>
97 <script src="assets/js/jquery.tablesorter.min.js" type='text/javascript'></script>
98 <script src="assets/js/jquery-ui-1.10.3.custom.min.js"></script>
99 <script src="assets/js/bootstrap.min.js" type='text/javascript'></script>
100 <script src="assets/js/prettify.js" type='text/javascript'></script>
101 <script src="assets/js/jit.js" type='text/javascript'></script>
102 <script src="assets/js/main.js" type='text/javascript'></script>
103
104 <script>
105 $(document).ready(function() {
106
107 //show or hide selected columns on load
108 $("input:checkbox").each(function(){
109 var selectedType = $(this).val();
110 if($(this).is(":checked")){
111 $("."+selectedType).show();
112 }
113 else{
114 $("."+selectedType).hide();
115 }
116 });
117
118 // enable add target button
119 $('#add-target-with-deps').removeAttr('disabled');
120
121 //edit columns functionality (show / hide table columns)
122 $("input:checkbox").change();
123 $("input:checkbox").change(function(){
124 var selectedType = $(this).val();
125 if($(this).is(":checked")){
126 $("."+selectedType).show();
127 }
128 else{
129 $("."+selectedType).hide();
130 }
131 });
132
133 //turn edit columns dropdown into a multi-select menu
134 $('.dropdown-menu input, .dropdown-menu label').click(function(e) {
135 e.stopPropagation();
136 });
137
138 //show tooltip with applied filter
139 $('#filtered').tooltip({container:'table', placement:'bottom', delay:{hide:1500}, html:true});
140
141 $('#filtered').click(function() {
142 $(this).tooltip('hide');
143 });
144
145 //show target added tooltip
146 $("#remove-target, #add-target, #add-target-with-deps2").tooltip({ trigger: 'manual' });
147
148 // add target without dependencies
149 $("#add-target").click(function(){
150 $('#target-removed').hide();
151 $('#target-added').html('<button type="button" class="close" data-dismiss="alert">&times;</button><strong>1</strong> target added to <a href="project-with-targets.html">your project</a>: <a href="#">meta-aarch64</a>').fadeIn();
152 $('#add-target').tooltip('show');
153 $("#add-target").hide();
154 $(".add-targets .tooltip").delay(2000).fadeOut(function(){
155 $("#remove-target").delay(300).fadeIn();
156 });
157 });
158
159 // add target with dependencies
160 $(document).on("click", "#add-target-dependencies", function() {
161 $('#target-removed').hide();
162 $('#target-added').html('<button type="button" class="close" data-dismiss="alert">&times;</button><strong>3</strong> targets added to <a href="project-with-targets.html">your project</a>: <a href="#">meta-acer</a> and its dependencies <a href="#">meta-android</a> and <a href="#">meta-oe</a>').delay(400).fadeIn(function(){
163 $('#add-target-with-deps').tooltip('show');
164 $("#add-target-with-deps, #add-target-with-deps").hide();
165 $(".add-targets .tooltip").delay(2000).fadeOut(function(){
166 $("#remove-target-with-deps").delay(300).fadeIn();
167 });
168 });
169 });
170
171 // delete target
172 $("#remove-target").click(function(){
173 $('#target-added').hide();
174 $('#target-removed').show();
175 $('#remove-target').tooltip('show');
176 $("#remove-target").hide();
177 $(".add-targets .tooltip").delay(2000).fadeOut(function(){
178 $("#add-target").delay(300).fadeIn();
179 });
180 });
181
182 });
183
184</script>
185
186{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 86a34adf24..167b687d03 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -1761,7 +1761,7 @@ if toastermain.settings.MANAGED:
1761 from django.contrib.auth.decorators import login_required 1761 from django.contrib.auth.decorators import login_required
1762 1762
1763 from orm.models import Project, ProjectLayer, ProjectTarget, ProjectVariable 1763 from orm.models import Project, ProjectLayer, ProjectTarget, ProjectVariable
1764 from orm.models import Branch, LayerSource, ToasterSetting, Release 1764 from orm.models import Branch, LayerSource, ToasterSetting, Release, Machine
1765 from bldcontrol.models import BuildRequest 1765 from bldcontrol.models import BuildRequest
1766 1766
1767 import traceback 1767 import traceback
@@ -1770,10 +1770,13 @@ if toastermain.settings.MANAGED:
1770 1770
1771 # the context processor that supplies data used across all the pages 1771 # the context processor that supplies data used across all the pages
1772 def managedcontextprocessor(request): 1772 def managedcontextprocessor(request):
1773 return { 1773 ret = {
1774 "projects": Project.objects.all(), 1774 "projects": Project.objects.all(),
1775 "MANAGED" : toastermain.settings.MANAGED 1775 "MANAGED" : toastermain.settings.MANAGED
1776 } 1776 }
1777 if 'project' in request.session:
1778 ret['project'] = request.session['project']
1779 return ret
1777 1780
1778 # new project 1781 # new project
1779 def newproject(request): 1782 def newproject(request):
@@ -1922,7 +1925,7 @@ if toastermain.settings.MANAGED:
1922 # define here what parameters the view needs in the GET portion in order to 1925 # define here what parameters the view needs in the GET portion in order to
1923 # be able to display something. 'count' and 'page' are mandatory for all views 1926 # be able to display something. 'count' and 'page' are mandatory for all views
1924 # that use paginators. 1927 # that use paginators.
1925 mandatory_parameters = { 'count': 10, 'page' : 1, 'orderby' : 'layer__name:-' }; 1928 mandatory_parameters = { 'count': 10, 'page' : 1, 'orderby' : 'layer__name:+' };
1926 retval = _verify_parameters( request.GET, mandatory_parameters ) 1929 retval = _verify_parameters( request.GET, mandatory_parameters )
1927 if retval: 1930 if retval:
1928 return _redirect_parameters( 'layers', request.GET, mandatory_parameters) 1931 return _redirect_parameters( 'layers', request.GET, mandatory_parameters)
@@ -1945,7 +1948,8 @@ if toastermain.settings.MANAGED:
1945 context = { 1948 context = {
1946 'objects' : layer_info, 1949 'objects' : layer_info,
1947 'objectname' : "layers", 1950 'objectname' : "layers",
1948 'default_orderby' : 'completed_on:-', 1951 'default_orderby' : 'layer__name:+',
1952 'total_count': queryset_with_search.count(),
1949 1953
1950 'tablecols' : [ 1954 'tablecols' : [
1951 { 'name': 'Layer', 1955 { 'name': 'Layer',
@@ -1954,8 +1958,10 @@ if toastermain.settings.MANAGED:
1954 }, 1958 },
1955 { 'name': 'Description', 1959 { 'name': 'Description',
1956 'dclass': 'span4', 1960 'dclass': 'span4',
1961 'clclass': 'description',
1957 }, 1962 },
1958 { 'name': 'Layer source', 1963 { 'name': 'Layer source',
1964 'clclass': 'source',
1959 'qhelp': "Where the layer is coming from, for example, if it's part of the OpenEmbedded collection of layers or if it's a layer you have imported", 1965 'qhelp': "Where the layer is coming from, for example, if it's part of the OpenEmbedded collection of layers or if it's a layer you have imported",
1960 'orderfield': _get_toggle_order(request, "layer_source__name"), 1966 'orderfield': _get_toggle_order(request, "layer_source__name"),
1961 'ordericon': _get_toggle_order_icon(request, "layer_source__name"), 1967 'ordericon': _get_toggle_order_icon(request, "layer_source__name"),
@@ -1967,15 +1973,20 @@ if toastermain.settings.MANAGED:
1967 }, 1973 },
1968 { 'name': 'Git repository URL', 1974 { 'name': 'Git repository URL',
1969 'dclass': 'span6', 1975 'dclass': 'span6',
1976 'clclass': 'git-repo', 'hidden': 1,
1970 'qhelp': "The Git repository for the layer source code", 1977 'qhelp': "The Git repository for the layer source code",
1971 }, 1978 },
1972 { 'name': 'Subdirectory', 1979 { 'name': 'Subdirectory',
1980 'clclass': 'git-subdir',
1981 'hidden': 1,
1973 'qhelp': "The layer directory within the Git repository", 1982 'qhelp': "The layer directory within the Git repository",
1974 }, 1983 },
1975 { 'name': 'Branch, tag o commit', 1984 { 'name': 'Branch, tag o commit',
1985 'clclass': 'branch',
1976 'qhelp': "The Git branch of the layer. For the layers from the OpenEmbedded source, the branch matches the Yocto Project version you selected for this project", 1986 'qhelp': "The Git branch of the layer. For the layers from the OpenEmbedded source, the branch matches the Yocto Project version you selected for this project",
1977 }, 1987 },
1978 { 'name': 'Dependencies', 1988 { 'name': 'Dependencies',
1989 'clclass': 'dependencies',
1979 'qhelp': "Other layers a layer depends upon", 1990 'qhelp': "Other layers a layer depends upon",
1980 }, 1991 },
1981 { 'name': 'Add | Delete', 1992 { 'name': 'Add | Delete',
@@ -1992,10 +2003,160 @@ if toastermain.settings.MANAGED:
1992 raise Exception("TODO: implement page #6591") 2003 raise Exception("TODO: implement page #6591")
1993 2004
1994 def targets(request): 2005 def targets(request):
1995 raise Exception("TODO: implement page #6592") 2006 template = "targets.html"
2007 # define here what parameters the view needs in the GET portion in order to
2008 # be able to display something. 'count' and 'page' are mandatory for all views
2009 # that use paginators.
2010 mandatory_parameters = { 'count': 10, 'page' : 1, 'orderby' : 'name:+' };
2011 retval = _verify_parameters( request.GET, mandatory_parameters )
2012 if retval:
2013 return _redirect_parameters( 'targets', request.GET, mandatory_parameters)
2014
2015 # boilerplate code that takes a request for an object type and returns a queryset
2016 # for that object type. copypasta for all needed table searches
2017 (filter_string, search_term, ordering_string) = _search_tuple(request, Recipe)
2018
2019 queryset_all = Recipe.objects.all()
2020 if 'project' in request.session:
2021 queryset_all = queryset_all.filter(Q(layer_version__up_branch__in = Branch.objects.filter(name = request.session['project'].release.name)) | Q(layer_version__build__in = request.session['project'].build_set.all()))
2022
2023 queryset_with_search = _get_queryset(Recipe, queryset_all, None, search_term, ordering_string, '-name')
2024 queryset = _get_queryset(Recipe, queryset_all, filter_string, search_term, ordering_string, '-name')
2025
2026 # retrieve the objects that will be displayed in the table; targets a paginator and gets a page range to display
2027 target_info = _build_page_range(Paginator(queryset, request.GET.get('count', 10)),request.GET.get('page', 1))
2028
2029
2030 context = {
2031 'objects' : target_info,
2032 'objectname' : "targets",
2033 'default_orderby' : 'name:+',
2034 'total_count': queryset_with_search.count(),
2035
2036 'tablecols' : [
2037 { 'name': 'Target',
2038 'orderfield': _get_toggle_order(request, "name"),
2039 'ordericon' : _get_toggle_order_icon(request, "name"),
2040 },
2041 { 'name': 'Target version',
2042 'dclass': 'span2',
2043 },
2044 { 'name': 'Description',
2045 'dclass': 'span5',
2046 'clclass': 'description',
2047 },
2048 { 'name': 'Recipe file',
2049 'clclass': 'recipe-file',
2050 'hidden': 1,
2051 'dclass': 'span5',
2052 },
2053 { 'name': 'Section',
2054 'clclass': 'target-section',
2055 'hidden': 1,
2056 },
2057 { 'name': 'License',
2058 'clclass': 'license',
2059 'hidden': 1,
2060 },
2061 { 'name': 'Layer',
2062 'clclass': 'layer',
2063 },
2064 { 'name': 'Layer source',
2065 'clclass': 'source',
2066 'qhelp': "Where the target is coming from, for example, if it's part of the OpenEmbedded collection of targets or if it's a target you have imported",
2067 'orderfield': _get_toggle_order(request, "layer_source__name"),
2068 'ordericon': _get_toggle_order_icon(request, "layer_source__name"),
2069 'filter': {
2070 'class': 'target',
2071 'label': 'Show:',
2072 'options': map(lambda x: (x.name, 'layer_source__pk:' + str(x.id), queryset_with_search.filter(layer_source__pk = x.id).count() ), LayerSource.objects.all()),
2073 }
2074 },
2075 { 'name': 'Branch, tag or commit',
2076 'clclass': 'branch',
2077 'hidden': 1,
2078 },
2079 { 'name': 'Build',
2080 'dclass': 'span2',
2081 'qhelp': "Add or delete targets to / from your project ",
2082 },
2083
2084 ]
2085 }
2086
2087 return render(request, template, context)
1996 2088
1997 def machines(request): 2089 def machines(request):
1998 raise Exception("TODO: implement page #6593") 2090 template = "machines.html"
2091 # define here what parameters the view needs in the GET portion in order to
2092 # be able to display something. 'count' and 'page' are mandatory for all views
2093 # that use paginators.
2094 mandatory_parameters = { 'count': 10, 'page' : 1, 'orderby' : 'name:+' };
2095 retval = _verify_parameters( request.GET, mandatory_parameters )
2096 if retval:
2097 return _redirect_parameters( 'machines', request.GET, mandatory_parameters)
2098
2099 # boilerplate code that takes a request for an object type and returns a queryset
2100 # for that object type. copypasta for all needed table searches
2101 (filter_string, search_term, ordering_string) = _search_tuple(request, Machine)
2102
2103 queryset_all = Machine.objects.all()
2104# if 'project' in request.session:
2105# queryset_all = queryset_all.filter(Q(layer_version__up_branch__in = Branch.objects.filter(name = request.session['project'].release.name)) | Q(layer_version__build__in = request.session['project'].build_set.all()))
2106
2107 queryset_with_search = _get_queryset(Machine, queryset_all, None, search_term, ordering_string, '-name')
2108 queryset = _get_queryset(Machine, queryset_all, filter_string, search_term, ordering_string, '-name')
2109
2110 # retrieve the objects that will be displayed in the table; machines a paginator and gets a page range to display
2111 machine_info = _build_page_range(Paginator(queryset, request.GET.get('count', 10)),request.GET.get('page', 1))
2112
2113
2114 context = {
2115 'objects' : machine_info,
2116 'objectname' : "machines",
2117 'default_orderby' : 'name:+',
2118 'total_count': queryset_with_search.count(),
2119
2120 'tablecols' : [
2121 { 'name': 'Machine',
2122 'orderfield': _get_toggle_order(request, "name"),
2123 'ordericon' : _get_toggle_order_icon(request, "name"),
2124 },
2125 { 'name': 'Description',
2126 'dclass': 'span5',
2127 'clclass': 'description',
2128 },
2129 { 'name': 'Machine file',
2130 'clclass': 'machine-file',
2131 'hidden': 1,
2132 },
2133 { 'name': 'Layer',
2134 'clclass': 'layer',
2135 },
2136 { 'name': 'Layer source',
2137 'clclass': 'source',
2138 'qhelp': "Where the machine is coming from, for example, if it's part of the OpenEmbedded collection of machines or if it's a machine you have imported",
2139 'orderfield': _get_toggle_order(request, "layer_source__name"),
2140 'ordericon': _get_toggle_order_icon(request, "layer_source__name"),
2141 'filter': {
2142 'class': 'machine',
2143 'label': 'Show:',
2144 'options': map(lambda x: (x.name, 'layer_source__pk:' + str(x.id), queryset_with_search.filter(layer_source__pk = x.id).count() ), LayerSource.objects.all()),
2145 }
2146 },
2147 { 'name': 'Branch, tag or commit',
2148 'clclass': 'branch',
2149 'hidden': 1,
2150 },
2151 { 'name': 'Select',
2152 'dclass': 'span2',
2153 'qhelp': "Add or delete machines to / from your project ",
2154 },
2155
2156 ]
2157 }
2158
2159 return render(request, template, context)
1999 2160
2000 def projectconf(request, pid): 2161 def projectconf(request, pid):
2001 raise Exception("TODO: implement page #6588") 2162 raise Exception("TODO: implement page #6588")