1 ##############################################################################
2 # Copyright (c) 2016 Max Breitenfeldt and others.
3 # Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
11 from django.contrib import messages
12 from django.shortcuts import get_object_or_404
13 from django.http import JsonResponse, HttpResponse
14 from django.utils import timezone
15 from django.views import View
16 from django.views.generic import TemplateView
17 from django.shortcuts import redirect, render
18 from django.db.models import Q
20 from resource_inventory.models import ResourceBundle, HostProfile, Image, Host
21 from resource_inventory.resource_manager import ResourceManager
22 from account.models import Lab
23 from booking.models import Booking
24 from booking.stats import StatisticsManager
25 from booking.forms import HostReImageForm
26 from api.models import JobFactory
27 from workflow.views import login
28 from booking.forms import QuickBookingForm
29 from booking.quick_deployer import create_from_form, drop_filter
32 def quick_create_clear_fields(request):
33 request.session['quick_create_forminfo'] = None
36 def quick_create(request):
37 if not request.user.is_authenticated:
40 if request.method == 'GET':
43 r_manager = ResourceManager.getInstance()
45 for lab in Lab.objects.all():
46 profiles[str(lab)] = r_manager.getAvailableHostTypes(lab)
48 context['lab_profile_map'] = profiles
50 context['form'] = QuickBookingForm(default_user=request.user.username, user=request.user)
52 context.update(drop_filter(request.user))
54 return render(request, 'booking/quick_deploy.html', context)
55 if request.method == 'POST':
56 form = QuickBookingForm(request.POST, user=request.user)
58 context['lab_profile_map'] = {}
59 context['form'] = form
63 create_from_form(form, request)
64 except Exception as e:
65 messages.error(request, "Whoops, an error occurred: " + str(e))
66 return render(request, 'workflow/exit_redirect.html', context)
68 messages.success(request, "We've processed your request. "
69 "Check Account->My Bookings for the status of your new booking")
70 return render(request, 'workflow/exit_redirect.html', context)
72 messages.error(request, "Looks like the form didn't validate. Check that you entered everything correctly")
73 return render(request, 'booking/quick_deploy.html', context)
76 class BookingView(TemplateView):
77 template_name = "booking/booking_detail.html"
79 def get_context_data(self, **kwargs):
80 booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
81 title = 'Booking Details'
82 context = super(BookingView, self).get_context_data(**kwargs)
83 context.update({'title': title, 'booking': booking})
87 class BookingDeleteView(TemplateView):
88 template_name = "booking/booking_delete.html"
90 def get_context_data(self, **kwargs):
91 booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
92 title = 'Delete Booking'
93 context = super(BookingDeleteView, self).get_context_data(**kwargs)
94 context.update({'title': title, 'booking': booking})
98 def bookingDelete(request, booking_id):
99 booking = get_object_or_404(Booking, id=booking_id)
101 messages.add_message(request, messages.SUCCESS, 'Booking deleted')
102 return redirect('../../../../')
105 class BookingListView(TemplateView):
106 template_name = "booking/booking_list.html"
108 def get_context_data(self, **kwargs):
109 bookings = Booking.objects.filter(end__gte=timezone.now())
110 title = 'Search Booking'
111 context = super(BookingListView, self).get_context_data(**kwargs)
112 context.update({'title': title, 'bookings': bookings})
116 class ResourceBookingsJSON(View):
117 def get(self, request, *args, **kwargs):
118 resource = get_object_or_404(ResourceBundle, id=self.kwargs['resource_id'])
119 bookings = resource.booking_set.get_queryset().values(
125 'config_bundle__name'
127 return JsonResponse({'bookings': list(bookings)})
130 def build_image_mapping(lab, user):
132 for profile in HostProfile.objects.filter(labs=lab):
133 images = Image.objects.filter(
137 Q(public=True) | Q(owner=user)
139 mapping[profile.name] = [{"name": image.name, "value": image.id} for image in images]
143 def booking_detail_view(request, booking_id):
145 if request.user.is_authenticated:
148 return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
150 booking = get_object_or_404(Booking, id=booking_id)
151 allowed_users = set(list(booking.collaborators.all()))
152 allowed_users.add(booking.owner)
153 if user not in allowed_users:
154 return render(request, "dashboard/login.html", {'title': 'This page is private'})
157 'title': 'Booking Details',
161 'image_mapping': build_image_mapping(booking.lab, user)
166 "booking/booking_detail.html",
171 def booking_modify_image(request, booking_id):
172 form = HostReImageForm(request.POST)
174 booking = Booking.objects.get(id=booking_id)
175 if request.user != booking.owner:
176 return HttpResponse("unauthorized")
177 if timezone.now() > booking.end:
178 return HttpResponse("unauthorized")
179 new_image = Image.objects.get(id=form.cleaned_data['image_id'])
180 host = Host.objects.get(id=form.cleaned_data['host_id'])
181 host.config.image = new_image
183 JobFactory.reimageHost(new_image, booking, host)
184 return HttpResponse(new_image.name)
185 return HttpResponse("error")
188 def booking_stats_view(request):
191 "booking/stats.html",
192 context={"data": StatisticsManager.getContinuousBookingTimeSeries(), "title": "Booking Statistics"}
196 def booking_stats_json(request):
198 span = int(request.GET.get("days", 14))
201 return JsonResponse(StatisticsManager.getContinuousBookingTimeSeries(span), safe=False)