diff options
Diffstat (limited to 'bitbake')
| -rw-r--r-- | bitbake/lib/toaster/bldcontrol/models.py | 33 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/static/css/default.css | 4 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/static/js/projectapp.js | 24 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/base.html | 3 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/basetable_bottom.html | 13 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/layers.html | 124 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/mrb_section.html | 11 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/project.html | 48 | ||||
| -rw-r--r-- | bitbake/lib/toaster/toastergui/templates/targets.html | 340 | ||||
| -rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 157 |
10 files changed, 458 insertions, 299 deletions
diff --git a/bitbake/lib/toaster/bldcontrol/models.py b/bitbake/lib/toaster/bldcontrol/models.py index f72fb8fbc9..e643d08603 100644 --- a/bitbake/lib/toaster/bldcontrol/models.py +++ b/bitbake/lib/toaster/bldcontrol/models.py | |||
| @@ -42,11 +42,34 @@ class BuildEnvironment(models.Model): | |||
| 42 | 42 | ||
| 43 | def get_artifact_type(self, path): | 43 | def get_artifact_type(self, path): |
| 44 | if self.betype == BuildEnvironment.TYPE_LOCAL: | 44 | if self.betype == BuildEnvironment.TYPE_LOCAL: |
| 45 | import magic | 45 | try: |
| 46 | m = magic.open(magic.MAGIC_MIME_TYPE) | 46 | import magic |
| 47 | m.load() | 47 | |
| 48 | return m.file(path) | 48 | # fair warning: this is a mess; there are multiple competeing and incompatible |
| 49 | raise Exception("FIXME: not implemented") | 49 | # magic modules floating around, so we try some of the most common combinations |
| 50 | |||
| 51 | try: # we try ubuntu's python-magic 5.4 | ||
| 52 | m = magic.open(magic.MAGIC_MIME_TYPE) | ||
| 53 | m.load() | ||
| 54 | return m.file(path) | ||
| 55 | except AttributeError: | ||
| 56 | pass | ||
| 57 | |||
| 58 | try: # we try python-magic 0.4.6 | ||
| 59 | m = magic.Magic(magic.MAGIC_MIME) | ||
| 60 | return m.from_file(path) | ||
| 61 | except AttributeError: | ||
| 62 | pass | ||
| 63 | |||
| 64 | try: # we try pip filemagic 1.6 | ||
| 65 | m = magic.Magic(flags=magic.MAGIC_MIME_TYPE) | ||
| 66 | return m.id_filename(path) | ||
| 67 | except AttributeError: | ||
| 68 | pass | ||
| 69 | |||
| 70 | return "binary/octet-stream" | ||
| 71 | except ImportError: | ||
| 72 | return "binary/octet-stream" | ||
| 50 | 73 | ||
| 51 | def get_artifact(self, path): | 74 | def get_artifact(self, path): |
| 52 | if self.betype == BuildEnvironment.TYPE_LOCAL: | 75 | if self.betype == BuildEnvironment.TYPE_LOCAL: |
diff --git a/bitbake/lib/toaster/toastergui/static/css/default.css b/bitbake/lib/toaster/toastergui/static/css/default.css index 9e62c6c8e7..fb20fc9241 100644 --- a/bitbake/lib/toaster/toastergui/static/css/default.css +++ b/bitbake/lib/toaster/toastergui/static/css/default.css | |||
| @@ -61,8 +61,8 @@ dd p { line-height: 20px; } | |||
| 61 | 61 | ||
| 62 | /* Override default Twitter Boostrap styles for anchor tags inside tables */ | 62 | /* Override default Twitter Boostrap styles for anchor tags inside tables */ |
| 63 | td a, td a > code { color: #333333; } | 63 | td a, td a > code { color: #333333; } |
| 64 | td a > code { white-space: normal; } | 64 | td code { white-space: normal; } |
| 65 | td a:hover { color: #000000; text-decoration: underline; } | 65 | td a:hover, td a > code:hover { color: #000000; text-decoration: underline; } |
| 66 | 66 | ||
| 67 | /* Override default Twitter Bootstrap styles for tr.error */ | 67 | /* Override default Twitter Bootstrap styles for tr.error */ |
| 68 | .table tbody tr.error > td { background-color: transparent; } /* override default Bootstrap behaviour */ | 68 | .table tbody tr.error > td { background-color: transparent; } /* override default Bootstrap behaviour */ |
diff --git a/bitbake/lib/toaster/toastergui/static/js/projectapp.js b/bitbake/lib/toaster/toastergui/static/js/projectapp.js index e674d8ffd1..b347451e88 100644 --- a/bitbake/lib/toaster/toastergui/static/js/projectapp.js +++ b/bitbake/lib/toaster/toastergui/static/js/projectapp.js | |||
| @@ -92,6 +92,24 @@ projectApp.config(function($interpolateProvider) { | |||
| 92 | $interpolateProvider.endSymbol("]}"); | 92 | $interpolateProvider.endSymbol("]}"); |
| 93 | }); | 93 | }); |
| 94 | 94 | ||
| 95 | |||
| 96 | // add time interval to HH:mm filter | ||
| 97 | projectApp.filter('timediff', function() { | ||
| 98 | return function(input) { | ||
| 99 | function pad(j) { | ||
| 100 | if (parseInt(j) < 10) {return "0" + j} | ||
| 101 | return j; | ||
| 102 | } | ||
| 103 | seconds = parseInt(input); | ||
| 104 | minutes = Math.floor(seconds / 60); | ||
| 105 | seconds = seconds - minutes * 60; | ||
| 106 | hours = Math.floor(seconds / 3600); | ||
| 107 | seconds = seconds - hours * 3600; | ||
| 108 | return pad(hours) + ":" + pad(minutes) + ":" + pad(seconds); | ||
| 109 | } | ||
| 110 | }); | ||
| 111 | |||
| 112 | |||
| 95 | // main controller for the project page | 113 | // main controller for the project page |
| 96 | projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $location, $cookies, $q, $sce) { | 114 | projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $location, $cookies, $q, $sce) { |
| 97 | 115 | ||
| @@ -150,7 +168,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc | |||
| 150 | 168 | ||
| 151 | // identify canceled builds here, so we can display them. | 169 | // identify canceled builds here, so we can display them. |
| 152 | _diffArrays(oldbuilds, $scope.builds, | 170 | _diffArrays(oldbuilds, $scope.builds, |
| 153 | function (e,f) { return e.status == f.status && e.id == f.id }, // compare | 171 | function (e,f) { return e.id == f.id }, // compare |
| 154 | undefined, // added | 172 | undefined, // added |
| 155 | function (e) { // deleted | 173 | function (e) { // deleted |
| 156 | if (e.status == "deleted") return; | 174 | if (e.status == "deleted") return; |
| @@ -421,7 +439,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc | |||
| 421 | }).then( function () { | 439 | }).then( function () { |
| 422 | $scope.toggle(elementid); | 440 | $scope.toggle(elementid); |
| 423 | if (data['projectVersion'] != undefined) { | 441 | if (data['projectVersion'] != undefined) { |
| 424 | alertText += "<b>" + $scope.release.name + "</b>"; | 442 | alertText += "<b>" + $scope.project.release.name + "</b>"; |
| 425 | } | 443 | } |
| 426 | $scope.displayAlert(alertZone, alertText, "alert-info"); | 444 | $scope.displayAlert(alertZone, alertText, "alert-info"); |
| 427 | }); | 445 | }); |
| @@ -506,7 +524,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc | |||
| 506 | // init code | 524 | // init code |
| 507 | // | 525 | // |
| 508 | $scope.init = function() { | 526 | $scope.init = function() { |
| 509 | $scope.pollHandle = $interval(function () { $scope._makeXHRCall({method: "POST", url: $scope.urls.xhr_edit, data: undefined});}, 4000, 0); | 527 | $scope.pollHandle = $interval(function () { $scope._makeXHRCall({method: "GET", url: $scope.urls.xhr_edit, data: undefined});}, 4000, 0); |
| 510 | } | 528 | } |
| 511 | 529 | ||
| 512 | $scope.init(); | 530 | $scope.init(); |
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html index d414bfbbde..f377081849 100644 --- a/bitbake/lib/toaster/toastergui/templates/base.html +++ b/bitbake/lib/toaster/toastergui/templates/base.html | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | <!DOCTYPE html> | 1 | <!DOCTYPE html> |
| 2 | {% load static %} | 2 | {% load static %} |
| 3 | <html> | 3 | <html lang="en"> |
| 4 | <head> | 4 | <head> |
| 5 | <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title> | 5 | <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title> |
| 6 | <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css"> | 6 | <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}" type="text/css"> |
| @@ -9,6 +9,7 @@ | |||
| 9 | <link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'> | 9 | <link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'> |
| 10 | <link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'> | 10 | <link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'> |
| 11 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | 11 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| 12 | <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
| 12 | <script src="{% static 'js/jquery-2.0.3.min.js' %}"> | 13 | <script src="{% static 'js/jquery-2.0.3.min.js' %}"> |
| 13 | </script> | 14 | </script> |
| 14 | <script src="{% static 'js/jquery.cookie.js' %}"> | 15 | <script src="{% static 'js/jquery.cookie.js' %}"> |
diff --git a/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html b/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html index 091e11a51e..d48ad92020 100644 --- a/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html +++ b/bitbake/lib/toaster/toastergui/templates/basetable_bottom.html | |||
| @@ -58,9 +58,12 @@ | |||
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | // load cookie for number of entries to be displayed on page | 60 | // load cookie for number of entries to be displayed on page |
| 61 | pagesize = $.cookie('count'); | 61 | if ({{request.GET.count}} != "") { |
| 62 | if (!pagesize) | 62 | pagesize = {{request.GET.count}}; |
| 63 | pagesize = 10; | 63 | } else { |
| 64 | pagesize = $.cookie('_count'); | ||
| 65 | } | ||
| 66 | |||
| 64 | $('.pagesize option').prop('selected', false) | 67 | $('.pagesize option').prop('selected', false) |
| 65 | .filter('[value="' + pagesize + '"]') | 68 | .filter('[value="' + pagesize + '"]') |
| 66 | .attr('selected', true); | 69 | .attr('selected', true); |
| @@ -81,9 +84,9 @@ | |||
| 81 | $('.progress, .lead span').tooltip({container:'table', placement:'top'}); | 84 | $('.progress, .lead span').tooltip({container:'table', placement:'top'}); |
| 82 | 85 | ||
| 83 | $(".pagesize").change(function () { | 86 | $(".pagesize").change(function () { |
| 84 | reload_params({"count":$(this).val()}); | ||
| 85 | // save cookie with pagesize | 87 | // save cookie with pagesize |
| 86 | $.cookie("count", $(this).val(), { path : $(location).attr('pathname') }); | 88 | $.cookie("_count", $(this).val(), { path : $(location).attr('pathname') }); |
| 89 | reload_params({"count":$(this).val()}); | ||
| 87 | }); | 90 | }); |
| 88 | }); | 91 | }); |
| 89 | </script> | 92 | </script> |
diff --git a/bitbake/lib/toaster/toastergui/templates/layers.html b/bitbake/lib/toaster/toastergui/templates/layers.html index 51f4dd96e7..db34fe4818 100644 --- a/bitbake/lib/toaster/toastergui/templates/layers.html +++ b/bitbake/lib/toaster/toastergui/templates/layers.html | |||
| @@ -9,67 +9,66 @@ | |||
| 9 | {% block projectinfomain %} | 9 | {% block projectinfomain %} |
| 10 | <div class="page-header"> | 10 | <div class="page-header"> |
| 11 | <h1> | 11 | <h1> |
| 12 | {% if request.GET.search and objects.paginator.count > 0 %} | 12 | {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} |
| 13 | {{objects.paginator.count}} layer{{objects.paginator.count|pluralize}} found | 13 | {{objects.paginator.count}} layer{{objects.paginator.count|pluralize}} found |
| 14 | {%elif request.GET.search and objects.paginator.count == 0%} | 14 | {% elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} |
| 15 | No layer found | 15 | No layers found |
| 16 | {%else%} | 16 | {%else%} |
| 17 | All layers | 17 | All layers |
| 18 | {%endif%} | 18 | {%endif%} |
| 19 | <i class="icon-question-sign get-help heading-help" title="This page lists all the layers compatible with " + {{project.release.name}} + " that Toaster knows about."></i> | 19 | <i class="icon-question-sign get-help heading-help" title="This page lists all the layers compatible with {{project.release.name}} that Toaster knows about."></i> |
| 20 | </h1> | 20 | </h1> |
| 21 | </div> | 21 | </div> |
| 22 | 22 | ||
| 23 | <div id="zone1alerts"> | 23 | <div id="zone1alerts"> |
| 24 | |||
| 25 | </div> | 24 | </div> |
| 26 | 25 | ||
| 27 | 26 | ||
| 28 | <div id="layer-added" class="alert alert-info lead" style="display:none;"></div> | ||
| 29 | |||
| 30 | |||
| 31 | {% include "basetable_top_layers.html" %} | 27 | {% include "basetable_top_layers.html" %} |
| 32 | {% for lv in objects %} | 28 | {% for o in objects %} |
| 33 | <tr class="data"> | 29 | <tr class="data"> |
| 34 | <td class="layer"><a href="{% url 'layerdetails' lv.id %}">{{lv.layer.name}}</a></td> | 30 | <td class="layer"><a href="{% url 'layerdetails' o.id %}">{{o.layer.name}}</a></td> |
| 35 | <td class="description">{{lv.layer.summary}}</td> | 31 | <td class="description">{% if o.layer.summary %}{{o.layer.summary}}{%endif%}</td> |
| 36 | <td class="source"><a href="{% url 'layerdetails' lv.pk %}">{{lv.layer_source.name}}</a></td> | 32 | <td class="source"><a href="{% url 'layerdetails' o.pk %}">{{o.layer_source.name}}</a></td> |
| 37 | <td class="git-repo"><a href="{% url 'layerdetails' lv.pk %}"><code>{{lv.layer.vcs_url}}</code></a> | 33 | <td class="git-repo"><a href="{% url 'layerdetails' o.pk %}"><code>{{o.layer.vcs_url}}</code></a> |
| 38 | {% if lv.get_vcs_link_url %} | 34 | {% if o.get_vcs_link_url %} |
| 39 | <a target="_blank" href="{{ lv.get_vcs_link_url }}"><i class="icon-share get-info"></i></a> | 35 | <a target="_blank" href="{{ o.get_vcs_link_url }}"><i class="icon-share get-info"></i></a> |
| 40 | {% endif %} | 36 | {% endif %} |
| 41 | </td> | 37 | </td> |
| 42 | <td class="git-subdir" style="display: table-cell;"><a href="{% url 'layerdetails' lv.pk %}"><code>{{lv.dirpath}}</code></a> | 38 | <td class="git-subdir" style="display: table-cell;"><a href="{% url 'layerdetails' o.pk %}"><code>{{o.dirpath}}</code></a> |
| 43 | {% if lv.dirpath and lv.get_vcs_dirpath_link_url %} | 39 | {% if o.dirpath and o.get_vcs_dirpath_link_url %} |
| 44 | <a target="_blank" href="{{ lv.get_vcs_dirpath_link_url }}"><i class="icon-share get-info"></i></a> | 40 | <a target="_blank" href="{{ o.get_vcs_dirpath_link_url }}"><i class="icon-share get-info"></i></a> |
| 45 | {% endif %} | 41 | {% endif %} |
| 46 | </td> | 42 | </td> |
| 47 | <td class="branch">{% if lv.branch %}{{lv.branch}}{% else %}{{lv.up_branch.name}}{% endif %}</td> | 43 | <td class="branch">{% if o.branch %}{{o.branch}}{% else %}{{o.up_branch.name}}{% endif %}</td> |
| 48 | <td class="dependencies"> | 44 | <td class="dependencies"> |
| 49 | {% with lvds=lv.dependencies.all%} | 45 | {% with ods=o.dependencies.all%} |
| 50 | {% if lvds.count %} | 46 | {% if ods.count %} |
| 51 | <a class="btn" | 47 | <a class="btn" |
| 52 | title="<a href='{% url "layerdetails" lv.pk %}'>{{lv.layer.name}}</a> dependencies" | 48 | title="<a href='{% url "layerdetails" o.pk %}'>{{o.layer.name}}</a> dependencies" |
| 53 | data-content="<ul class='unstyled'> | 49 | data-content="<ul class='unstyled'> |
| 54 | {% for i in lvds%} | 50 | {% for i in ods%} |
| 55 | <li><a href='{% url "layerdetails" i.depends_on.pk %}'>{{i.depends_on.layer.name}}</a></li> | 51 | <li><a href='{% url "layerdetails" i.depends_on.pk %}'>{{i.depends_on.layer.name}}</a></li> |
| 56 | {% endfor %} | 52 | {% endfor %} |
| 57 | </ul>"> | 53 | </ul>"> |
| 58 | {{lvds.count}} | 54 | {{ods.count}} |
| 59 | </a> | 55 | </a> |
| 60 | {% endif %} | 56 | {% endif %} |
| 61 | {% endwith %} | 57 | {% endwith %} |
| 62 | </td> | 58 | </td> |
| 63 | <td class="add-del-layers" value="{{lv.pk}}"> | 59 | {% if project %} |
| 64 | <button id="layer-del-{{lv.pk}}" class="btn btn-danger btn-block remove-layer" style="display:none;" onclick="layerDel({{lv.pk}}, '{{lv.layer.name}}', '{%url 'layerdetails' lv.pk%}')"> | 60 | <td class="add-del-layers" value="{{o.pk}}"> |
| 61 | <div id="layer-tooltip-{{o.pk}}" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner">layer was modified</div> | ||
| 62 | <button id="layer-del-{{o.pk}}" class="btn btn-danger btn-block remove-layer layerbtn" style="display:none;" onclick="layerDel({{o.pk}}, '{{o.layer.name}}', '{%url 'layerdetails' o.pk%}')" > | ||
| 65 | <i class="icon-trash"></i> | 63 | <i class="icon-trash"></i> |
| 66 | Delete layer | 64 | Delete layer |
| 67 | </button> | 65 | </button> |
| 68 | <button id="layer-add-{{lv.pk}}" class="btn btn-block" style="display:none;" onclick="layerAdd({{lv.pk}}, '{{lv.layer.name}}', '{%url 'layerdetails' lv.pk%}')" > | 66 | <button id="layer-add-{{o.pk}}" class="btn btn-block layerbtn" style="display:none;" onclick="layerAdd({{o.pk}}, '{{o.layer.name}}', '{%url 'layerdetails' o.pk%}')" title="layer added"> |
| 69 | <i class="icon-plus"></i> | 67 | <i class="icon-plus"></i> |
| 70 | Add layer | 68 | Add layer |
| 71 | </button> | 69 | </button> |
| 72 | </td> | 70 | </td> |
| 71 | {% endif %} | ||
| 73 | </tr> | 72 | </tr> |
| 74 | {% endfor %} | 73 | {% endfor %} |
| 75 | {% include "basetable_bottom.html" %} | 74 | {% include "basetable_bottom.html" %} |
| @@ -78,7 +77,7 @@ | |||
| 78 | 77 | ||
| 79 | <!-- 'Layer dependencies modal' --> | 78 | <!-- 'Layer dependencies modal' --> |
| 80 | <div id="dependencies_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> | 79 | <div id="dependencies_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> |
| 81 | <form id="dependencies_modal_form"> | 80 | <form id="dependencies_modal_form" style="margin: 0px"> |
| 82 | <div class="modal-header"> | 81 | <div class="modal-header"> |
| 83 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> | 82 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> |
| 84 | <h3><span class="layer-name"></span> dependencies</h3> | 83 | <h3><span class="layer-name"></span> dependencies</h3> |
| @@ -95,8 +94,11 @@ | |||
| 95 | </form> | 94 | </form> |
| 96 | </div> | 95 | </div> |
| 97 | 96 | ||
| 97 | {% if project %} | ||
| 98 | <script> | 98 | <script> |
| 99 | 99 | ||
| 100 | var tooltipUpdateText; | ||
| 101 | |||
| 100 | function _makeXHREditCall(data, onsuccess, onfail) { | 102 | function _makeXHREditCall(data, onsuccess, onfail) { |
| 101 | $.ajax( { | 103 | $.ajax( { |
| 102 | type: "POST", | 104 | type: "POST", |
| @@ -120,13 +122,14 @@ function _makeXHREditCall(data, onsuccess, onfail) { | |||
| 120 | 122 | ||
| 121 | 123 | ||
| 122 | function layerDel(layerId, layerName, layerURL) { | 124 | function layerDel(layerId, layerName, layerURL) { |
| 125 | tooltipUpdateText = "1 layer deleted"; | ||
| 123 | _makeXHREditCall({ 'layerDel': layerId }, function () { | 126 | _makeXHREditCall({ 'layerDel': layerId }, function () { |
| 124 | show_alert("<strong>1</strong> layer deleted from <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>"); | 127 | show_alert("You have deleted <strong>1</strong> layer from <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>"); |
| 125 | }); | 128 | }); |
| 126 | } | 129 | } |
| 127 | 130 | ||
| 128 | function show_alert(text, cls) { | 131 | function show_alert(text, cls) { |
| 129 | $("#zone1alerts").html("<div class=\"alert alert-info\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">×</button>" + text + "</div>"); | 132 | $("#zone1alerts").html("<div class=\"alert alert-info lead\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">×</button>" + text + "</div>"); |
| 130 | } | 133 | } |
| 131 | 134 | ||
| 132 | function show_dependencies_modal(layerId, layerName, layerURL, dependencies) { | 135 | function show_dependencies_modal(layerId, layerName, layerURL, dependencies) { |
| @@ -142,25 +145,35 @@ function show_dependencies_modal(layerId, layerName, layerURL, dependencies) { | |||
| 142 | } | 145 | } |
| 143 | $('#dependencies_list').html(deplistHtml); | 146 | $('#dependencies_list').html(deplistHtml); |
| 144 | 147 | ||
| 148 | var selected = [layerId]; | ||
| 149 | var layer_link_list = "<a href='"+layerURL+"'>"+layerName+"</a>"; | ||
| 150 | |||
| 145 | $("#dependencies_modal_form").submit(function (e) { | 151 | $("#dependencies_modal_form").submit(function (e) { |
| 146 | e.preventDefault(); | 152 | e.preventDefault(); |
| 147 | var selected = [layerId]; | ||
| 148 | $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))}); | 153 | $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))}); |
| 154 | if (selected.length > 1) { | ||
| 155 | tooltipUpdateText = "" + selected.length + " layers added"; | ||
| 156 | } else { | ||
| 157 | tooltipUpdateText = "1 layer added"; | ||
| 158 | } | ||
| 149 | 159 | ||
| 150 | _makeXHREditCall({ 'layerAdd': selected.join(",") }, function () { | 160 | for (var i = 0; i < selected.length; i++) { |
| 151 | var layer_link_list = "<a href='"+layerURL+"'>"+layerName+"</a>"; | 161 | for (var j = 0; j < dependencies.length; j++) { |
| 152 | for (var i = 0; i < selected.length; i++) { | 162 | if (dependencies[j].id == selected[i]) { |
| 153 | for (var j = 0; j < dependencies.length; i++) { | 163 | layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>" |
| 154 | if (dependencies[j].id == selected[i]) { | 164 | break; |
| 155 | layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>" | ||
| 156 | break; | ||
| 157 | } | ||
| 158 | } | 165 | } |
| 159 | } | 166 | } |
| 167 | } | ||
| 168 | |||
| 169 | $('#dependencies_modal').modal('hide'); | ||
| 160 | 170 | ||
| 161 | $('#dependencies_modal').modal('hide'); | 171 | {% if project %} |
| 162 | show_alert("<strong>"+selected.length+"</strong> layers added to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>:" + layer_link_list); | 172 | _makeXHREditCall({ 'layerAdd': selected.join(",") }, function () { |
| 173 | show_alert("You have added <strong>"+selected.length+"</strong> layers to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: " + layer_link_list); | ||
| 163 | }); | 174 | }); |
| 175 | {% endif %} | ||
| 176 | |||
| 164 | }); | 177 | }); |
| 165 | $('#dependencies_modal').modal('show'); | 178 | $('#dependencies_modal').modal('show'); |
| 166 | } | 179 | } |
| @@ -178,8 +191,9 @@ function layerAdd(layerId, layerName, layerURL) { | |||
| 178 | show_dependencies_modal(layerId, layerName, layerURL, _data.list); | 191 | show_dependencies_modal(layerId, layerName, layerURL, _data.list); |
| 179 | } | 192 | } |
| 180 | else { | 193 | else { |
| 194 | tooltipUpdateText = "1 layer added"; | ||
| 181 | _makeXHREditCall({ 'layerAdd': layerId }, function () { | 195 | _makeXHREditCall({ 'layerAdd': layerId }, function () { |
| 182 | show_alert("<strong>1</strong> layer added to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>"); | 196 | show_alert("You have added <strong>1</strong> layer to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>"); |
| 183 | }); | 197 | }); |
| 184 | } | 198 | } |
| 185 | } | 199 | } |
| @@ -188,15 +202,31 @@ function layerAdd(layerId, layerName, layerURL) { | |||
| 188 | } | 202 | } |
| 189 | 203 | ||
| 190 | function button_set(id, state) { | 204 | function button_set(id, state) { |
| 205 | var tohide, toshow; | ||
| 191 | if (state == "add") | 206 | if (state == "add") |
| 192 | { | 207 | { |
| 193 | $("#layer-add-" + id).show(); | 208 | tohide = "#layer-del-"; |
| 194 | $("#layer-del-" + id).hide(); | 209 | toshow = "#layer-add-"; |
| 195 | } | 210 | } |
| 196 | else if (state == "del") | 211 | else if (state == "del") |
| 197 | { | 212 | { |
| 198 | $("#layer-add-" + id).hide(); | 213 | tohide = "#layer-add-"; |
| 199 | $("#layer-del-" + id).show(); | 214 | toshow = "#layer-del-"; |
| 215 | } | ||
| 216 | |||
| 217 | |||
| 218 | var previouslyvisible = $(tohide + id).is(":visible"); | ||
| 219 | if (previouslyvisible) { | ||
| 220 | $(tohide + id).fadeOut( function() { | ||
| 221 | $("#layer-tooltip-" + id).text(tooltipUpdateText); | ||
| 222 | $("#layer-tooltip-" + id).fadeIn().delay(2000).fadeOut(function(){ | ||
| 223 | $(toshow + id).delay(300).fadeIn(); | ||
| 224 | }); | ||
| 225 | }); | ||
| 226 | } else { | ||
| 227 | $(tohide + id).hide(); | ||
| 228 | $("#layer-tooltip-" + id).hide(); | ||
| 229 | $(toshow + id).show(); | ||
| 200 | } | 230 | } |
| 201 | }; | 231 | }; |
| 202 | 232 | ||
| @@ -214,9 +244,11 @@ function updateButtons(projectLayers) { | |||
| 214 | } | 244 | } |
| 215 | 245 | ||
| 216 | $(document).ready(function (){ | 246 | $(document).ready(function (){ |
| 247 | $('.layerbtn').tooltip({ trigger: 'manual' }); | ||
| 217 | updateButtons({{projectlayerset}}); | 248 | updateButtons({{projectlayerset}}); |
| 218 | }); | 249 | }); |
| 219 | 250 | ||
| 220 | </script> | 251 | </script> |
| 252 | {%endif%} | ||
| 221 | 253 | ||
| 222 | {% endblock %} | 254 | {% endblock %} |
diff --git a/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/bitbake/lib/toaster/toastergui/templates/mrb_section.html index 3d17ac62e4..586c47bfae 100644 --- a/bitbake/lib/toaster/toastergui/templates/mrb_section.html +++ b/bitbake/lib/toaster/toastergui/templates/mrb_section.html | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a> | 44 | Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a> |
| 45 | </span> | 45 | </span> |
| 46 | {% if build.project %} | 46 | {% if build.project %} |
| 47 | <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%elif build.outcome == build.FAILED%}btn-danger{%else%}btn-info{%endif%} pull-right" onclick="scheduleBuild({%url 'xhr_projectbuild' build.project.id as myurl %}{{myurl|json}}, {{build.project.name|json}}, {{build.get_sorted_target_list|mapselect:'target'|json}})">Run again</a> | 47 | <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%elif build.outcome == build.FAILED%}btn-danger{%else%}btn-info{%endif%} pull-right" onclick="scheduleBuild({% url 'xhr_projectbuild' build.project.id as bpi%}{{bpi|json}}, {{build.project.name|json}}, {{build.get_sorted_target_list|mapselect:'target'|json}})">Run again</a> |
| 48 | {% endif %} | 48 | {% endif %} |
| 49 | </div> | 49 | </div> |
| 50 | {%endif%} | 50 | {%endif%} |
| @@ -81,19 +81,18 @@ function _makeXHRBuildCall(url, data, onsuccess, onfail) { | |||
| 81 | alert("Call failed"); | 81 | alert("Call failed"); |
| 82 | console.log(_data); | 82 | console.log(_data); |
| 83 | if (onfail) onfail(data); | 83 | if (onfail) onfail(data); |
| 84 | } | 84 | } }); |
| 85 | }); | ||
| 86 | } | 85 | } |
| 87 | 86 | ||
| 88 | 87 | ||
| 89 | function scheduleBuild(url, projectName, buildlist) { | 88 | function scheduleBuild(url, projectName, buildlist) { |
| 90 | console.log("scheduleBuild"); | 89 | console.log("scheduleBuild"); |
| 91 | // _makeXHRBuildCall(url , {targets: buildlist.join(" ")}, function (_data) { | 90 | _makeXHRBuildCall(url, {targets: buildlist.join(" ")}, function (_data) { |
| 92 | 91 | ||
| 93 | $('#latest-builds').prepend('<div class="alert alert-info" style="padding-top:0px">' + '<span class="label label-info" style="font-weight: normal; margin-bottom: 5px; margin-left:-15px; padding-top:5px;">'+projectName+'</span><div class="row-fluid">' + | 92 | $('#latest-builds').prepend('<div class="alert alert-info" style="padding-top:0px">' + '<span class="label label-info" style="font-weight: normal; margin-bottom: 5px; margin-left:-15px; padding-top:5px;">'+projectName+'</span><div class="row-fluid">' + |
| 94 | '<div class="span4 lead">' + buildlist.join(" ") + | 93 | '<div class="span4 lead">' + buildlist.join(" ") + |
| 95 | '</div><div class="span4 lead pull-right">Build queued. Your build will start shortly.</div></div></div>'); | 94 | '</div><div class="span4 lead pull-right">Build queued. Your build will start shortly.</div></div></div>'); |
| 96 | // } | 95 | }); |
| 97 | } | 96 | } |
| 98 | 97 | ||
| 99 | </script> | 98 | </script> |
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html index 9399b312ca..6a812834d3 100644 --- a/bitbake/lib/toaster/toastergui/templates/project.html +++ b/bitbake/lib/toaster/toastergui/templates/project.html | |||
| @@ -76,6 +76,14 @@ vim: expandtab tabstop=2 | |||
| 76 | </div> | 76 | </div> |
| 77 | </script> | 77 | </script> |
| 78 | 78 | ||
| 79 | <script type="text/ng-template" id="target_display"> | ||
| 80 | <div ng-switch on="t.task.length"> | ||
| 81 | <div ng-switch-when="0">{[t.target]}</div> | ||
| 82 | <div ng-switch-default>{[t.target]}:{[t.task]}</div> | ||
| 83 | </div> | ||
| 84 | </script> | ||
| 85 | |||
| 86 | |||
| 79 | <!-- build form --> | 87 | <!-- build form --> |
| 80 | <div class="well"> | 88 | <div class="well"> |
| 81 | <form class="build-form" ng-submit="targetNamedBuild()"> | 89 | <form class="build-form" ng-submit="targetNamedBuild()"> |
| @@ -99,11 +107,11 @@ vim: expandtab tabstop=2 | |||
| 99 | 107 | ||
| 100 | <h2 class="air" ng-if="builds.length">Latest builds</h2> | 108 | <h2 class="air" ng-if="builds.length">Latest builds</h2> |
| 101 | 109 | ||
| 102 | <div class="alert" ng-repeat="b in builds" ng-class="{'queued':'alert-info', 'deleted':'alert-info', 'in progress': 'alert-info', 'In Progress':'alert-info', 'Succeeded':'alert-success', 'failed':'alert-error', 'Failed':'alert-error'}[b.status]"> | 110 | <div class="alert" ng-repeat="b in builds" ng-class="{'queued':'alert-info', 'deleted':'alert-info', 'in progress': 'alert-info', 'failed':'alert-error', 'completed':{'In Progress':'alert-info', 'Succeeded':'alert-success', 'Failed':'alert-error'}[b.build[0].status]}[b.status]" > |
| 103 | <div class="row-fluid"> | 111 | <div class="row-fluid"> |
| 104 | <switch ng-switch="b.status"> | 112 | <switch ng-switch="b.status"> |
| 105 | <case ng-switch-when="failed"> | 113 | <case ng-switch-when="failed"> |
| 106 | <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | 114 | <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div> |
| 107 | <div class="row-fluid"> | 115 | <div class="row-fluid"> |
| 108 | <div class="air well" ng-repeat="e in b.errors"> | 116 | <div class="air well" ng-repeat="e in b.errors"> |
| 109 | {[e.type]}: <pre>{[e.msg]}</pre> | 117 | {[e.type]}: <pre>{[e.msg]}</pre> |
| @@ -111,53 +119,51 @@ vim: expandtab tabstop=2 | |||
| 111 | </div> | 119 | </div> |
| 112 | </case> | 120 | </case> |
| 113 | <case ng-switch-when="queued"> | 121 | <case ng-switch-when="queued"> |
| 114 | <div class="lead span5"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | 122 | <div class="lead span5"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div> |
| 115 | <div class="span4 lead" >Build queued | 123 | <div class="span4 lead" >Build queued |
| 116 | <i title="This build will start as soon as a build server is available" class="icon-question-sign get-help get-help-blue heading-help" data-toggle="tooltip"></i> | 124 | <i title="This build will start as soon as a build server is available" class="icon-question-sign get-help get-help-blue heading-help" data-toggle="tooltip"></i> |
| 117 | </div> | 125 | </div> |
| 118 | <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button> | 126 | <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button> |
| 119 | </case> | 127 | </case> |
| 120 | <case ng-switch-when="created"> | 128 | <case ng-switch-when="created"> |
| 121 | <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | 129 | <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div> |
| 122 | <div class="span6" > | 130 | <div class="span6" > |
| 123 | <span class="lead">Creating build</span> | 131 | <span class="lead">Creating build</span> |
| 124 | </div> | 132 | </div> |
| 125 | <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button> | 133 | <button class="btn pull-right btn-info" ng-click="buildCancel(b.id)">Cancel</button> |
| 126 | </case> | 134 | </case> |
| 127 | <case ng-switch-when="deleted"> | 135 | <case ng-switch-when="deleted"> |
| 128 | <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | 136 | <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div> |
| 129 | <div class="span6" id="{[b.id]}-deleted" > | 137 | <div class="span6" id="{[b.id]}-deleted" > |
| 130 | <span class="lead">Build deleted</span> | 138 | <span class="lead">Build deleted</span> |
| 131 | </div> | 139 | </div> |
| 132 | <button class="btn pull-right btn-info" ng-click="builds.splice(builds.indexOf(b), 1)">Close</button> | 140 | <button class="btn pull-right btn-info" ng-click="builds.splice(builds.indexOf(b), 1)">Close</button> |
| 133 | </case> | 141 | </case> |
| 134 | <case ng-switch-when="in progress"> | 142 | <case ng-switch-when="in progress"> |
| 135 | <div class="lead span3"> <span ng-repeat="t in b.targets">{[t.target]} </span> </div> | 143 | <div class="lead span3"> <span ng-repeat="t in b.targets" ng-include src="'target_display'"></span> </div> |
| 136 | <div class="span4" > | ||
| 137 | </div> | ||
| 138 | <div class="lead pull-right">Build starting shortly</div> | ||
| 139 | </case> | ||
| 140 | <case ng-switch-when="In Progress"> | ||
| 141 | <div class="span4" > | 144 | <div class="span4" > |
| 142 | <div class="progress" style="margin-top:5px;" data-toggle="tooltip" tooltip="{[b.completeper]}% of tasks complete"> | 145 | <div class="progress" style="margin-top:5px;" data-toggle="tooltip" tooltip="{[b.build[0].completeper]}% of tasks complete"> |
| 143 | <div style="width: {[b.completeper]}%;" class="bar"></div> | 146 | <div style="width: {[b.build[0].completeper]}%;" class="bar"></div> |
| 144 | </div> | 147 | </div> |
| 145 | </div> | 148 | </div> |
| 146 | <div class="lead pull-right">ETA: at {[b.eta]}</div> | 149 | <div class="lead pull-right">ETA: at {[b.build[0].eta|date:"shortDate"]}</div> |
| 147 | </case> | 150 | </case> |
| 148 | <case ng-switch-default=""> | 151 | <case ng-switch-when="completed"> |
| 149 | <div class="lead span3"><a href="{[b.build_page_url]}"><span ng-repeat="t in b.targets">{[t.target]} </span> </div></a> | 152 | <div class="lead span3"><a href="{[b.build[0].build_page_url]}"><span ng-repeat="t in b.targets" ng-include src="'target_display'"></span></a></div> |
| 150 | <div class="span2 lead"> | 153 | <div class="span2 lead"> |
| 151 | {[b.completed_on|date:'dd/MM/yy HH:mm']} | 154 | {[b.build[0].completed_on|date:'dd/MM/yy HH:mm']} |
| 152 | </div> | 155 | </div> |
| 153 | <div class="span2"><span>{[b.errors.len]}</span></div> | 156 | <div class="span2"><span><a href="{[b.build[0].build_page_url]}#errors" class="lead error" ng-if="b.build[0].errors">{[b.build[0].errors]}</a></span></div> |
| 154 | <div class="span2"><span>{[b.warnings.len]}</span></div> | 157 | <div class="span2"><span><a href="{[b.build[0].build_page_url]}#warnings" class="lead warning" ng-if="b.build[0].warnings">{[b.build[0].warnings]}</a></span></div> |
| 155 | <div> <span class="lead">Build time: {[b.build_time|date:"HH:mm"]}</span> | 158 | <div> <span class="lead">Build time: {[b.build[0].build_time|timediff]}</span> |
| 156 | <button class="btn pull-right" ng-class="{'Succeeded': 'btn-success', 'Failed': 'btn-danger'}[b.status]" | 159 | <button class="btn pull-right" ng-class="{'Succeeded': 'btn-success', 'Failed': 'btn-danger'}[b.build[0].status]" |
| 157 | ng-click="targetExistingBuild(b.targets)">Run again</button> | 160 | ng-click="targetExistingBuild(b.targets)">Run again</button> |
| 158 | 161 | ||
| 159 | </div> | 162 | </div> |
| 160 | </case> | 163 | </case> |
| 164 | <case ng-switch-default=""> | ||
| 165 | <div>FIXME!</div> | ||
| 166 | </case> | ||
| 161 | </switch> | 167 | </switch> |
| 162 | <div class="lead pull-right"> | 168 | <div class="lead pull-right"> |
| 163 | </div> | 169 | </div> |
diff --git a/bitbake/lib/toaster/toastergui/templates/targets.html b/bitbake/lib/toaster/toastergui/templates/targets.html index 3afdf0a5e9..32a644a743 100644 --- a/bitbake/lib/toaster/toastergui/templates/targets.html +++ b/bitbake/lib/toaster/toastergui/templates/targets.html | |||
| @@ -9,55 +9,74 @@ | |||
| 9 | {% block projectinfomain %} | 9 | {% block projectinfomain %} |
| 10 | <div class="page-header"> | 10 | <div class="page-header"> |
| 11 | <h1> | 11 | <h1> |
| 12 | All targets | 12 | {% if request.GET.filter and objects.paginator.count > 0 or request.GET.search and objects.paginator.count > 0 %} |
| 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> | 13 | {{objects.paginator.count}} target{{objects.paginator.count|pluralize}} found |
| 14 | {% elif request.GET.filter and objects.paginator.count == 0 or request.GET.search and objects.paginator.count == 0 %} | ||
| 15 | No targets found | ||
| 16 | {%else%} | ||
| 17 | All targets | ||
| 18 | {%endif%} | ||
| 19 | <i class="icon-question-sign get-help heading-help" title="This page lists all the targets compatible with " + {{project.release.name}} + " that Toaster knows about."></i> | ||
| 14 | </h1> | 20 | </h1> |
| 15 | </div> | 21 | </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">×</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 | 22 | ||
| 23 | <div id="zone1alerts"> | ||
| 24 | |||
| 25 | </div> | ||
| 26 | |||
| 27 | {% if objects.paginator.count == 0 %} | ||
| 28 | <div class="row-fluid"> | ||
| 29 | <div class="alert"> | ||
| 30 | <form class="no-results input-append" id="searchform"> | ||
| 31 | <input id="search" name="search" class="input-xxlarge" type="text" value="{{request.GET.search}}"/>{% if request.GET.search %}<a href="javascript:$('#search').val('');searchform.submit()" class="add-on btn" tabindex="-1"><i class="icon-remove"></i></a>{% endif %} | ||
| 32 | <button class="btn" type="submit" value="Search">Search</button> | ||
| 33 | <button class="btn btn-link" onclick="javascript:$('#search').val('');searchform.submit()">Show all targets</button> | ||
| 34 | </form> | ||
| 35 | </div> | ||
| 36 | </div> | ||
| 37 | |||
| 38 | {% else %} | ||
| 32 | 39 | ||
| 33 | {% include "basetable_top.html" %} | 40 | {% include "basetable_top.html" %} |
| 34 | {% for o in objects %} | 41 | {% for o in objects %} |
| 35 | <tr class="data"> | 42 | <tr class="data"> |
| 36 | <td class="target"> | 43 | <td class="target"> |
| 37 | {{o.name}} ({{o.id}}, {{o.up_id}}) | 44 | {{o.name}} |
| 38 | <a target="_blank" href="{{o.get_layersource_view_url}}"><i class="icon-share get-info"></i></a> | 45 | <a target="_blank" href="{{o.get_layersource_view_url}}"><i class="icon-share get-info"></i></a> |
| 39 | </td> | 46 | </td> |
| 40 | <td class="version">{{o.version}}</td> | 47 | <td class="version">{{o.version}}</td> |
| 41 | <td class="description">{{o.description}}</td> | 48 | <td class="description">{% if o.description %}{{o.description}}{% else %}{{o.summary}}{%endif%}</td> |
| 42 | <td class="recipe-file"> | 49 | <td class="recipe-file"> |
| 43 | <code>{{o.file_path}}</code> | 50 | <code>{{o.file_path}}</code> |
| 44 | <a href="{{o.get_vcs_link_url}}" target="_blank"><i class="icon-share get-info"></i></a> | 51 | <a href="{{o.get_vcs_link_url}}{{o.file_path}}" target="_blank"><i class="icon-share get-info"></i></a> |
| 45 | </td> | 52 | </td> |
| 46 | <td class="target-section">{{o.section}}</td> | 53 | <td class="target-section">{{o.section}}</td> |
| 47 | <td class="license">{{o.license}}</td> | 54 | <td class="license">{{o.license}}</td> |
| 48 | <td class="layer"><a href="#">{{o.layer_version.layer.name}}</a></td> | 55 | <td class="layer"><a href="{% url 'layerdetails' o.layer_version.id%}">{{o.layer_version.layer.name}}</a></td> |
| 49 | <td class="source">{{o.layer_source.name}}</td> | 56 | <td class="source">{{o.layer_source.name}}</td> |
| 50 | <td class="branch">{{o.layer_version.commit}}</td> | 57 | <td class="branch"> |
| 51 | <td class="build"> | 58 | {% if o.layer_version.up_branch %} |
| 52 | <a id="build-target" href="project-with-targets.html?target=3g-router-image" class="btn btn-block" style="display:none;"> | 59 | {{o.layer_version.up_branch.name}} |
| 53 | Build target | 60 | {% else %} |
| 54 | </a> | 61 | <a class="btn" |
| 55 | <a id="add-layer" href="#" class="btn btn-block nopop" title="1 layer added"> | 62 | data-content="<ul class='unstyled'> |
| 56 | <i class="icon-plus"></i> | 63 | <li>{{o.layer_version.commit}}</li> |
| 57 | Add layer | 64 | </ul>"> |
| 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> | 65 | {{o.layer_version.commit|truncatechars:13}} |
| 59 | </a> | 66 | </a> |
| 60 | </td> | 67 | {% endif %} |
| 68 | </td> | ||
| 69 | <td class="add-layer" value="{{o.pk}}" layerversion_id="{{o.layer_version.pk}}"> | ||
| 70 | <div id="layer-tooltip-{{o.pk}}" style="display: none; font-size: 11px; line-height: 1.3;" class="tooltip-inner">layer was modified</div> | ||
| 71 | <a href="{% url 'project' project.id %}#/targetbuild={{o.name}}" id="target-build-{{o.pk}}" class="btn btn-block remove-layer" style="display:none;" > | ||
| 72 | Build target | ||
| 73 | </a> | ||
| 74 | <a id="layer-add-{{o.pk}}" class="btn btn-block" style="display:none;" href="javascript:layerAdd({{o.layer_version.pk}}, '{{o.layer_version.layer.name}}', '{%url 'layerdetails' o.layer_version.pk%}', {{o.pk}})" > | ||
| 75 | <i class="icon-plus"></i> | ||
| 76 | Add layer | ||
| 77 | <i title="" class="icon-question-sign get-help" data-original-title="To build this target, you must first add the {{o.layer_version.layer.name}} layer to your project"></i> | ||
| 78 | </a> | ||
| 79 | </td> | ||
| 61 | </tr> | 80 | </tr> |
| 62 | {% endfor %} | 81 | {% endfor %} |
| 63 | {% include "basetable_bottom.html" %} | 82 | {% include "basetable_bottom.html" %} |
| @@ -65,122 +84,177 @@ | |||
| 65 | <!-- Modals --> | 84 | <!-- Modals --> |
| 66 | 85 | ||
| 67 | <!-- 'Layer dependencies modal' --> | 86 | <!-- 'Layer dependencies modal' --> |
| 68 | <div id="dependencies-message" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> | 87 | <div id="dependencies_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true"> |
| 88 | <form id="dependencies_modal_form"> | ||
| 69 | <div class="modal-header"> | 89 | <div class="modal-header"> |
| 70 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> | 90 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button> |
| 71 | <h3>meta-acer dependencies</h3> | 91 | <h3><span class="layer-name"></span> dependencies</h3> |
| 72 | </div> | 92 | </div> |
| 73 | <div class="modal-body"> | 93 | <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> | 94 | <p><strong class="layer-name"></strong> depends on some layers that are not added to your project. Select the ones you want to add:</p> |
| 75 | <ul class="unstyled"> | 95 | <ul class="unstyled" id="dependencies_list"> |
| 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> | 96 | </ul> |
| 89 | </div> | 97 | </div> |
| 90 | <div class="modal-footer"> | 98 | <div class="modal-footer"> |
| 91 | <button id="add-target-dependencies" type="submit" class="btn btn-primary" data-dismiss="modal" >Add targets</button> | 99 | <button class="btn btn-primary" type="submit">Add layers</button> |
| 92 | <button class="btn" data-dismiss="modal">Cancel</button> | 100 | <button class="btn" type="reset" data-dismiss="modal">Cancel</button> |
| 93 | </div> | 101 | </div> |
| 102 | </form> | ||
| 94 | </div> | 103 | </div> |
| 95 | 104 | ||
| 96 | <script src="assets/js/jquery-1.9.1.min.js" type='text/javascript'></script> | 105 | {% endif %} |
| 97 | <script src="assets/js/jquery.tablesorter.min.js" type='text/javascript'></script> | 106 | |
| 98 | <script src="assets/js/jquery-ui-1.10.3.custom.min.js"></script> | 107 | {% if project %} |
| 99 | <script src="assets/js/bootstrap.min.js" type='text/javascript'></script> | 108 | <script> |
| 100 | <script src="assets/js/prettify.js" type='text/javascript'></script> | 109 | |
| 101 | <script src="assets/js/jit.js" type='text/javascript'></script> | 110 | var tooltipUpdateText; |
| 102 | <script src="assets/js/main.js" type='text/javascript'></script> | 111 | |
| 103 | 112 | function _makeXHREditCall(data, onsuccess, onfail) { | |
| 104 | <script> | 113 | $.ajax( { |
| 105 | $(document).ready(function() { | 114 | type: "POST", |
| 106 | 115 | url: "{% url 'xhr_projectedit' project.id %}", | |
| 107 | //show or hide selected columns on load | 116 | data: data, |
| 108 | $("input:checkbox").each(function(){ | 117 | headers: { 'X-CSRFToken' : $.cookie('csrftoken')}, |
| 109 | var selectedType = $(this).val(); | 118 | success: function (_data) { |
| 110 | if($(this).is(":checked")){ | 119 | if (_data.error != "ok") { |
| 111 | $("."+selectedType).show(); | 120 | alert(_data.error); |
| 121 | } else { | ||
| 122 | updateButtons(_data.layers.map(function (e) {return e.id})); | ||
| 123 | if (onsuccess != undefined) onsuccess(_data); | ||
| 112 | } | 124 | } |
| 113 | else{ | 125 | }, |
| 114 | $("."+selectedType).hide(); | 126 | error: function (_data) { |
| 127 | alert("Call failed"); | ||
| 128 | console.log(_data); | ||
| 129 | } | ||
| 130 | }); | ||
| 131 | } | ||
| 132 | |||
| 133 | function show_alert(text, cls) { | ||
| 134 | $("#zone1alerts").html("<div class=\"alert alert-info lead\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">×</button>" + text + "</div>"); | ||
| 135 | } | ||
| 136 | |||
| 137 | |||
| 138 | function show_dependencies_modal(layerId, layerName, layerURL, dependencies) { | ||
| 139 | // update layer name | ||
| 140 | $('.layer-name').text(layerName); | ||
| 141 | var deplistHtml = ""; | ||
| 142 | for (var i = 0; i < dependencies.length; i++) { | ||
| 143 | deplistHtml += "<li><label class=\"checkbox\"><input name=\"dependencies\" value=\"" | ||
| 144 | deplistHtml += dependencies[i].id; | ||
| 145 | deplistHtml +="\" type=\"checkbox\" checked=\"checked\"/>"; | ||
| 146 | deplistHtml += dependencies[i].name; | ||
| 147 | deplistHtml += "</label></li>"; | ||
| 148 | } | ||
| 149 | $('#dependencies_list').html(deplistHtml); | ||
| 150 | |||
| 151 | var selected = [layerId]; | ||
| 152 | var layer_link_list = undefined; | ||
| 153 | |||
| 154 | $("#dependencies_modal_form").submit(function (e) { | ||
| 155 | e.preventDefault(); | ||
| 156 | $("input[name='dependencies']:checked").map(function () { selected.push(parseInt($(this).val()))}); | ||
| 157 | layer_link_list = "<a href='"+layerURL+"'>"+layerName+"</a>"; | ||
| 158 | if (selected.length > 1) { | ||
| 159 | tooltipUpdateText = "" + selected.length + " layers added"; | ||
| 160 | } else { | ||
| 161 | tooltipUpdateText = "1 layer added"; | ||
| 162 | } | ||
| 163 | |||
| 164 | for (var i = 0; i < selected.length; i++) { | ||
| 165 | for (var j = 0; j < dependencies.length; j++) { | ||
| 166 | if (dependencies[j].id == selected[i]) { | ||
| 167 | layer_link_list+= ", <a href='"+dependencies[j].layerdetailurl+"'>"+dependencies[j].name+"</a>" | ||
| 168 | break; | ||
| 169 | } | ||
| 115 | } | 170 | } |
| 171 | } | ||
| 172 | |||
| 173 | $('#dependencies_modal').modal('hide'); | ||
| 174 | |||
| 175 | {% if project %} | ||
| 176 | _makeXHREditCall({ 'layerAdd': selected.join(",") }, function onXHRSuccess() { | ||
| 177 | show_alert("You have added <strong>"+selected.length+"</strong> layer(s) to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>:" + layer_link_list); | ||
| 116 | }); | 178 | }); |
| 179 | {% endif %} | ||
| 117 | 180 | ||
| 118 | // enable add target button | 181 | }); |
| 119 | $('#add-target-with-deps').removeAttr('disabled'); | 182 | $('#dependencies_modal').modal('show'); |
| 183 | } | ||
| 120 | 184 | ||
| 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 | 185 | ||
| 133 | //turn edit columns dropdown into a multi-select menu | 186 | var pressedButton = undefined; |
| 134 | $('.dropdown-menu input, .dropdown-menu label').click(function(e) { | ||
| 135 | e.stopPropagation(); | ||
| 136 | }); | ||
| 137 | 187 | ||
| 138 | //show tooltip with applied filter | 188 | function layerAdd(layerId, layerName, layerURL, pressedButtonId) { |
| 139 | $('#filtered').tooltip({container:'table', placement:'bottom', delay:{hide:1500}, html:true}); | 189 | pressedButton = pressedButtonId; |
| 190 | $.ajax({ | ||
| 191 | url: '{% url "xhr_datatypeahead" %}', | ||
| 192 | data: {'type': 'layerdeps','value':layerId}, | ||
| 193 | success: function(_data) { | ||
| 194 | if (_data.error != "ok") { | ||
| 195 | alert(_data.error); | ||
| 196 | } else { | ||
| 197 | if (_data.list.length > 0) { | ||
| 198 | show_dependencies_modal(layerId, layerName, layerURL, _data.list); | ||
| 199 | } | ||
| 200 | else { | ||
| 201 | tooltipUpdateText = "1 layer added"; | ||
| 202 | _makeXHREditCall({ 'layerAdd': layerId }, function () { | ||
| 203 | show_alert("You have added <strong>1</strong> layer to <a href=\"{% url 'project' project.id%}\">{{project.name}}</a>: <a href=\""+layerURL+"\">" + layerName +"</a>"); | ||
| 204 | }); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | } | ||
| 208 | }) | ||
| 209 | } | ||
| 140 | 210 | ||
| 141 | $('#filtered').click(function() { | 211 | function buttonSet(id, state) { |
| 142 | $(this).tooltip('hide'); | 212 | var tohide, toshow; |
| 143 | }); | 213 | if (state == "add") |
| 214 | { | ||
| 215 | toshow = "#layer-add-"; | ||
| 216 | tohide = "#target-build-"; | ||
| 217 | } | ||
| 218 | else if (state == "build") | ||
| 219 | { | ||
| 220 | tohide = "#layer-add-"; | ||
| 221 | toshow = "#target-build-"; | ||
| 222 | } | ||
| 144 | 223 | ||
| 145 | //show target added tooltip | 224 | var previouslyvisible = $(tohide + id).is(":visible"); |
| 146 | $("#remove-target, #add-target, #add-target-with-deps2").tooltip({ trigger: 'manual' }); | 225 | if (previouslyvisible && id == pressedButton) { |
| 147 | 226 | $(tohide + id).fadeOut( function() { | |
| 148 | // add target without dependencies | 227 | $("#layer-tooltip-" + id).text(tooltipUpdateText); |
| 149 | $("#add-target").click(function(){ | 228 | $("#layer-tooltip-" + id).fadeIn().delay(2000).fadeOut(function(){ |
| 150 | $('#target-removed').hide(); | 229 | $(toshow + id).delay(300).fadeIn(); |
| 151 | $('#target-added').html('<button type="button" class="close" data-dismiss="alert">×</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 | }); | 230 | }); |
| 157 | }); | 231 | }); |
| 232 | } else { | ||
| 233 | $(tohide + id).hide(); | ||
| 234 | $("#layer-tooltip-" + id).hide(); | ||
| 235 | $(toshow + id).show(); | ||
| 236 | } | ||
| 237 | }; | ||
| 158 | 238 | ||
| 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">×</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 | 239 | ||
| 171 | // delete target | 240 | function updateButtons(projectLayers) { |
| 172 | $("#remove-target").click(function(){ | 241 | var displayedLayers = []; |
| 173 | $('#target-added').hide(); | 242 | $(".add-layer").map(function () { displayedLayers.push( { "l": parseInt($(this).attr('layerversion_id')), "i": parseInt($(this).attr('value'))})}); |
| 174 | $('#target-removed').show(); | 243 | for (var i=0; i < displayedLayers.length; i++) { |
| 175 | $('#remove-target').tooltip('show'); | 244 | if (projectLayers.indexOf(displayedLayers[i].l) > -1) { |
| 176 | $("#remove-target").hide(); | 245 | buttonSet(displayedLayers[i].i, "build"); |
| 177 | $(".add-targets .tooltip").delay(2000).fadeOut(function(){ | 246 | } |
| 178 | $("#add-target").delay(300).fadeIn(); | 247 | else { |
| 179 | }); | 248 | buttonSet(displayedLayers[i].i, "add"); |
| 180 | }); | 249 | } |
| 250 | } | ||
| 251 | } | ||
| 181 | 252 | ||
| 182 | }); | 253 | $(document).ready(function (){ |
| 254 | updateButtons({{projectlayerset}}); | ||
| 255 | }); | ||
| 183 | 256 | ||
| 184 | </script> | 257 | </script> |
| 258 | {%endif%} | ||
| 185 | 259 | ||
| 186 | {% endblock %} | 260 | {% endblock %} |
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index e568ee70ed..fb8075067a 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
| @@ -123,7 +123,7 @@ def _redirect_parameters(view, g, mandatory_parameters, *args, **kwargs): | |||
| 123 | params[i] = g[i] | 123 | params[i] = g[i] |
| 124 | for i in mandatory_parameters: | 124 | for i in mandatory_parameters: |
| 125 | if not i in params: | 125 | if not i in params: |
| 126 | params[i] = mandatory_parameters[i] | 126 | params[i] = urllib.unquote(str(mandatory_parameters[i])) |
| 127 | 127 | ||
| 128 | return redirect(url + "?%s" % urllib.urlencode(params), *args, **kwargs) | 128 | return redirect(url + "?%s" % urllib.urlencode(params), *args, **kwargs) |
| 129 | 129 | ||
| @@ -202,6 +202,7 @@ def _get_search_results(search_term, queryset, model): | |||
| 202 | 202 | ||
| 203 | search_objects.append(reduce(operator.or_, q_map)) | 203 | search_objects.append(reduce(operator.or_, q_map)) |
| 204 | search_object = reduce(operator.and_, search_objects) | 204 | search_object = reduce(operator.and_, search_objects) |
| 205 | print "search objects", search_object | ||
| 205 | queryset = queryset.filter(search_object) | 206 | queryset = queryset.filter(search_object) |
| 206 | 207 | ||
| 207 | return queryset | 208 | return queryset |
| @@ -1914,8 +1915,7 @@ if toastermain.settings.MANAGED: | |||
| 1914 | login(request, user) | 1915 | login(request, user) |
| 1915 | 1916 | ||
| 1916 | # save the project | 1917 | # save the project |
| 1917 | prj = Project.objects.create_project(name = request.POST['projectname'], | 1918 | prj = Project.objects.create_project(name = request.POST['projectname'], release = Release.objects.get(pk = request.POST['projectversion'])) |
| 1918 | release = Release.objects.get(pk = request.POST['projectversion'])) | ||
| 1919 | prj.user_id = request.user.pk | 1919 | prj.user_id = request.user.pk |
| 1920 | prj.save() | 1920 | prj.save() |
| 1921 | return redirect(reverse(project, args = (prj.pk,)) + "#/newproject") | 1921 | return redirect(reverse(project, args = (prj.pk,)) + "#/newproject") |
| @@ -1933,36 +1933,21 @@ if toastermain.settings.MANAGED: | |||
| 1933 | 1933 | ||
| 1934 | 1934 | ||
| 1935 | def _project_recent_build_list(prj): | 1935 | def _project_recent_build_list(prj): |
| 1936 | # build requests not yet started | 1936 | return map(lambda x: { |
| 1937 | return (map(lambda x: { | ||
| 1938 | "id": x.pk, | ||
| 1939 | "targets" : map(lambda y: {"target": y.target }, x.brtarget_set.all()), | ||
| 1940 | "status": x.get_state_display(), | ||
| 1941 | }, prj.buildrequest_set.filter(state__lt = BuildRequest.REQ_INPROGRESS).order_by("-pk")) + | ||
| 1942 | # build requests started, but with no build yet | ||
| 1943 | map(lambda x: { | ||
| 1944 | "id": x.pk, | 1937 | "id": x.pk, |
| 1945 | "targets" : map(lambda y: {"target": y.target }, x.brtarget_set.all()), | 1938 | "targets" : map(lambda y: {"target": y.target, "task": y.task }, x.brtarget_set.all()), |
| 1946 | "status": x.get_state_display(), | ||
| 1947 | }, prj.buildrequest_set.filter(state = BuildRequest.REQ_INPROGRESS, build = None).order_by("-pk")) + | ||
| 1948 | # build requests that failed | ||
| 1949 | map(lambda x: { | ||
| 1950 | "id": x.pk, | ||
| 1951 | "targets" : map(lambda y: {"target": y.target }, x.brtarget_set.all()), | ||
| 1952 | "status": x.get_state_display(), | 1939 | "status": x.get_state_display(), |
| 1953 | "errors": map(lambda y: {"type": y.errtype, "msg": y.errmsg, "tb": y.traceback}, x.brerror_set.all()), | 1940 | "errors": map(lambda y: {"type": y.errtype, "msg": y.errmsg, "tb": y.traceback}, x.brerror_set.all()), |
| 1954 | }, prj.buildrequest_set.filter(state = BuildRequest.REQ_FAILED).order_by("-pk")) + | 1941 | "build" : map( lambda y: {"id": y.pk, |
| 1955 | # and already made builds | 1942 | "status": y.get_outcome_display(), |
| 1956 | map(lambda x: { | 1943 | "completed_on" : y.completed_on.strftime('%s')+"000", |
| 1957 | "id": x.pk, | 1944 | "build_time" : (y.completed_on - y.started_on).total_seconds(), |
| 1958 | "targets": map(lambda y: {"target": y.target }, x.target_set.all()), | 1945 | "build_page_url" : reverse('builddashboard', args=(y.pk,)), |
| 1959 | "status": x.get_outcome_display(), | 1946 | "errors": y.errors_no, |
| 1960 | "completed_on" : x.completed_on.strftime('%s')+"000", | 1947 | "warnings": y.warnings_no, |
| 1961 | "build_time" : (x.completed_on - x.started_on).total_seconds(), | 1948 | "completeper": y.completeper(), |
| 1962 | "build_page_url" : reverse('builddashboard', args=(x.pk,)), | 1949 | "eta": y.eta().ctime()}, Build.objects.filter(buildrequest = x)), |
| 1963 | "completeper": x.completeper(), | 1950 | }, prj.buildrequest_set.order_by("-pk")[:5]) |
| 1964 | "eta": x.eta().ctime(), | ||
| 1965 | }, prj.build_set.all())) | ||
| 1966 | 1951 | ||
| 1967 | 1952 | ||
| 1968 | # Shows the edit project page | 1953 | # Shows the edit project page |
| @@ -2025,10 +2010,14 @@ if toastermain.settings.MANAGED: | |||
| 2025 | 2010 | ||
| 2026 | if 'buildCancel' in request.POST: | 2011 | if 'buildCancel' in request.POST: |
| 2027 | for i in request.POST['buildCancel'].strip().split(" "): | 2012 | for i in request.POST['buildCancel'].strip().split(" "): |
| 2028 | br = BuildRequest.objects.select_for_update().get(project = prj, pk = i, state__lte = BuildRequest.REQ_QUEUED) | 2013 | try: |
| 2029 | print "selected for delete", br.pk | 2014 | br = BuildRequest.objects.select_for_update().get(project = prj, pk = i, state__lte = BuildRequest.REQ_QUEUED) |
| 2030 | br.delete() | 2015 | print "selected for delete", br.pk |
| 2031 | print "selected for delete", br.pk | 2016 | br.delete() |
| 2017 | print "selected for delete", br.pk | ||
| 2018 | except BuildRequest.DoesNotExist: | ||
| 2019 | pass | ||
| 2020 | |||
| 2032 | 2021 | ||
| 2033 | if 'targets' in request.POST: | 2022 | if 'targets' in request.POST: |
| 2034 | ProjectTarget.objects.filter(project = prj).delete() | 2023 | ProjectTarget.objects.filter(project = prj).delete() |
| @@ -2059,7 +2048,7 @@ if toastermain.settings.MANAGED: | |||
| 2059 | # remove layers | 2048 | # remove layers |
| 2060 | if 'layerDel' in request.POST: | 2049 | if 'layerDel' in request.POST: |
| 2061 | for t in request.POST['layerDel'].strip().split(" "): | 2050 | for t in request.POST['layerDel'].strip().split(" "): |
| 2062 | pt = ProjectLayer.objects.get(project = prj, layercommit_id = int(t)).delete() | 2051 | pt = ProjectLayer.objects.filter(project = prj, layercommit_id = int(t)).delete() |
| 2063 | 2052 | ||
| 2064 | if 'projectName' in request.POST: | 2053 | if 'projectName' in request.POST: |
| 2065 | prj.name = request.POST['projectName'] | 2054 | prj.name = request.POST['projectName'] |
| @@ -2071,8 +2060,8 @@ if toastermain.settings.MANAGED: | |||
| 2071 | prj.save() | 2060 | prj.save() |
| 2072 | # we need to change the layers | 2061 | # we need to change the layers |
| 2073 | for i in prj.projectlayer_set.all(): | 2062 | for i in prj.projectlayer_set.all(): |
| 2074 | # find and add a similarly-named layer from the same layer source on the new branch | 2063 | # find and add a similarly-named layer on the new branch |
| 2075 | lv = Layer_Version.objects.filter(layer_source = i.layercommit.layer_source, layer__name = i.layercommit.layer.name, up_branch__in = Branch.objects.filter(name = prj.release.branch)) | 2064 | lv = Layer_Version.objects.filter(layer__name = i.layercommit.layer.name, up_branch__release = prj.release) |
| 2076 | if lv.count() == 1: | 2065 | if lv.count() == 1: |
| 2077 | ProjectLayer.objects.get_or_create(project = prj, layercommit = lv[0]) | 2066 | ProjectLayer.objects.get_or_create(project = prj, layercommit = lv[0]) |
| 2078 | # get rid of the old entry | 2067 | # get rid of the old entry |
| @@ -2095,17 +2084,19 @@ if toastermain.settings.MANAGED: | |||
| 2095 | @csrf_exempt | 2084 | @csrf_exempt |
| 2096 | def xhr_datatypeahead(request): | 2085 | def xhr_datatypeahead(request): |
| 2097 | try: | 2086 | try: |
| 2087 | # returns layers for current project release that are not in the project set | ||
| 2098 | if request.GET['type'] == "layers": | 2088 | if request.GET['type'] == "layers": |
| 2099 | queryset_all = Layer_Version.objects.all() | 2089 | queryset_all = Layer_Version.objects.all() |
| 2100 | if 'project_id' in request.session: | 2090 | if 'project_id' in request.session: |
| 2101 | prj = Project.objects.get(pk = request.session['project_id']) | 2091 | prj = Project.objects.get(pk = request.session['project_id']) |
| 2102 | queryset_all = queryset_all.filter(up_branch__in = Branch.objects.filter(name = prj.release.name)).exclude(pk__in = map(lambda x: x.layercommit_id, prj.projectlayer_set.all())) | 2092 | queryset_all = queryset_all.filter(up_branch__release = prj.release).exclude(pk__in = map(lambda x: x.layercommit_id, prj.projectlayer_set.all())) |
| 2103 | queryset_all = queryset_all.filter(layer__name__icontains=request.GET.get('value','')) | 2093 | queryset_all = queryset_all.filter(layer__name__icontains=request.GET.get('value','')) |
| 2104 | return HttpResponse(json.dumps( { "error":"ok", | 2094 | return HttpResponse(json.dumps( { "error":"ok", |
| 2105 | "list" : map( lambda x: {"id": x.pk, "name": x.layer.name, "detail": "(" + x.layer.layer_source.name + (")" if x.up_branch == None else " | "+x.up_branch.name+")")}, | 2095 | "list" : map( lambda x: {"id": x.pk, "name": x.layer.name, "detail": "(" + x.layer.layer_source.name + (")" if x.up_branch == None else " | "+x.up_branch.name+")")}, |
| 2106 | queryset_all[:8]) | 2096 | queryset_all[:8]) |
| 2107 | }), content_type = "application/json") | 2097 | }), content_type = "application/json") |
| 2108 | 2098 | ||
| 2099 | # returns layer dependencies for a layer, excluding current project layers | ||
| 2109 | if request.GET['type'] == "layerdeps": | 2100 | if request.GET['type'] == "layerdeps": |
| 2110 | queryset_all = LayerVersionDependency.objects.filter(layer_version_id = request.GET['value']) | 2101 | queryset_all = LayerVersionDependency.objects.filter(layer_version_id = request.GET['value']) |
| 2111 | 2102 | ||
| @@ -2122,6 +2113,7 @@ if toastermain.settings.MANAGED: | |||
| 2122 | map(lambda x: x.depends_on, queryset_all)) | 2113 | map(lambda x: x.depends_on, queryset_all)) |
| 2123 | }), content_type = "application/json") | 2114 | }), content_type = "application/json") |
| 2124 | 2115 | ||
| 2116 | # returns layer versions that would be deleted on the new release__pk | ||
| 2125 | if request.GET['type'] == "versionlayers": | 2117 | if request.GET['type'] == "versionlayers": |
| 2126 | if not 'project_id' in request.session: | 2118 | if not 'project_id' in request.session: |
| 2127 | raise Exception("This call cannot makes no sense outside a project context") | 2119 | raise Exception("This call cannot makes no sense outside a project context") |
| @@ -2129,8 +2121,8 @@ if toastermain.settings.MANAGED: | |||
| 2129 | retval = [] | 2121 | retval = [] |
| 2130 | prj = Project.objects.get(pk = request.session['project_id']) | 2122 | prj = Project.objects.get(pk = request.session['project_id']) |
| 2131 | for i in prj.projectlayer_set.all(): | 2123 | for i in prj.projectlayer_set.all(): |
| 2132 | lv = Layer_Version.objects.filter(layer_source = i.layercommit.layer_source, layer__name = i.layercommit.layer.name, up_branch__in = Branch.objects.filter(name = Release.objects.get(pk=request.GET['value']).branch)) | 2124 | lv = Layer_Version.objects.filter(layer__name = i.layercommit.layer.name, up_branch__release__pk=request.GET['value']) |
| 2133 | if lv.count() != 1: | 2125 | if lv.count() != 1: # there is no layer_version with the new release id, and the same name |
| 2134 | retval.append(i) | 2126 | retval.append(i) |
| 2135 | 2127 | ||
| 2136 | return HttpResponse(json.dumps( {"error":"ok", | 2128 | return HttpResponse(json.dumps( {"error":"ok", |
| @@ -2138,14 +2130,14 @@ if toastermain.settings.MANAGED: | |||
| 2138 | lambda x: {"id": x.layercommit.pk, "name": x.layercommit.layer.name, "detail": "(" + x.layercommit.layer.layer_source.name + (")" if x.layercommit.up_branch == None else " | "+x.layercommit.up_branch.name+")")}, | 2130 | lambda x: {"id": x.layercommit.pk, "name": x.layercommit.layer.name, "detail": "(" + x.layercommit.layer.layer_source.name + (")" if x.layercommit.up_branch == None else " | "+x.layercommit.up_branch.name+")")}, |
| 2139 | retval) }), content_type = "application/json") | 2131 | retval) }), content_type = "application/json") |
| 2140 | 2132 | ||
| 2141 | 2133 | # returns targets provided by current project layers | |
| 2142 | if request.GET['type'] == "targets": | 2134 | if request.GET['type'] == "targets": |
| 2143 | queryset_all = Recipe.objects.all() | 2135 | queryset_all = Recipe.objects.all() |
| 2144 | if 'project_id' in request.session: | 2136 | if 'project_id' in request.session: |
| 2145 | queryset_all = queryset_all.filter(layer_version__layer__in = map(lambda x: x.layercommit.layer, ProjectLayer.objects.filter(project_id=request.session['project_id']))) | 2137 | queryset_all = queryset_all.filter(layer_version__layer__in = map(lambda x: x.layercommit.layer, ProjectLayer.objects.filter(project_id=request.session['project_id']))) |
| 2146 | return HttpResponse(json.dumps({ "error":"ok", | 2138 | return HttpResponse(json.dumps({ "error":"ok", |
| 2147 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, | 2139 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, |
| 2148 | queryset_all.filter(name__istartswith=request.GET.get('value',''))[:8]), | 2140 | queryset_all.filter(name__icontains=request.GET.get('value',''))[:8]), |
| 2149 | 2141 | ||
| 2150 | }), content_type = "application/json") | 2142 | }), content_type = "application/json") |
| 2151 | 2143 | ||
| @@ -2155,7 +2147,7 @@ if toastermain.settings.MANAGED: | |||
| 2155 | queryset_all = queryset_all.filter(layer_version__layer__in = map(lambda x: x.layercommit.layer, ProjectLayer.objects.filter(project_id=request.session['project_id']))) | 2147 | queryset_all = queryset_all.filter(layer_version__layer__in = map(lambda x: x.layercommit.layer, ProjectLayer.objects.filter(project_id=request.session['project_id']))) |
| 2156 | return HttpResponse(json.dumps({ "error":"ok", | 2148 | return HttpResponse(json.dumps({ "error":"ok", |
| 2157 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, | 2149 | "list" : map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ (" | " + x.layer_version.up_branch.name + "]" if x.layer_version.up_branch is not None else "]")}, |
| 2158 | queryset_all.filter(name__istartswith=request.GET.get('value',''))[:8]), | 2150 | queryset_all.filter(name__icontains=request.GET.get('value',''))[:8]), |
| 2159 | 2151 | ||
| 2160 | }), content_type = "application/json") | 2152 | }), content_type = "application/json") |
| 2161 | 2153 | ||
| @@ -2173,11 +2165,15 @@ if toastermain.settings.MANAGED: | |||
| 2173 | 2165 | ||
| 2174 | 2166 | ||
| 2175 | def layers(request): | 2167 | def layers(request): |
| 2168 | if not 'project_id' in request.session: | ||
| 2169 | raise Exception("invalid page: cannot show page without a project") | ||
| 2170 | |||
| 2176 | template = "layers.html" | 2171 | template = "layers.html" |
| 2177 | # define here what parameters the view needs in the GET portion in order to | 2172 | # define here what parameters the view needs in the GET portion in order to |
| 2178 | # be able to display something. 'count' and 'page' are mandatory for all views | 2173 | # be able to display something. 'count' and 'page' are mandatory for all views |
| 2179 | # that use paginators. | 2174 | # that use paginators. |
| 2180 | mandatory_parameters = { 'count': 10, 'page' : 1, 'orderby' : 'layer__name:+' }; | 2175 | (pagesize, orderby) = _get_parameters_values(request, 100, 'layer__name:+') |
| 2176 | mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby }; | ||
| 2181 | retval = _verify_parameters( request.GET, mandatory_parameters ) | 2177 | retval = _verify_parameters( request.GET, mandatory_parameters ) |
| 2182 | if retval: | 2178 | if retval: |
| 2183 | return _redirect_parameters( 'layers', request.GET, mandatory_parameters) | 2179 | return _redirect_parameters( 'layers', request.GET, mandatory_parameters) |
| @@ -2187,18 +2183,9 @@ if toastermain.settings.MANAGED: | |||
| 2187 | (filter_string, search_term, ordering_string) = _search_tuple(request, Layer_Version) | 2183 | (filter_string, search_term, ordering_string) = _search_tuple(request, Layer_Version) |
| 2188 | 2184 | ||
| 2189 | queryset_all = Layer_Version.objects.all() | 2185 | queryset_all = Layer_Version.objects.all() |
| 2190 | # mock an empty Project if we are outside project context | ||
| 2191 | class _mockProject(object): | ||
| 2192 | id = -1 | ||
| 2193 | class _mockManager(object): | ||
| 2194 | def all(self): | ||
| 2195 | return [] | ||
| 2196 | projectlayer_set = _mockManager() | ||
| 2197 | prj = _mockProject() | ||
| 2198 | 2186 | ||
| 2199 | if 'project_id' in request.session: | 2187 | prj = Project.objects.get(pk = request.session['project_id']) |
| 2200 | prj = Project.objects.get(pk = request.session['project_id']) | 2188 | queryset_all = queryset_all.filter(up_branch__release = prj.release) |
| 2201 | queryset_all = queryset_all.filter(up_branch__in = Branch.objects.filter(name = prj.release.name)) | ||
| 2202 | 2189 | ||
| 2203 | queryset_with_search = _get_queryset(Layer_Version, queryset_all, None, search_term, ordering_string, '-layer__name') | 2190 | queryset_with_search = _get_queryset(Layer_Version, queryset_all, None, search_term, ordering_string, '-layer__name') |
| 2204 | queryset = _get_queryset(Layer_Version, queryset_all, filter_string, search_term, ordering_string, '-layer__name') | 2191 | queryset = _get_queryset(Layer_Version, queryset_all, filter_string, search_term, ordering_string, '-layer__name') |
| @@ -2265,7 +2252,6 @@ if toastermain.settings.MANAGED: | |||
| 2265 | 2252 | ||
| 2266 | } | 2253 | } |
| 2267 | }, | 2254 | }, |
| 2268 | |||
| 2269 | ] | 2255 | ] |
| 2270 | } | 2256 | } |
| 2271 | 2257 | ||
| @@ -2279,31 +2265,30 @@ if toastermain.settings.MANAGED: | |||
| 2279 | return render(request, template, context) | 2265 | return render(request, template, context) |
| 2280 | 2266 | ||
| 2281 | def targets(request): | 2267 | def targets(request): |
| 2282 | template = "targets.html" | 2268 | if not 'project_id' in request.session: |
| 2283 | # define here what parameters the view needs in the GET portion in order to | 2269 | raise Exception("invalid page: cannot show page without a project") |
| 2284 | # be able to display something. 'count' and 'page' are mandatory for all views | 2270 | |
| 2285 | # that use paginators. | 2271 | template = 'targets.html' |
| 2286 | mandatory_parameters = { 'count': 10, 'page' : 1, 'orderby' : 'name:+' }; | 2272 | (pagesize, orderby) = _get_parameters_values(request, 100, 'name:+') |
| 2273 | mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby } | ||
| 2287 | retval = _verify_parameters( request.GET, mandatory_parameters ) | 2274 | retval = _verify_parameters( request.GET, mandatory_parameters ) |
| 2288 | if retval: | 2275 | if retval: |
| 2289 | return _redirect_parameters( 'targets', request.GET, mandatory_parameters) | 2276 | return _redirect_parameters( 'targets', request.GET, mandatory_parameters) |
| 2290 | |||
| 2291 | # boilerplate code that takes a request for an object type and returns a queryset | ||
| 2292 | # for that object type. copypasta for all needed table searches | ||
| 2293 | (filter_string, search_term, ordering_string) = _search_tuple(request, Recipe) | 2277 | (filter_string, search_term, ordering_string) = _search_tuple(request, Recipe) |
| 2294 | 2278 | ||
| 2295 | queryset_all = Recipe.objects.all() | 2279 | prj = Project.objects.get(pk = request.session['project_id']) |
| 2296 | if 'project_id' in request.session: | 2280 | queryset_all = Recipe.objects.filter(Q(layer_version__up_branch__release = prj.release) | Q(layer_version__build__in = prj.build_set.all())) |
| 2297 | queryset_all = queryset_all.filter(Q(layer_version__up_branch__in = Branch.objects.filter(name = Project.objects.get(pk=request.session['project_id']).release.name)) | Q(layer_version__build__in = Project.objects.get(pk = request.session['project_id']).build_set.all())) | ||
| 2298 | 2281 | ||
| 2299 | queryset_with_search = _get_queryset(Recipe, queryset_all, None, search_term, ordering_string, '-name') | 2282 | queryset_with_search = _get_queryset(Recipe, queryset_all, None, search_term, ordering_string, '-name') |
| 2300 | queryset = _get_queryset(Recipe, queryset_all, filter_string, search_term, ordering_string, '-name') | 2283 | |
| 2284 | queryset_with_search.prefetch_related("layer_source") | ||
| 2301 | 2285 | ||
| 2302 | # retrieve the objects that will be displayed in the table; targets a paginator and gets a page range to display | 2286 | # retrieve the objects that will be displayed in the table; targets a paginator and gets a page range to display |
| 2303 | target_info = _build_page_range(Paginator(queryset, request.GET.get('count', 10)),request.GET.get('page', 1)) | 2287 | target_info = _build_page_range(Paginator(queryset_with_search, request.GET.get('count', 10)),request.GET.get('page', 1)) |
| 2304 | 2288 | ||
| 2305 | 2289 | ||
| 2306 | context = { | 2290 | context = { |
| 2291 | 'projectlayerset' : json.dumps(map(lambda x: x.layercommit.id, prj.projectlayer_set.all())), | ||
| 2307 | 'objects' : target_info, | 2292 | 'objects' : target_info, |
| 2308 | 'objectname' : "targets", | 2293 | 'objectname' : "targets", |
| 2309 | 'default_orderby' : 'name:+', | 2294 | 'default_orderby' : 'name:+', |
| @@ -2329,13 +2314,19 @@ if toastermain.settings.MANAGED: | |||
| 2329 | { 'name': 'Section', | 2314 | { 'name': 'Section', |
| 2330 | 'clclass': 'target-section', | 2315 | 'clclass': 'target-section', |
| 2331 | 'hidden': 1, | 2316 | 'hidden': 1, |
| 2317 | 'orderfield': _get_toggle_order(request, "section"), | ||
| 2318 | 'ordericon': _get_toggle_order_icon(request, "section"), | ||
| 2332 | }, | 2319 | }, |
| 2333 | { 'name': 'License', | 2320 | { 'name': 'License', |
| 2334 | 'clclass': 'license', | 2321 | 'clclass': 'license', |
| 2335 | 'hidden': 1, | 2322 | 'hidden': 1, |
| 2323 | 'orderfield': _get_toggle_order(request, "license"), | ||
| 2324 | 'ordericon': _get_toggle_order_icon(request, "license"), | ||
| 2336 | }, | 2325 | }, |
| 2337 | { 'name': 'Layer', | 2326 | { 'name': 'Layer', |
| 2338 | 'clclass': 'layer', | 2327 | 'clclass': 'layer', |
| 2328 | 'orderfield': _get_toggle_order(request, "layer_version__layer__name"), | ||
| 2329 | 'ordericon': _get_toggle_order_icon(request, "layer_version__layer__name"), | ||
| 2339 | }, | 2330 | }, |
| 2340 | { 'name': 'Layer source', | 2331 | { 'name': 'Layer source', |
| 2341 | 'clclass': 'source', | 2332 | 'clclass': 'source', |
| @@ -2345,20 +2336,32 @@ if toastermain.settings.MANAGED: | |||
| 2345 | 'filter': { | 2336 | 'filter': { |
| 2346 | 'class': 'target', | 2337 | 'class': 'target', |
| 2347 | 'label': 'Show:', | 2338 | 'label': 'Show:', |
| 2348 | '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()), | 2339 | 'options': map(lambda x: ("Targets provided by " + x.name + " layers", 'layer_source__pk:' + str(x.id), queryset_with_search.filter(layer_source__pk = x.id).count() ), LayerSource.objects.all()), |
| 2349 | } | 2340 | } |
| 2350 | }, | 2341 | }, |
| 2351 | { 'name': 'Branch, tag or commit', | 2342 | { 'name': 'Branch, tag or commit', |
| 2352 | 'clclass': 'branch', | 2343 | 'clclass': 'branch', |
| 2353 | 'hidden': 1, | 2344 | 'hidden': 1, |
| 2354 | }, | 2345 | }, |
| 2346 | ] | ||
| 2347 | } | ||
| 2348 | |||
| 2349 | if 'project_id' in request.session: | ||
| 2350 | context['tablecols'] += [ | ||
| 2355 | { 'name': 'Build', | 2351 | { 'name': 'Build', |
| 2356 | 'dclass': 'span2', | 2352 | 'dclass': 'span2', |
| 2357 | 'qhelp': "Add or delete targets to / from your project ", | 2353 | 'qhelp': "Add or delete targets to / from your project ", |
| 2358 | }, | 2354 | 'filter': { |
| 2355 | 'class': 'add-layer', | ||
| 2356 | 'label': 'Show:', | ||
| 2357 | 'options': [ | ||
| 2358 | ('Targets provided by layers added to this project', "layer_version__projectlayer__project:" + str(prj.id), queryset_with_search.filter(layer_version__projectlayer__project = prj.id).count()), | ||
| 2359 | ('Targets provided by layers not added to this project', "layer_version__projectlayer__project:NOT" + str(prj.id), queryset_with_search.exclude(layer_version__projectlayer__project = prj.id).count()), | ||
| 2360 | ] | ||
| 2361 | |||
| 2362 | } | ||
| 2363 | }, ] | ||
| 2359 | 2364 | ||
| 2360 | ] | ||
| 2361 | } | ||
| 2362 | 2365 | ||
| 2363 | return render(request, template, context) | 2366 | return render(request, template, context) |
| 2364 | 2367 | ||
| @@ -2378,7 +2381,7 @@ if toastermain.settings.MANAGED: | |||
| 2378 | 2381 | ||
| 2379 | queryset_all = Machine.objects.all() | 2382 | queryset_all = Machine.objects.all() |
| 2380 | # if 'project_id' in request.session: | 2383 | # if 'project_id' in request.session: |
| 2381 | # queryset_all = queryset_all.filter(Q(layer_version__up_branch__in = Branch.objects.filter(name = Project.objects.get(request.session['project_id']).release.name)) | Q(layer_version__build__in = Project.objects.get(request.session['project_id']).build_set.all())) | 2384 | # queryset_all = queryset_all.filter(Q(layer_version__up_branch__release = Project.objects.get(request.session['project_id']).release) | Q(layer_version__build__in = Project.objects.get(request.session['project_id']).build_set.all())) |
| 2382 | 2385 | ||
| 2383 | queryset_with_search = _get_queryset(Machine, queryset_all, None, search_term, ordering_string, '-name') | 2386 | queryset_with_search = _get_queryset(Machine, queryset_all, None, search_term, ordering_string, '-name') |
| 2384 | queryset = _get_queryset(Machine, queryset_all, filter_string, search_term, ordering_string, '-name') | 2387 | queryset = _get_queryset(Machine, queryset_all, filter_string, search_term, ordering_string, '-name') |
| @@ -2643,7 +2646,7 @@ if toastermain.settings.MANAGED: | |||
| 2643 | def projects(request): | 2646 | def projects(request): |
| 2644 | template="projects.html" | 2647 | template="projects.html" |
| 2645 | 2648 | ||
| 2646 | (pagesize, orderby) = _get_parameters_values(request, 10, 'updated:-') | 2649 | (pagesize, orderby) = _get_parameters_values(request, 10, 'updated:+') |
| 2647 | mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby } | 2650 | mandatory_parameters = { 'count': pagesize, 'page' : 1, 'orderby' : orderby } |
| 2648 | retval = _verify_parameters( request.GET, mandatory_parameters ) | 2651 | retval = _verify_parameters( request.GET, mandatory_parameters ) |
| 2649 | if retval: | 2652 | if retval: |
| @@ -2654,8 +2657,8 @@ if toastermain.settings.MANAGED: | |||
| 2654 | # boilerplate code that takes a request for an object type and returns a queryset | 2657 | # boilerplate code that takes a request for an object type and returns a queryset |
| 2655 | # for that object type. copypasta for all needed table searches | 2658 | # for that object type. copypasta for all needed table searches |
| 2656 | (filter_string, search_term, ordering_string) = _search_tuple(request, Project) | 2659 | (filter_string, search_term, ordering_string) = _search_tuple(request, Project) |
| 2657 | queryset_with_search = _get_queryset(Project, queryset_all, None, search_term, ordering_string, 'updated:-') | 2660 | queryset_with_search = _get_queryset(Project, queryset_all, None, search_term, ordering_string, '-updated') |
| 2658 | queryset = _get_queryset(Project, queryset_all, filter_string, search_term, ordering_string, 'updated:-') | 2661 | queryset = _get_queryset(Project, queryset_all, filter_string, search_term, ordering_string, '-updated') |
| 2659 | 2662 | ||
| 2660 | # retrieve the objects that will be displayed in the table; projects a paginator and gets a page range to display | 2663 | # retrieve the objects that will be displayed in the table; projects a paginator and gets a page range to display |
| 2661 | project_info = _build_page_range(Paginator(queryset, pagesize), request.GET.get('page', 1)) | 2664 | project_info = _build_page_range(Paginator(queryset, pagesize), request.GET.get('page', 1)) |
