summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster/toastergui/views.py')
-rw-r--r--[-rwxr-xr-x]bitbake/lib/toaster/toastergui/views.py151
1 files changed, 151 insertions, 0 deletions
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 34ed2b2e3c..4939b6b1f4 100755..100644
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -25,6 +25,7 @@ import re
25from django.db.models import F, Q, Sum 25from django.db.models import F, Q, Sum
26from django.db import IntegrityError 26from django.db import IntegrityError
27from django.shortcuts import render, redirect, get_object_or_404 27from django.shortcuts import render, redirect, get_object_or_404
28from django.utils.http import urlencode
28from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe 29from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe
29from orm.models import LogMessage, Variable, Package_Dependency, Package 30from orm.models import LogMessage, Variable, Package_Dependency, Package
30from orm.models import Task_Dependency, Package_File 31from orm.models import Task_Dependency, Package_File
@@ -51,6 +52,7 @@ logger = logging.getLogger("toaster")
51 52
52# Project creation and managed build enable 53# Project creation and managed build enable
53project_enable = ('1' == os.environ.get('TOASTER_BUILDSERVER')) 54project_enable = ('1' == os.environ.get('TOASTER_BUILDSERVER'))
55is_project_specific = ('1' == os.environ.get('TOASTER_PROJECTSPECIFIC'))
54 56
55class MimeTypeFinder(object): 57class MimeTypeFinder(object):
56 # setting this to False enables additional non-standard mimetypes 58 # setting this to False enables additional non-standard mimetypes
@@ -70,6 +72,7 @@ class MimeTypeFinder(object):
70# single point to add global values into the context before rendering 72# single point to add global values into the context before rendering
71def toaster_render(request, page, context): 73def toaster_render(request, page, context):
72 context['project_enable'] = project_enable 74 context['project_enable'] = project_enable
75 context['project_specific'] = is_project_specific
73 return render(request, page, context) 76 return render(request, page, context)
74 77
75 78
@@ -1434,12 +1437,160 @@ if True:
1434 1437
1435 raise Exception("Invalid HTTP method for this page") 1438 raise Exception("Invalid HTTP method for this page")
1436 1439
1440 # new project
1441 def newproject_specific(request, pid):
1442 if not project_enable:
1443 return redirect( landing )
1444
1445 project = Project.objects.get(pk=pid)
1446 template = "newproject_specific.html"
1447 context = {
1448 'email': request.user.email if request.user.is_authenticated() else '',
1449 'username': request.user.username if request.user.is_authenticated() else '',
1450 'releases': Release.objects.order_by("description"),
1451 'projectname': project.name,
1452 'project_pk': project.pk,
1453 }
1454
1455 # WORKAROUND: if we already know release, redirect 'newproject_specific' to 'project_specific'
1456 if '1' == project.get_variable('INTERNAL_PROJECT_SPECIFIC_SKIPRELEASE'):
1457 return redirect(reverse(project_specific, args=(project.pk,)))
1458
1459 try:
1460 context['defaultbranch'] = ToasterSetting.objects.get(name = "DEFAULT_RELEASE").value
1461 except ToasterSetting.DoesNotExist:
1462 pass
1463
1464 if request.method == "GET":
1465 # render new project page
1466 return toaster_render(request, template, context)
1467 elif request.method == "POST":
1468 mandatory_fields = ['projectname', 'ptype']
1469 try:
1470 ptype = request.POST.get('ptype')
1471 if ptype == "build":
1472 mandatory_fields.append('projectversion')
1473 # make sure we have values for all mandatory_fields
1474 missing = [field for field in mandatory_fields if len(request.POST.get(field, '')) == 0]
1475 if missing:
1476 # set alert for missing fields
1477 raise BadParameterException("Fields missing: %s" % ", ".join(missing))
1478
1479 if not request.user.is_authenticated():
1480 user = authenticate(username = request.POST.get('username', '_anonuser'), password = 'nopass')
1481 if user is None:
1482 user = User.objects.create_user(username = request.POST.get('username', '_anonuser'), email = request.POST.get('email', ''), password = "nopass")
1483
1484 user = authenticate(username = user.username, password = 'nopass')
1485 login(request, user)
1486
1487 # save the project
1488 if ptype == "analysis":
1489 release = None
1490 else:
1491 release = Release.objects.get(pk = request.POST.get('projectversion', None ))
1492
1493 prj = Project.objects.create_project(name = request.POST['projectname'], release = release, existing_project = project)
1494 prj.user_id = request.user.pk
1495 prj.save()
1496 return redirect(reverse(project_specific, args=(prj.pk,)) + "?notify=new-project")
1497
1498 except (IntegrityError, BadParameterException) as e:
1499 # fill in page with previously submitted values
1500 for field in mandatory_fields:
1501 context.__setitem__(field, request.POST.get(field, "-- missing"))
1502 if isinstance(e, IntegrityError) and "username" in str(e):
1503 context['alert'] = "Your chosen username is already used"
1504 else:
1505 context['alert'] = str(e)
1506 return toaster_render(request, template, context)
1507
1508 raise Exception("Invalid HTTP method for this page")
1509
1437 # Shows the edit project page 1510 # Shows the edit project page
1438 def project(request, pid): 1511 def project(request, pid):
1439 project = Project.objects.get(pk=pid) 1512 project = Project.objects.get(pk=pid)
1513
1514 if '1' == os.environ.get('TOASTER_PROJECTSPECIFIC'):
1515 if request.GET:
1516 #Example:request.GET=<QueryDict: {'setMachine': ['qemuarm']}>
1517 params = urlencode(request.GET).replace('%5B%27','').replace('%27%5D','')
1518 return redirect("%s?%s" % (reverse(project_specific, args=(project.pk,)),params))
1519 else:
1520 return redirect(reverse(project_specific, args=(project.pk,)))
1440 context = {"project": project} 1521 context = {"project": project}
1441 return toaster_render(request, "project.html", context) 1522 return toaster_render(request, "project.html", context)
1442 1523
1524 # Shows the edit project-specific page
1525 def project_specific(request, pid):
1526 project = Project.objects.get(pk=pid)
1527
1528 # Are we refreshing from a successful project specific update clone?
1529 if Project.PROJECT_SPECIFIC_CLONING_SUCCESS == project.get_variable(Project.PROJECT_SPECIFIC_STATUS):
1530 return redirect(reverse(landing_specific,args=(project.pk,)))
1531
1532 context = {
1533 "project": project,
1534 "is_new" : project.get_variable(Project.PROJECT_SPECIFIC_ISNEW),
1535 "default_image_recipe" : project.get_variable(Project.PROJECT_SPECIFIC_DEFAULTIMAGE),
1536 "mru" : Build.objects.all().filter(project=project,outcome=Build.IN_PROGRESS),
1537 }
1538 if project.build_set.filter(outcome=Build.IN_PROGRESS).count() > 0:
1539 context['build_in_progress_none_completed'] = True
1540 else:
1541 context['build_in_progress_none_completed'] = False
1542 return toaster_render(request, "project.html", context)
1543
1544 # perform the final actions for the project specific page
1545 def project_specific_finalize(cmnd, pid):
1546 project = Project.objects.get(pk=pid)
1547 callback = project.get_variable(Project.PROJECT_SPECIFIC_CALLBACK)
1548 if "update" == cmnd:
1549 # Delete all '_PROJECT_PREPARE_' builds
1550 for b in Build.objects.all().filter(project=project):
1551 delete_build = False
1552 for t in b.target_set.all():
1553 if '_PROJECT_PREPARE_' == t.target:
1554 delete_build = True
1555 if delete_build:
1556 from django.core import management
1557 management.call_command('builddelete', str(b.id), interactive=False)
1558 # perform callback at this last moment if defined, in case Toaster gets shutdown next
1559 default_target = project.get_variable(Project.PROJECT_SPECIFIC_DEFAULTIMAGE)
1560 if callback:
1561 callback = callback.replace("<IMAGE>",default_target)
1562 if "cancel" == cmnd:
1563 if callback:
1564 callback = callback.replace("<IMAGE>","none")
1565 callback = callback.replace("--update","--cancel")
1566 # perform callback at this last moment if defined, in case this Toaster gets shutdown next
1567 ret = ''
1568 if callback:
1569 ret = os.system('bash -c "%s"' % callback)
1570 project.set_variable(Project.PROJECT_SPECIFIC_CALLBACK,'')
1571 # Delete the temp project specific variables
1572 project.set_variable(Project.PROJECT_SPECIFIC_ISNEW,'')
1573 project.set_variable(Project.PROJECT_SPECIFIC_STATUS,Project.PROJECT_SPECIFIC_NONE)
1574 # WORKAROUND: Release this workaround flag
1575 project.set_variable('INTERNAL_PROJECT_SPECIFIC_SKIPRELEASE','')
1576
1577 # Shows the final landing page for project specific update
1578 def landing_specific(request, pid):
1579 project_specific_finalize("update", pid)
1580 context = {
1581 "install_dir": os.environ['TOASTER_DIR'],
1582 }
1583 return toaster_render(request, "landing_specific.html", context)
1584
1585 # Shows the related landing-specific page
1586 def landing_specific_cancel(request, pid):
1587 project_specific_finalize("cancel", pid)
1588 context = {
1589 "install_dir": os.environ['TOASTER_DIR'],
1590 "status": "cancel",
1591 }
1592 return toaster_render(request, "landing_specific.html", context)
1593
1443 def jsunittests(request): 1594 def jsunittests(request):
1444 """ Provides a page for the js unit tests """ 1595 """ Provides a page for the js unit tests """
1445 bbv = BitbakeVersion.objects.filter(branch="master").first() 1596 bbv = BitbakeVersion.objects.filter(branch="master").first()