diff options
Diffstat (limited to 'bitbake/lib/toaster/toastergui/views.py')
-rw-r--r--[-rwxr-xr-x] | bitbake/lib/toaster/toastergui/views.py | 151 |
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 | |||
25 | from django.db.models import F, Q, Sum | 25 | from django.db.models import F, Q, Sum |
26 | from django.db import IntegrityError | 26 | from django.db import IntegrityError |
27 | from django.shortcuts import render, redirect, get_object_or_404 | 27 | from django.shortcuts import render, redirect, get_object_or_404 |
28 | from django.utils.http import urlencode | ||
28 | from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe | 29 | from orm.models import Build, Target, Task, Layer, Layer_Version, Recipe |
29 | from orm.models import LogMessage, Variable, Package_Dependency, Package | 30 | from orm.models import LogMessage, Variable, Package_Dependency, Package |
30 | from orm.models import Task_Dependency, Package_File | 31 | from 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 |
53 | project_enable = ('1' == os.environ.get('TOASTER_BUILDSERVER')) | 54 | project_enable = ('1' == os.environ.get('TOASTER_BUILDSERVER')) |
55 | is_project_specific = ('1' == os.environ.get('TOASTER_PROJECTSPECIFIC')) | ||
54 | 56 | ||
55 | class MimeTypeFinder(object): | 57 | class 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 |
71 | def toaster_render(request, page, context): | 73 | def 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() |