diff options
Diffstat (limited to 'bitbake/lib/toaster/toastergui/views.py')
-rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 208 |
1 files changed, 56 insertions, 152 deletions
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index c25c512a84..5221f1f728 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py | |||
@@ -136,28 +136,6 @@ def _template_renderer(template): | |||
136 | 136 | ||
137 | # we're about to return; to keep up with the XHR API, we set the error to OK | 137 | # we're about to return; to keep up with the XHR API, we set the error to OK |
138 | context["error"] = "ok" | 138 | context["error"] = "ok" |
139 | def _objtojson(obj): | ||
140 | from django.db.models.query import QuerySet | ||
141 | from django.db.models import Model, IntegerField | ||
142 | if isinstance(obj, datetime): | ||
143 | return obj.isoformat() | ||
144 | elif isinstance(obj, timedelta): | ||
145 | return obj.total_seconds() | ||
146 | elif isinstance(obj, QuerySet) or isinstance(obj, set): | ||
147 | return list(obj) | ||
148 | elif hasattr( obj, '__dict__'): | ||
149 | d = obj.__dict__ | ||
150 | nd = dict(d) | ||
151 | for di in d: | ||
152 | if di.startswith("_"): | ||
153 | del nd[di] | ||
154 | elif isinstance(d[di], Model): | ||
155 | nd[di] = d[di].pk | ||
156 | elif isinstance(d[di], int) and hasattr(obj, "get_%s_display" % di): | ||
157 | nd[di] = getattr(obj, "get_%s_display" % di)() | ||
158 | return nd | ||
159 | else: | ||
160 | raise TypeError("Unserializable object %s of type %s" % ( obj, type(obj))) | ||
161 | 139 | ||
162 | return HttpResponse(jsonfilter(context, default=objtojson ), | 140 | return HttpResponse(jsonfilter(context, default=objtojson ), |
163 | content_type = "application/json; charset=utf-8") | 141 | content_type = "application/json; charset=utf-8") |
@@ -167,6 +145,21 @@ def _template_renderer(template): | |||
167 | return func_wrapper | 145 | return func_wrapper |
168 | 146 | ||
169 | 147 | ||
148 | def _lv_to_dict(prj, x = None): | ||
149 | if x is None: | ||
150 | def wrapper(x): | ||
151 | return _lv_to_dict(prj, x) | ||
152 | return wrapper | ||
153 | |||
154 | return {"id": x.pk, | ||
155 | "name": x.layer.name, | ||
156 | "tooltip": x.layer.vcs_url+" | "+x.get_vcs_reference(), | ||
157 | "detail": "(" + x.layer.vcs_url + (")" if x.up_branch == None else " | "+x.get_vcs_reference()+")"), | ||
158 | "giturl": x.layer.vcs_url, | ||
159 | "layerdetailurl" : reverse('layerdetails', args=(prj.id,x.pk)), | ||
160 | "revision" : x.get_vcs_reference(), | ||
161 | } | ||
162 | |||
170 | 163 | ||
171 | def _build_page_range(paginator, index = 1): | 164 | def _build_page_range(paginator, index = 1): |
172 | try: | 165 | try: |
@@ -335,7 +328,6 @@ def _search_tuple(request, model): | |||
335 | def _get_queryset(model, queryset, filter_string, search_term, ordering_string, ordering_secondary=''): | 328 | def _get_queryset(model, queryset, filter_string, search_term, ordering_string, ordering_secondary=''): |
336 | if filter_string: | 329 | if filter_string: |
337 | filter_query = _get_filtering_query(filter_string) | 330 | filter_query = _get_filtering_query(filter_string) |
338 | # raise Exception(filter_query) | ||
339 | queryset = queryset.filter(filter_query) | 331 | queryset = queryset.filter(filter_query) |
340 | else: | 332 | else: |
341 | queryset = queryset.all() | 333 | queryset = queryset.all() |
@@ -2330,82 +2322,12 @@ if toastermain.settings.MANAGED: | |||
2330 | return context | 2322 | return context |
2331 | 2323 | ||
2332 | 2324 | ||
2333 | def xhr_projectbuild(request, pid): | ||
2334 | try: | ||
2335 | if request.method != "POST": | ||
2336 | raise BadParameterException("invalid method") | ||
2337 | pid = pid | ||
2338 | prj = Project.objects.get(id = pid) | ||
2339 | |||
2340 | |||
2341 | if 'buildCancel' in request.POST: | ||
2342 | for i in request.POST['buildCancel'].strip().split(" "): | ||
2343 | try: | ||
2344 | br = BuildRequest.objects.select_for_update().get(project = prj, pk = i, state__lte = BuildRequest.REQ_QUEUED) | ||
2345 | br.state = BuildRequest.REQ_DELETED | ||
2346 | br.save() | ||
2347 | except BuildRequest.DoesNotExist: | ||
2348 | pass | ||
2349 | |||
2350 | if 'buildDelete' in request.POST: | ||
2351 | for i in request.POST['buildDelete'].strip().split(" "): | ||
2352 | try: | ||
2353 | br = BuildRequest.objects.select_for_update().get(project = prj, pk = i, state__lte = BuildRequest.REQ_DELETED).delete() | ||
2354 | except BuildRequest.DoesNotExist: | ||
2355 | pass | ||
2356 | |||
2357 | if 'targets' in request.POST: | ||
2358 | ProjectTarget.objects.filter(project = prj).delete() | ||
2359 | s = str(request.POST['targets']) | ||
2360 | for t in s.translate(None, ";%|\"").split(" "): | ||
2361 | if ":" in t: | ||
2362 | target, task = t.split(":") | ||
2363 | else: | ||
2364 | target = t | ||
2365 | task = "" | ||
2366 | ProjectTarget.objects.create(project = prj, target = target, task = task) | ||
2367 | |||
2368 | br = prj.schedule_build() | ||
2369 | |||
2370 | return HttpResponse(jsonfilter({"error":"ok", | ||
2371 | "builds" : _project_recent_build_list(prj), | ||
2372 | }), content_type = "application/json") | ||
2373 | except Exception as e: | ||
2374 | return HttpResponse(jsonfilter({"error":str(e) + "\n" + traceback.format_exc()}), content_type = "application/json") | ||
2375 | |||
2376 | |||
2377 | from django.views.decorators.csrf import csrf_exempt | 2325 | from django.views.decorators.csrf import csrf_exempt |
2378 | @csrf_exempt | 2326 | @csrf_exempt |
2379 | def xhr_datatypeahead(request, pid): | 2327 | def xhr_datatypeahead(request, pid): |
2380 | try: | 2328 | try: |
2381 | prj = Project.objects.get(pk = pid) | 2329 | prj = Project.objects.get(pk = pid) |
2382 | 2330 | ||
2383 | def _lv_to_dict(x): | ||
2384 | return {"id": x.pk, | ||
2385 | "name": x.layer.name, | ||
2386 | "tooltip": x.layer.vcs_url+" | "+x.get_vcs_reference(), | ||
2387 | "detail": "(" + x.layer.vcs_url + (")" if x.up_branch == None else " | "+x.get_vcs_reference()+")"), | ||
2388 | "giturl": x.layer.vcs_url, | ||
2389 | "layerdetailurl" : reverse('layerdetails', args=(prj.id,x.pk)), | ||
2390 | "revision" : x.get_vcs_reference(), | ||
2391 | } | ||
2392 | |||
2393 | |||
2394 | # returns layers for current project release that are not in the project set, matching the name | ||
2395 | if request.GET.get('type', None) == "layers": | ||
2396 | # all layers for the current project | ||
2397 | queryset_all = prj.compatible_layerversions().filter(layer__name__icontains=request.GET.get('search','')) | ||
2398 | |||
2399 | # but not layers with equivalent layers already in project | ||
2400 | if not request.GET.has_key('include_added'): | ||
2401 | queryset_all = queryset_all.exclude(pk__in = [x.id for x in prj.projectlayer_equivalent_set()])[:8] | ||
2402 | |||
2403 | # and show only the selected layers for this project | ||
2404 | final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset_all]) | ||
2405 | |||
2406 | return HttpResponse(jsonfilter( { "error":"ok", "list" : map( _lv_to_dict, sorted(final_list, key = lambda x: x.layer.name)) }), content_type = "application/json") | ||
2407 | |||
2408 | |||
2409 | # returns layer dependencies for a layer, excluding current project layers | 2331 | # returns layer dependencies for a layer, excluding current project layers |
2410 | if request.GET.get('type', None) == "layerdeps": | 2332 | if request.GET.get('type', None) == "layerdeps": |
2411 | queryset = prj.compatible_layerversions().exclude(pk__in = [x.id for x in prj.projectlayer_equivalent_set()]).filter( | 2333 | queryset = prj.compatible_layerversions().exclude(pk__in = [x.id for x in prj.projectlayer_equivalent_set()]).filter( |
@@ -2413,8 +2335,7 @@ if toastermain.settings.MANAGED: | |||
2413 | 2335 | ||
2414 | final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset]) | 2336 | final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset]) |
2415 | 2337 | ||
2416 | return HttpResponse(jsonfilter( { "error":"ok", "list" : map( _lv_to_dict, sorted(final_list, key = lambda x: x.layer.name)) }), content_type = "application/json") | 2338 | return HttpResponse(jsonfilter( { "error":"ok", "list" : map( _lv_to_dict(prj), sorted(final_list, key = lambda x: x.layer.name)) }), content_type = "application/json") |
2417 | |||
2418 | 2339 | ||
2419 | 2340 | ||
2420 | # returns layer versions that would be deleted on the new release__pk | 2341 | # returns layer versions that would be deleted on the new release__pk |
@@ -2428,7 +2349,7 @@ if toastermain.settings.MANAGED: | |||
2428 | retval.append(i) | 2349 | retval.append(i) |
2429 | 2350 | ||
2430 | return HttpResponse(jsonfilter( {"error":"ok", | 2351 | return HttpResponse(jsonfilter( {"error":"ok", |
2431 | "list" : map( _lv_to_dict, map(lambda x: x.layercommit, retval )) | 2352 | "list" : map( _lv_to_dict(prj), map(lambda x: x.layercommit, retval )) |
2432 | }), content_type = "application/json") | 2353 | }), content_type = "application/json") |
2433 | 2354 | ||
2434 | 2355 | ||
@@ -2446,52 +2367,8 @@ if toastermain.settings.MANAGED: | |||
2446 | # and show only the selected layers for this project | 2367 | # and show only the selected layers for this project |
2447 | final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset_all]) | 2368 | final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset_all]) |
2448 | 2369 | ||
2449 | return HttpResponse(jsonfilter( { "error":"ok", "list" : map( _lv_to_dict, final_list) }), content_type = "application/json") | 2370 | return HttpResponse(jsonfilter( { "error":"ok", "list" : map( _lv_to_dict(prj), final_list) }), content_type = "application/json") |
2450 | 2371 | ||
2451 | # returns targets provided by current project layers | ||
2452 | if request.GET.get('type', None) == "targets": | ||
2453 | search_token = request.GET.get('search','') | ||
2454 | queryset_all = Recipe.objects.filter(layer_version__layer__name__in = [x.layercommit.layer.name for x in prj.projectlayer_set.all().select_related("layercommit__layer")]).filter(Q(name__icontains=search_token) | Q(layer_version__layer__name__icontains=search_token)) | ||
2455 | |||
2456 | # layer_equivalent_set = [] | ||
2457 | # for i in prj.projectlayer_set.all().select_related("layercommit__up_branch", "layercommit__layer"): | ||
2458 | # layer_equivalent_set += i.layercommit.get_equivalents_wpriority(prj) | ||
2459 | |||
2460 | # queryset_all = queryset_all.filter(layer_version__in = layer_equivalent_set) | ||
2461 | |||
2462 | # if we have more than one hit here (for distinct name and version), max the id it out | ||
2463 | queryset_all_maxids = queryset_all.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id') | ||
2464 | queryset_all = queryset_all.filter(id__in = queryset_all_maxids).order_by("name").select_related("layer_version__layer") | ||
2465 | |||
2466 | |||
2467 | return HttpResponse(jsonfilter({ "error":"ok", | ||
2468 | "list" : | ||
2469 | # 7152 - sort by token position | ||
2470 | sorted ( | ||
2471 | map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name +"]"}, | ||
2472 | queryset_all[:8]), | ||
2473 | key = lambda i: i["name"].find(search_token) if i["name"].find(search_token) > -1 else 9999, | ||
2474 | ) | ||
2475 | |||
2476 | }), content_type = "application/json") | ||
2477 | |||
2478 | # returns machines provided by the current project layers | ||
2479 | if request.GET.get('type', None) == "machines": | ||
2480 | queryset_all = Machine.objects.all() | ||
2481 | if 'project_id' in request.session: | ||
2482 | queryset_all = queryset_all.filter(layer_version__in = prj.projectlayer_equivalent_set()).order_by("name") | ||
2483 | |||
2484 | search_token = request.GET.get('search','') | ||
2485 | queryset_all = queryset_all.filter(Q(name__icontains=search_token) | Q(description__icontains=search_token)) | ||
2486 | |||
2487 | return HttpResponse(jsonfilter({ "error":"ok", | ||
2488 | "list" : | ||
2489 | # 7152 - sort by the token position | ||
2490 | sorted ( | ||
2491 | map ( lambda x: {"id": x.pk, "name": x.name, "detail":"[" + x.layer_version.layer.name+ "]"}, queryset_all[:8]), | ||
2492 | key = lambda i: i["name"].find(search_token) if i["name"].find(search_token) > -1 else 9999, | ||
2493 | ) | ||
2494 | }), content_type = "application/json") | ||
2495 | 2372 | ||
2496 | raise Exception("Unknown request! " + request.GET.get('type', "No parameter supplied")) | 2373 | raise Exception("Unknown request! " + request.GET.get('type', "No parameter supplied")) |
2497 | except Exception as e: | 2374 | except Exception as e: |
@@ -2791,7 +2668,41 @@ if toastermain.settings.MANAGED: | |||
2791 | 2668 | ||
2792 | @_template_renderer('projectbuilds.html') | 2669 | @_template_renderer('projectbuilds.html') |
2793 | def projectbuilds(request, pid): | 2670 | def projectbuilds(request, pid): |
2794 | buildrequests = BuildRequest.objects.filter(project_id = pid).exclude(state__lte = BuildRequest.REQ_INPROGRESS).exclude(state=BuildRequest.REQ_DELETED) | 2671 | # process any build request |
2672 | prj = Project.objects.get(id = pid) | ||
2673 | if request.method == "POST": | ||
2674 | |||
2675 | if 'buildCancel' in request.POST: | ||
2676 | for i in request.POST['buildCancel'].strip().split(" "): | ||
2677 | try: | ||
2678 | br = BuildRequest.objects.select_for_update().get(project = prj, pk = i, state__lte = BuildRequest.REQ_QUEUED) | ||
2679 | br.state = BuildRequest.REQ_DELETED | ||
2680 | br.save() | ||
2681 | except BuildRequest.DoesNotExist: | ||
2682 | pass | ||
2683 | |||
2684 | if 'buildDelete' in request.POST: | ||
2685 | for i in request.POST['buildDelete'].strip().split(" "): | ||
2686 | try: | ||
2687 | br = BuildRequest.objects.select_for_update().get(project = prj, pk = i, state__lte = BuildRequest.REQ_DELETED).delete() | ||
2688 | except BuildRequest.DoesNotExist: | ||
2689 | pass | ||
2690 | |||
2691 | if 'targets' in request.POST: | ||
2692 | ProjectTarget.objects.filter(project = prj).delete() | ||
2693 | s = str(request.POST['targets']) | ||
2694 | for t in s.translate(None, ";%|\"").split(" "): | ||
2695 | if ":" in t: | ||
2696 | target, task = t.split(":") | ||
2697 | else: | ||
2698 | target = t | ||
2699 | task = "" | ||
2700 | ProjectTarget.objects.create(project = prj, target = target, task = task) | ||
2701 | |||
2702 | br = prj.schedule_build() | ||
2703 | |||
2704 | |||
2705 | buildrequests = BuildRequest.objects.filter(project = prj).exclude(state__lte = BuildRequest.REQ_INPROGRESS).exclude(state=BuildRequest.REQ_DELETED) | ||
2795 | 2706 | ||
2796 | try: | 2707 | try: |
2797 | context, pagesize, orderby = _build_list_helper(request, buildrequests, False) | 2708 | context, pagesize, orderby = _build_list_helper(request, buildrequests, False) |
@@ -2940,9 +2851,10 @@ if toastermain.settings.MANAGED: | |||
2940 | # add fields needed in JSON dumps for API call support | 2851 | # add fields needed in JSON dumps for API call support |
2941 | for p in project_info.object_list: | 2852 | for p in project_info.object_list: |
2942 | p.id = p.pk | 2853 | p.id = p.pk |
2943 | p.xhrProjectDataTypeaheadUrl = reverse('xhr_datatypeahead', args=(p.id,)) | ||
2944 | p.projectPageUrl = reverse('project', args=(p.id,)) | 2854 | p.projectPageUrl = reverse('project', args=(p.id,)) |
2945 | p.projectBuildUrl = reverse('xhr_projectbuild', args=(p.id,)) | 2855 | p.projectLayersUrl = reverse('projectlayers', args=(p.id,)) |
2856 | p.projectBuildsUrl = reverse('projectbuilds', args=(p.id,)) | ||
2857 | p.projectTargetsUrl = reverse('projecttargets', args=(p.id,)) | ||
2946 | 2858 | ||
2947 | # build view-specific information; this is rendered specifically in the builds page, at the top of the page (i.e. Recent builds) | 2859 | # build view-specific information; this is rendered specifically in the builds page, at the top of the page (i.e. Recent builds) |
2948 | build_mru = _managed_get_latest_builds() | 2860 | build_mru = _managed_get_latest_builds() |
@@ -3242,14 +3154,6 @@ else: | |||
3242 | return {} | 3154 | return {} |
3243 | 3155 | ||
3244 | @_template_renderer('landing_not_managed.html') | 3156 | @_template_renderer('landing_not_managed.html') |
3245 | def xhr_projectbuild(request, pid): | ||
3246 | return {} | ||
3247 | |||
3248 | @_template_renderer('landing_not_managed.html') | ||
3249 | def xhr_datatypeahead(request): | ||
3250 | return {} | ||
3251 | |||
3252 | @_template_renderer('landing_not_managed.html') | ||
3253 | def xhr_configvaredit(request, pid): | 3157 | def xhr_configvaredit(request, pid): |
3254 | return {} | 3158 | return {} |
3255 | 3159 | ||