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(initial={}, chosen_users=[], 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, looks like an error occurred. "
66 "Let the admins know that you got the following message: " + str(e))
67 return render(request, 'workflow/exit_redirect.html', context)
69 messages.success(request, "We've processed your request. "
70 "Check Account->My Bookings for the status of your new booking")
71 return render(request, 'workflow/exit_redirect.html', context)
73 messages.error(request, "Looks like the form didn't validate. Check that you entered everything correctly")
74 return render(request, 'booking/quick_deploy.html', context)
77 class BookingView(TemplateView):
78 template_name = "booking/booking_detail.html"
80 def get_context_data(self, **kwargs):
81 booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
82 title = 'Booking Details'
83 context = super(BookingView, self).get_context_data(**kwargs)
84 context.update({'title': title, 'booking': booking})
88 class BookingDeleteView(TemplateView):
89 template_name = "booking/booking_delete.html"
91 def get_context_data(self, **kwargs):
92 booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
93 title = 'Delete Booking'
94 context = super(BookingDeleteView, self).get_context_data(**kwargs)
95 context.update({'title': title, 'booking': booking})
99 def bookingDelete(request, booking_id):
100 booking = get_object_or_404(Booking, id=booking_id)
102 messages.add_message(request, messages.SUCCESS, 'Booking deleted')
103 return redirect('../../../../')
106 class BookingListView(TemplateView):
107 template_name = "booking/booking_list.html"
109 def get_context_data(self, **kwargs):
110 bookings = Booking.objects.filter(end__gte=timezone.now())
111 title = 'Search Booking'
112 context = super(BookingListView, self).get_context_data(**kwargs)
113 context.update({'title': title, 'bookings': bookings})
117 class ResourceBookingsJSON(View):
118 def get(self, request, *args, **kwargs):
119 resource = get_object_or_404(ResourceBundle, id=self.kwargs['resource_id'])
120 bookings = resource.booking_set.get_queryset().values(
126 'config_bundle__name'
128 return JsonResponse({'bookings': list(bookings)})
131 def build_image_mapping(lab, user):
133 for profile in HostProfile.objects.filter(labs=lab):
134 images = Image.objects.filter(
138 Q(public=True) | Q(owner=user)
140 mapping[profile.name] = [{"name": image.name, "value": image.id} for image in images]
144 def booking_detail_view(request, booking_id):
146 if request.user.is_authenticated:
149 return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
151 booking = get_object_or_404(Booking, id=booking_id)
152 allowed_users = set(list(booking.collaborators.all()))
153 allowed_users.add(booking.owner)
154 if user not in allowed_users:
155 return render(request, "dashboard/login.html", {'title': 'This page is private'})
158 'title': 'Booking Details',
162 'image_mapping': build_image_mapping(booking.lab, user)
167 "booking/booking_detail.html",
172 def booking_modify_image(request, booking_id):
173 form = HostReImageForm(request.POST)
175 booking = Booking.objects.get(id=booking_id)
176 if request.user != booking.owner:
177 return HttpResponse("unauthorized")
178 if timezone.now() > booking.end:
179 return HttpResponse("unauthorized")
180 new_image = Image.objects.get(id=form.cleaned_data['image_id'])
181 host = Host.objects.get(id=form.cleaned_data['host_id'])
182 host.config.image = new_image
184 JobFactory.reimageHost(new_image, booking, host)
185 return HttpResponse(new_image.name)
186 return HttpResponse("error")
189 def booking_stats_view(request):
192 "booking/stats.html",
193 context={"data": StatisticsManager.getContinuousBookingTimeSeries(), "title": "Booking Statistics"}
197 def booking_stats_json(request):
199 span = int(request.GET.get("days", 14))
202 return JsonResponse(StatisticsManager.getContinuousBookingTimeSeries(span), safe=False)