diff options
Diffstat (limited to 'bitbake/lib/toaster/toastergui/views.py')
| -rw-r--r-- | bitbake/lib/toaster/toastergui/views.py | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index a123eb5095..d54c66be81 100644 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
| @@ -103,8 +103,11 @@ def _get_filtering_query(filter_string): | |||
| 103 | querydict = dict(zip(keys, values)) | 103 | querydict = dict(zip(keys, values)) |
| 104 | return reduce(lambda x, y: x & y, map(lambda x: __get_q_for_val(k, querydict[k]),[k for k in querydict])) | 104 | return reduce(lambda x, y: x & y, map(lambda x: __get_q_for_val(k, querydict[k]),[k for k in querydict])) |
| 105 | 105 | ||
| 106 | def _get_toggle_order(request, orderkey): | 106 | def _get_toggle_order(request, orderkey, reverse = False): |
| 107 | return "%s:-" % orderkey if request.GET.get('orderby', "") == "%s:+" % orderkey else "%s:+" % orderkey | 107 | if reverse: |
| 108 | return "%s:+" % orderkey if request.GET.get('orderby', "") == "%s:-" % orderkey else "%s:-" % orderkey | ||
| 109 | else: | ||
| 110 | return "%s:-" % orderkey if request.GET.get('orderby', "") == "%s:+" % orderkey else "%s:+" % orderkey | ||
| 108 | 111 | ||
| 109 | # we check that the input comes in a valid form that we can recognize | 112 | # we check that the input comes in a valid form that we can recognize |
| 110 | def _validate_input(input, model): | 113 | def _validate_input(input, model): |
| @@ -163,12 +166,12 @@ def _search_tuple(request, model): | |||
| 163 | 166 | ||
| 164 | 167 | ||
| 165 | # returns a lazy-evaluated queryset for a filter/search/order combination | 168 | # returns a lazy-evaluated queryset for a filter/search/order combination |
| 166 | def _get_queryset(model, filter_string, search_term, ordering_string): | 169 | def _get_queryset(model, queryset, filter_string, search_term, ordering_string): |
| 167 | if filter_string: | 170 | if filter_string: |
| 168 | filter_query = _get_filtering_query(filter_string) | 171 | filter_query = _get_filtering_query(filter_string) |
| 169 | queryset = model.objects.filter(filter_query) | 172 | queryset = queryset.filter(filter_query) |
| 170 | else: | 173 | else: |
| 171 | queryset = model.objects.all() | 174 | queryset = queryset.all() |
| 172 | 175 | ||
| 173 | if search_term: | 176 | if search_term: |
| 174 | queryset = _get_search_results(search_term, queryset, model) | 177 | queryset = _get_search_results(search_term, queryset, model) |
| @@ -196,16 +199,21 @@ def builds(request): | |||
| 196 | # boilerplate code that takes a request for an object type and returns a queryset | 199 | # boilerplate code that takes a request for an object type and returns a queryset |
| 197 | # for that object type. copypasta for all needed table searches | 200 | # for that object type. copypasta for all needed table searches |
| 198 | (filter_string, search_term, ordering_string) = _search_tuple(request, Build) | 201 | (filter_string, search_term, ordering_string) = _search_tuple(request, Build) |
| 199 | queryset = _get_queryset(Build, filter_string, search_term, ordering_string) | 202 | queryset = Build.objects.exclude(outcome = Build.IN_PROGRESS) |
| 203 | queryset = _get_queryset(Build, queryset, filter_string, search_term, ordering_string) | ||
| 200 | 204 | ||
| 201 | # retrieve the objects that will be displayed in the table; builds a paginator and gets a page range to display | 205 | # retrieve the objects that will be displayed in the table; builds a paginator and gets a page range to display |
| 202 | build_info = _build_page_range(Paginator(queryset.exclude(outcome = Build.IN_PROGRESS), request.GET.get('count', 10)),request.GET.get('page', 1)) | 206 | build_info = _build_page_range(Paginator(queryset, request.GET.get('count', 10)),request.GET.get('page', 1)) |
| 203 | 207 | ||
| 204 | # build view-specific information; this is rendered specifically in the builds page, at the top of the page (i.e. Recent builds) | 208 | # build view-specific information; this is rendered specifically in the builds page, at the top of the page (i.e. Recent builds) |
| 205 | build_mru = Build.objects.filter(completed_on__gte=(timezone.now()-timedelta(hours=24))).order_by("-started_on")[:3] | 209 | build_mru = Build.objects.filter(completed_on__gte=(timezone.now()-timedelta(hours=24))).order_by("-started_on")[:3] |
| 206 | for b in [ x for x in build_mru if x.outcome == Build.IN_PROGRESS ]: | 210 | for b in [ x for x in build_mru if x.outcome == Build.IN_PROGRESS ]: |
| 207 | tf = Task.objects.filter(build = b) | 211 | tf = Task.objects.filter(build = b) |
| 208 | b.completeper = tf.exclude(order__isnull=True).count()*100/tf.count() | 212 | tfc = tf.count() |
| 213 | if tfc > 0: | ||
| 214 | b.completeper = tf.exclude(order__isnull=True).count()*100/tf.count() | ||
| 215 | else: | ||
| 216 | b.completeper = 0 | ||
| 209 | b.eta = timezone.now() | 217 | b.eta = timezone.now() |
| 210 | if b.completeper > 0: | 218 | if b.completeper > 0: |
| 211 | b.eta += ((timezone.now() - b.started_on)*100/b.completeper) | 219 | b.eta += ((timezone.now() - b.started_on)*100/b.completeper) |
| @@ -218,6 +226,7 @@ def builds(request): | |||
| 218 | 'mru' : build_mru, | 226 | 'mru' : build_mru, |
| 219 | # TODO: common objects for all table views, adapt as needed | 227 | # TODO: common objects for all table views, adapt as needed |
| 220 | 'objects' : build_info, | 228 | 'objects' : build_info, |
| 229 | 'objectname' : "builds", | ||
| 221 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns | 230 | # Specifies the display of columns for the table, appearance in "Edit columns" box, toggling default show/hide, and specifying filters for columns |
| 222 | 'tablecols' : [ | 231 | 'tablecols' : [ |
| 223 | {'name': 'Outcome ', # column with a single filter | 232 | {'name': 'Outcome ', # column with a single filter |
| @@ -239,10 +248,13 @@ def builds(request): | |||
| 239 | }, | 248 | }, |
| 240 | {'name': 'Machine ', | 249 | {'name': 'Machine ', |
| 241 | 'qhelp': "The machine is the hardware for which you are building", | 250 | 'qhelp': "The machine is the hardware for which you are building", |
| 242 | 'dclass': 'span3'}, # a slightly wider column | 251 | 'orderfield': _get_toggle_order(request, "machine"), |
| 252 | 'dclass': 'span3' | ||
| 253 | }, # a slightly wider column | ||
| 243 | {'name': 'Started on ', 'clclass': 'started_on', 'hidden' : 1, # this is an unchecked box, which hides the column | 254 | {'name': 'Started on ', 'clclass': 'started_on', 'hidden' : 1, # this is an unchecked box, which hides the column |
| 244 | 'qhelp': "The date and time you started the build", | 255 | 'qhelp': "The date and time you started the build", |
| 245 | 'filter' : {'class' : 'started_on', 'label': 'Show only builds started', 'options' : { | 256 | 'orderfield': _get_toggle_order(request, "started_on", True), |
| 257 | 'filter' : {'class' : 'started_on', 'label': 'Show only builds started', 'options' : { | ||
| 246 | 'Today' : 'started_on__gte:'+timezone.now().strftime("%Y-%m-%d"), | 258 | 'Today' : 'started_on__gte:'+timezone.now().strftime("%Y-%m-%d"), |
| 247 | 'Yesterday' : 'started_on__gte:'+(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d"), | 259 | 'Yesterday' : 'started_on__gte:'+(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d"), |
| 248 | 'Within one week' : 'started_on__gte:'+(timezone.now()-timedelta(days=7)).strftime("%Y-%m-%d"), | 260 | 'Within one week' : 'started_on__gte:'+(timezone.now()-timedelta(days=7)).strftime("%Y-%m-%d"), |
| @@ -250,7 +262,7 @@ def builds(request): | |||
| 250 | }, | 262 | }, |
| 251 | {'name': 'Completed on ', | 263 | {'name': 'Completed on ', |
| 252 | 'qhelp': "The date and time the build finished", | 264 | 'qhelp': "The date and time the build finished", |
| 253 | 'orderfield': _get_toggle_order(request, "completed_on"), | 265 | 'orderfield': _get_toggle_order(request, "completed_on", True), |
| 254 | 'filter' : {'class' : 'completed_on', 'label': 'Show only builds completed', 'options' : { | 266 | 'filter' : {'class' : 'completed_on', 'label': 'Show only builds completed', 'options' : { |
| 255 | 'Today' : 'completed_on__gte:'+timezone.now().strftime("%Y-%m-%d"), | 267 | 'Today' : 'completed_on__gte:'+timezone.now().strftime("%Y-%m-%d"), |
| 256 | 'Yesterday' : 'completed_on__gte:'+(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d"), | 268 | 'Yesterday' : 'completed_on__gte:'+(timezone.now()-timedelta(hours=24)).strftime("%Y-%m-%d"), |
| @@ -266,7 +278,7 @@ def builds(request): | |||
| 266 | }, | 278 | }, |
| 267 | {'name': 'Errors ', 'clclass': 'errors_no', | 279 | {'name': 'Errors ', 'clclass': 'errors_no', |
| 268 | 'qhelp': "How many errors were encountered during the build (if any)", | 280 | 'qhelp': "How many errors were encountered during the build (if any)", |
| 269 | 'orderfield': _get_toggle_order(request, "errors_no"), | 281 | 'orderfield': _get_toggle_order(request, "errors_no", True), |
| 270 | 'filter' : {'class' : 'errors_no', 'label': 'Show only ', 'options' : { | 282 | 'filter' : {'class' : 'errors_no', 'label': 'Show only ', 'options' : { |
| 271 | 'Builds with errors' : 'errors_no__gte:1', | 283 | 'Builds with errors' : 'errors_no__gte:1', |
| 272 | 'Builds without errors' : 'errors_no:0', | 284 | 'Builds without errors' : 'errors_no:0', |
| @@ -274,20 +286,25 @@ def builds(request): | |||
| 274 | }, | 286 | }, |
| 275 | {'name': 'Warnings', 'clclass': 'warnings_no', | 287 | {'name': 'Warnings', 'clclass': 'warnings_no', |
| 276 | 'qhelp': "How many warnigns were encountered during the build (if any)", | 288 | 'qhelp': "How many warnigns were encountered during the build (if any)", |
| 277 | 'orderfield': _get_toggle_order(request, "warnings_no"), | 289 | 'orderfield': _get_toggle_order(request, "warnings_no", True), |
| 278 | 'filter' : {'class' : 'warnings_no', 'label': 'Show only ', 'options' : { | 290 | 'filter' : {'class' : 'warnings_no', 'label': 'Show only ', 'options' : { |
| 279 | 'Builds with warnings' : 'warnings_no__gte:1', | 291 | 'Builds with warnings' : 'warnings_no__gte:1', |
| 280 | 'Builds without warnings' : 'warnings_no:0', | 292 | 'Builds without warnings' : 'warnings_no:0', |
| 281 | }} | 293 | }} |
| 282 | }, | 294 | }, |
| 283 | {'name': 'Time ', 'clclass': 'time', 'hidden' : 1, | 295 | {'name': 'Time ', 'clclass': 'time', 'hidden' : 1, |
| 284 | 'qhelp': "How long it took the build to finish",}, | 296 | 'qhelp': "How long it took the build to finish", |
| 297 | 'orderfield': _get_toggle_order(request, "timespent", True), | ||
| 298 | }, | ||
| 285 | {'name': 'Log', | 299 | {'name': 'Log', |
| 286 | 'dclass': "span4", | 300 | 'dclass': "span4", |
| 287 | 'qhelp': "The location in disk of the build main log file", | 301 | 'qhelp': "The location in disk of the build main log file", |
| 288 | 'clclass': 'log', 'hidden': 1}, | 302 | 'clclass': 'log', 'hidden': 1 |
| 303 | }, | ||
| 289 | {'name': 'Output', 'clclass': 'output', | 304 | {'name': 'Output', 'clclass': 'output', |
| 290 | 'qhelp': "The root file system types produced by the build. You can find them in your <code>/build/tmp/deploy/images/</code> directory"}, | 305 | 'qhelp': "The root file system types produced by the build. You can find them in your <code>/build/tmp/deploy/images/</code> directory", |
| 306 | 'orderfield': _get_toggle_order(request, "image_fstypes") | ||
| 307 | }, | ||
| 291 | ] | 308 | ] |
| 292 | } | 309 | } |
| 293 | 310 | ||
| @@ -368,9 +385,10 @@ def tasks(request, build_id): | |||
| 368 | if retval: | 385 | if retval: |
| 369 | return _redirect_parameters( 'tasks', request.GET, mandatory_parameters, build_id = build_id) | 386 | return _redirect_parameters( 'tasks', request.GET, mandatory_parameters, build_id = build_id) |
| 370 | (filter_string, search_term, ordering_string) = _search_tuple(request, Task) | 387 | (filter_string, search_term, ordering_string) = _search_tuple(request, Task) |
| 371 | queryset = _get_queryset(Task, filter_string, search_term, ordering_string) | 388 | queryset = Task.objects.filter(build=build_id, order__gt=0) |
| 389 | queryset = _get_queryset(Task, queryset, filter_string, search_term, ordering_string) | ||
| 372 | 390 | ||
| 373 | tasks = _build_page_range(Paginator(queryset.filter(build=build_id, order__gt=0), request.GET.get('count', 100)),request.GET.get('page', 1)) | 391 | tasks = _build_page_range(Paginator(queryset, request.GET.get('count', 100)),request.GET.get('page', 1)) |
| 374 | 392 | ||
| 375 | for t in tasks: | 393 | for t in tasks: |
| 376 | if t.outcome == Task.OUTCOME_COVERED: | 394 | if t.outcome == Task.OUTCOME_COVERED: |
| @@ -387,9 +405,10 @@ def recipes(request, build_id): | |||
| 387 | if retval: | 405 | if retval: |
| 388 | return _redirect_parameters( 'recipes', request.GET, mandatory_parameters, build_id = build_id) | 406 | return _redirect_parameters( 'recipes', request.GET, mandatory_parameters, build_id = build_id) |
| 389 | (filter_string, search_term, ordering_string) = _search_tuple(request, Recipe) | 407 | (filter_string, search_term, ordering_string) = _search_tuple(request, Recipe) |
| 390 | queryset = _get_queryset(Recipe, filter_string, search_term, ordering_string) | 408 | queryset = Recipe.objects.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id)) |
| 409 | queryset = _get_queryset(Recipe, queryset, filter_string, search_term, ordering_string) | ||
| 391 | 410 | ||
| 392 | recipes = _build_page_range(Paginator(queryset.filter(layer_version__id__in=Layer_Version.objects.filter(build=build_id)), request.GET.get('count', 100)),request.GET.get('page', 1)) | 411 | recipes = _build_page_range(Paginator(queryset, request.GET.get('count', 100)),request.GET.get('page', 1)) |
| 393 | 412 | ||
| 394 | context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': recipes, } | 413 | context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': recipes, } |
| 395 | 414 | ||
| @@ -410,9 +429,10 @@ def configvars(request, build_id): | |||
| 410 | return _redirect_parameters( 'configvars', request.GET, mandatory_parameters, build_id = build_id) | 429 | return _redirect_parameters( 'configvars', request.GET, mandatory_parameters, build_id = build_id) |
| 411 | 430 | ||
| 412 | (filter_string, search_term, ordering_string) = _search_tuple(request, Variable) | 431 | (filter_string, search_term, ordering_string) = _search_tuple(request, Variable) |
| 413 | queryset = _get_queryset(Variable, filter_string, search_term, ordering_string) | 432 | queryset = Variable.objects.filter(build=build_id) |
| 433 | queryset = _get_queryset(Variable, queryset, filter_string, search_term, ordering_string) | ||
| 414 | 434 | ||
| 415 | variables = _build_page_range(Paginator(queryset.filter(build=build_id), request.GET.get('count', 50)), request.GET.get('page', 1)) | 435 | variables = _build_page_range(Paginator(queryset, request.GET.get('count', 50)), request.GET.get('page', 1)) |
| 416 | 436 | ||
| 417 | context = { | 437 | context = { |
| 418 | 'build': Build.objects.filter(pk=build_id)[0], | 438 | 'build': Build.objects.filter(pk=build_id)[0], |
| @@ -492,9 +512,10 @@ def bpackage(request, build_id): | |||
| 492 | if retval: | 512 | if retval: |
| 493 | return _redirect_parameters( 'packages', request.GET, mandatory_parameters, build_id = build_id) | 513 | return _redirect_parameters( 'packages', request.GET, mandatory_parameters, build_id = build_id) |
| 494 | (filter_string, search_term, ordering_string) = _search_tuple(request, Package) | 514 | (filter_string, search_term, ordering_string) = _search_tuple(request, Package) |
| 495 | queryset = _get_queryset(Package, filter_string, search_term, ordering_string) | 515 | queryset = Package.objects.filter(build = build_id) |
| 516 | queryset = _get_queryset(Package, queryset, filter_string, search_term, ordering_string) | ||
| 496 | 517 | ||
| 497 | packages = _build_page_range(Paginator(queryset.filter(build = build_id), request.GET.get('count', 100)),request.GET.get('page', 1)) | 518 | packages = _build_page_range(Paginator(queryset, request.GET.get('count', 100)),request.GET.get('page', 1)) |
| 498 | 519 | ||
| 499 | context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : packages} | 520 | context = {'build': Build.objects.filter(pk=build_id)[0], 'objects' : packages} |
| 500 | return render(request, template, context) | 521 | return render(request, template, context) |
