bornhack-website/src/program/views.py

319 lines
13 KiB
Python
Raw Normal View History

import datetime, os
from django.views.generic import ListView, TemplateView, DetailView, View
from django.views.generic.edit import CreateView, UpdateView
from django.conf import settings
from django.views.decorators.http import require_safe
2017-03-12 14:43:41 +00:00
from django.http import Http404, HttpResponse
from django.utils.decorators import method_decorator
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.shortcuts import redirect
from django.urls import reverse
import icalendar
2017-03-12 14:43:41 +00:00
from camps.mixins import CampViewMixin
from .mixins import CreateProposalMixin, EnsureUnapprovedProposalMixin, EnsureUserOwnsProposalMixin, EnsureWritableCampMixin, PictureViewMixin, EnsureCFSOpenMixin
2017-03-12 14:43:41 +00:00
from . import models
2017-03-31 17:25:48 +00:00
############## ical calendar ########################################################
class ICSView(CampViewMixin, View):
2017-03-31 17:25:48 +00:00
def get(self, request, *args, **kwargs):
2017-04-13 12:01:50 +00:00
eventinstances = models.EventInstance.objects.filter(event__camp=self.camp)
type_ = request.GET.get('type', None)
location = request.GET.get('location', None)
if type_:
try:
eventtype = models.EventType.objects.get(
slug=type_
)
eventinstances = eventinstances.filter(event__event_type=eventtype)
except models.EventType.DoesNotExist:
raise Http404
if location:
try:
eventlocation = models.EventLocation.objects.get(
slug=location,
camp=self.camp,
)
eventinstances = eventinstances.filter(location__slug=location)
except models.EventLocation.DoesNotExist:
raise Http404
cal = icalendar.Calendar()
for event_instance in eventinstances:
cal.add_component(event_instance.get_ics_event())
2017-04-13 12:14:44 +00:00
response = HttpResponse(cal.to_ical())
response['Content-Type'] = 'text/calendar'
response['Content-Disposition'] = 'inline; filename={}.ics'.format(self.camp.slug)
return response
############## proposals ########################################################
2017-03-12 14:43:41 +00:00
class ProposalListView(LoginRequiredMixin, CampViewMixin, ListView):
model = models.SpeakerProposal
template_name = 'proposal_list.html'
context_object_name = 'speakerproposal_list'
2017-03-12 14:43:41 +00:00
def get_queryset(self, **kwargs):
# only show speaker proposals for the current user
2017-03-12 14:43:41 +00:00
return super().get_queryset().filter(user=self.request.user)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
2017-03-14 17:06:23 +00:00
# also add eventproposals to the context
context['eventproposal_list'] = models.EventProposal.objects.filter(camp=self.camp, user=self.request.user)
2017-03-12 14:43:41 +00:00
return context
class SpeakerProposalCreateView(LoginRequiredMixin, CampViewMixin, CreateProposalMixin, EnsureWritableCampMixin, EnsureCFSOpenMixin, CreateView):
model = models.SpeakerProposal
fields = ['name', 'biography', 'picture_small', 'picture_large']
template_name = 'speakerproposal_form.html'
2017-03-12 14:43:41 +00:00
2017-03-14 17:06:23 +00:00
def get_success_url(self):
return reverse('proposal_list', kwargs={'camp_slug': self.camp.slug})
2017-03-12 14:43:41 +00:00
class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, EnsureUnapprovedProposalMixin, EnsureWritableCampMixin, EnsureCFSOpenMixin, UpdateView):
model = models.SpeakerProposal
2017-03-12 14:43:41 +00:00
fields = ['name', 'biography', 'picture_small', 'picture_large']
template_name = 'speakerproposal_form.html'
2017-03-12 14:43:41 +00:00
def get_success_url(self):
return reverse('proposal_list', kwargs={'camp_slug': self.camp.slug})
2017-03-12 14:43:41 +00:00
def form_valid(self, form):
if form.instance.proposal_status == models.UserSubmittedModel.PROPOSAL_PENDING:
2017-04-01 19:45:43 +00:00
messages.warning(self.request, "Your speaker proposal has been reverted to status draft. Please submit it again when you are ready.")
form.instance.proposal_status = models.UserSubmittedModel.PROPOSAL_DRAFT
return super().form_valid(form)
class SpeakerProposalSubmitView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, EnsureUnapprovedProposalMixin, EnsureWritableCampMixin, EnsureCFSOpenMixin, UpdateView):
model = models.SpeakerProposal
fields = []
template_name = 'speakerproposal_submit.html'
def get_success_url(self):
return reverse('proposal_list', kwargs={'camp_slug': self.camp.slug})
def form_valid(self, form):
form.instance.proposal_status = models.UserSubmittedModel.PROPOSAL_PENDING
messages.info(self.request, "Your proposal has been submitted and is now pending approval")
return super().form_valid(form)
class SpeakerProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
model = models.SpeakerProposal
template_name = 'speakerproposal_detail.html'
2017-03-12 14:43:41 +00:00
@method_decorator(require_safe, name='dispatch')
class SpeakerProposalPictureView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, PictureViewMixin, DetailView):
model = models.SpeakerProposal
def get(self, request, *args, **kwargs):
2017-03-14 17:06:23 +00:00
# is the proposal owned by current user?
if self.get_object().user != request.user:
2017-03-12 14:43:41 +00:00
raise Http404()
# get and return the response
2017-03-29 22:20:14 +00:00
response = self.get_picture_response('/public/speakerproposals/%(campslug)s/%(proposaluuid)s/%(filename)s' % {
'campslug': self.camp.slug,
'proposaluuid': self.get_object().uuid,
'filename': os.path.basename(self.picture.name),
})
2017-03-12 14:43:41 +00:00
return response
class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, CreateProposalMixin, EnsureWritableCampMixin, EnsureCFSOpenMixin, CreateView):
model = models.EventProposal
2017-03-12 14:43:41 +00:00
fields = ['title', 'abstract', 'event_type', 'speakers']
template_name = 'eventproposal_form.html'
2017-03-12 14:43:41 +00:00
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'].fields['speakers'].queryset = models.SpeakerProposal.objects.filter(camp=self.camp, user=self.request.user)
2017-03-12 15:16:24 +00:00
context['form'].fields['event_type'].queryset = models.EventType.objects.filter(public=True)
2017-03-12 14:43:41 +00:00
return context
class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, EnsureUnapprovedProposalMixin, EnsureWritableCampMixin, EnsureCFSOpenMixin, UpdateView):
model = models.EventProposal
2017-03-12 14:52:24 +00:00
fields = ['title', 'abstract', 'event_type', 'speakers']
template_name = 'eventproposal_form.html'
def get_success_url(self):
return reverse('proposal_list', kwargs={'camp_slug': self.camp.slug})
2017-03-12 15:16:24 +00:00
def form_valid(self, form):
if form.instance.proposal_status == models.UserSubmittedModel.PROPOSAL_PENDING:
2017-04-01 19:45:43 +00:00
messages.warning(self.request, "Your event proposal has been reverted to status draft. Please submit it again when you are ready.")
form.instance.proposal_status = models.UserSubmittedModel.PROPOSAL_DRAFT
return super().form_valid(form)
class EventProposalSubmitView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, EnsureUnapprovedProposalMixin, EnsureWritableCampMixin, EnsureCFSOpenMixin, UpdateView):
model = models.EventProposal
fields = []
template_name = 'eventproposal_submit.html'
def get_success_url(self):
return reverse('proposal_list', kwargs={'camp_slug': self.camp.slug})
def form_valid(self, form):
form.instance.proposal_status = models.UserSubmittedModel.PROPOSAL_PENDING
messages.info(self.request, "Your proposal has been submitted and is now pending approval")
return super().form_valid(form)
class EventProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
model = models.EventProposal
template_name = 'eventproposal_detail.html'
2017-03-12 14:43:41 +00:00
################## speakers ###############################################
@method_decorator(require_safe, name='dispatch')
class SpeakerPictureView(CampViewMixin, PictureViewMixin, DetailView):
model = models.Speaker
def get(self, request, *args, **kwargs):
2017-03-29 22:20:14 +00:00
# get and return the response
response = self.get_picture_response(path='/public/speakers/%(campslug)s/%(slug)s/%(filename)s' % {
'campslug': self.camp.slug,
'slug': self.get_object().slug,
'filename': os.path.basename(self.picture.name),
})
return response
2016-07-13 20:37:20 +00:00
2016-08-08 17:45:32 +00:00
class SpeakerDetailView(CampViewMixin, DetailView):
2016-08-08 17:45:32 +00:00
model = models.Speaker
template_name = 'speaker_detail.html'
class SpeakerListView(CampViewMixin, ListView):
2016-08-08 17:36:13 +00:00
model = models.Speaker
template_name = 'speaker_list.html'
2017-03-12 14:43:41 +00:00
################## events ##############################################
2017-01-23 17:57:30 +00:00
class EventListView(CampViewMixin, ListView):
2016-08-08 17:36:13 +00:00
model = models.Event
template_name = 'event_list.html'
2016-07-13 20:37:20 +00:00
2017-03-12 14:43:41 +00:00
class EventDetailView(CampViewMixin, DetailView):
model = models.Event
template_name = 'schedule_event_detail.html'
################## schedule #############################################
class ScheduleView(CampViewMixin, TemplateView):
def get_template_names(self):
if 'day' in self.kwargs:
return 'schedule_day.html'
return 'schedule_overview.html'
2016-07-13 20:37:20 +00:00
def get_context_data(self, *args, **kwargs):
context = super(ScheduleView, self).get_context_data(**kwargs)
eventinstances = models.EventInstance.objects.filter(event__in=self.camp.events.all())
type_slug = self.request.GET.get('type', None)
location_slug = self.request.GET.get('location', None)
if type_slug:
2017-01-23 17:57:30 +00:00
try:
eventtype = models.EventType.objects.get(
slug=type_slug
2017-01-23 17:57:30 +00:00
)
except models.EventType.DoesNotExist:
raise Http404
context['eventtype'] = eventtype
context['get_string'] = '?type={}'.format(type_slug)
eventinstances = eventinstances.filter(event__event_type=eventtype)
if location_slug:
try:
eventlocation = models.EventLocation.objects.get(
slug=location_slug,
camp=self.camp,
)
except models.EventLocation.DoesNotExist:
raise Http404
context['location'] = eventlocation
get_part = 'location={}'.format(location_slug)
if 'get_string' in context:
context['get_string'] = context['get_string'] + '&{}'.format(get_part)
else:
context['get_string'] = '?{}'.format(get_part)
eventinstances = eventinstances.filter(location=eventlocation)
context['eventinstances'] = eventinstances
2017-01-23 17:57:30 +00:00
# Do stuff if we are dealing with a day schedule
if 'day' in kwargs:
when = datetime.datetime(year=int(self.kwargs['year']), month=int(self.kwargs['month']), day=int(self.kwargs['day']))
eventinstances = models.EventInstance.objects.filter(event__in=self.camp.events.all())
skip = []
for ei in eventinstances:
if ei.schedule_date != when.date():
skip.append(ei.id)
else:
if 'type' in self.request.GET:
eventtype = models.EventType.objects.get(
slug=self.request.GET['type']
)
if ei.event.event_type != eventtype:
skip.append(ei.id)
eventinstances = eventinstances.exclude(id__in=skip).order_by('event__event_type')
if 'location' in self.request.GET:
eventlocation = models.EventLocation.objects.get(
camp=self.camp,
slug=self.request.GET['location']
)
eventinstances = eventinstances.filter(location=eventlocation)
context['eventinstances'] = eventinstances
start = when + datetime.timedelta(hours=settings.SCHEDULE_MIDNIGHT_OFFSET_HOURS)
timeslots = []
# calculate how many timeslots we have in the schedule based on the lenght of the timeslots in minutes,
# and the number of minutes in 24 hours
for i in range(0,int((24*60)/settings.SCHEDULE_TIMESLOT_LENGTH_MINUTES)):
timeslot = start + datetime.timedelta(minutes=i*settings.SCHEDULE_TIMESLOT_LENGTH_MINUTES)
timeslots.append(timeslot)
context['timeslots'] = timeslots
2017-01-23 22:58:41 +00:00
# include the components to make the urls
context['urlyear'] = self.kwargs['year']
context['urlmonth'] = self.kwargs['month']
context['urlday'] = self.kwargs['day']
2017-01-23 22:58:41 +00:00
return context
2016-08-07 13:49:30 +00:00
class CallForSpeakersView(CampViewMixin, TemplateView):
def get_template_names(self):
return '%s_call_for_speakers.html' % self.camp.slug