""" All views to display or edit events and event-photos. """ from datetime import timedelta from django.contrib.auth import get_user_model from django.contrib.auth.mixins import PermissionRequiredMixin from django.urls import reverse from django.db.models import Q from django.http import HttpResponse, Http404 from django.shortcuts import redirect from django.utils import timezone from django.utils.translation import ugettext as _ from django.views import generic from extra_views import InlineFormSetView from icalendar import Calendar, Event from . import forms, mixins, models class DeleteEventPhoto(PermissionRequiredMixin, mixins.EventDetailMixin, generic.DeleteView): """Delete a requested photo and redirect to the album view.""" model = models.Photo permission_required = 'events.delete_photo' def get_success_url(self): """Redirect to the album view of the event from the deleted image.""" return reverse('event-photo-list', args=[self.object.event_id]) class EventArchiveIndex(mixins.EventArchiveMixin, generic.ArchiveIndexView): """Index of the event archive, displays the upcoming events first.""" allow_empty = True class EventArchiveMonth(mixins.EventArchiveMixin, generic.MonthArchiveView): """List the events from the specific month of the given year.""" month_format = '%m' class EventArchiveYear(mixins.EventArchiveMixin, generic.YearArchiveView): """List all events from the specified year.""" year_format = '%Y' class EventDetail(mixins.EventDetailMixin, generic.DetailView): """Detail View to see all details of an event.""" model = models.Event class EventForm(PermissionRequiredMixin, mixins.EventDetailMixin, generic.UpdateView): """Frontend formular to add or edit a Event.""" form_class = forms.EventForm template_name = 'events/event_form.html' permission_required = 'events.add_event' def get_context_data(self, **kwargs): """Dynamicle set the title to Add or Edit Event, depanding if an event ID was given, or not.""" context = super(EventForm, self).get_context_data(**kwargs) if self.kwargs.get('pk'): context['title'] = _("Edit Event") else: context['title'] = _("Add Event") return context def get_object(self, queryset=None): """Try return the existing Event for an update if an id has been submitted, else create a new one. """ return models.Event.objects.get(pk=self.kwargs['pk']) \ if self.kwargs.get('pk') else models.Event() class EventGallery(generic.ListView): """Display a overview of all event photo albums.""" template_name = 'events/photo_gallery.html' queryset = models.Event.objects.filter( start__lt=timezone.now(), event_series__isnull=True, photo_count__gt=0 ) queryset = queryset.order_by('-start') paginate_by = 24 class EventListIcal(generic.View): """Generates an returns an iCal File with all upcoming events.""" def get(self, request, *args, **kwargs): """Add all upcoming events to an .ics file and send it.""" response = HttpResponse(content_type="text/calendar; charset=UTF-8") calendar = Calendar() calendar.add('prodid', 'http://www.kasu.at/') calendar.add('version', '2.0') for event in models.Event.objects.upcoming(limit=None): ics_event = Event() ics_event.add('DTSTART', timezone.localtime(event.start)) ics_event.add('SUMMARY', event.name) ics_event.add('DESCRIPTION', event.description) ics_event.add('LOCATION', event.location.address) ics_event.add('URL', 'http://www.kasu.at' + event.get_absolute_url()) ics_event['UID'] = 'event-%d@www.kasu.at' % event.pk ics_event.add('PRIORITY', 5) if event.end: ics_event.add('DTEND', timezone.localtime(event.end)) calendar.add_component(ics_event) response.write(calendar.to_ical()) return response class EventPhoto(mixins.EventDetailMixin, generic.UpdateView): """Display the requested Photo and allows rotation if the user has change permissions.""" form_class = forms.EditPhotoForm model = models.Photo template_name = 'events/photo_detail.html' def post(self, request, *args, **kwargs): if request.POST.get('rotate') and request.user.has_perm( 'events.change_photo'): photo = models.Photo.objects.get(pk=kwargs['pk']) photo.rotate(request.POST['rotate']) return self.get(request) else: return generic.UpdateView.post(self, request, *args, **kwargs) class EventPhotoList(mixins.EventDetailMixin, generic.ListView): """List all Photos of the event or event series in an album.""" context_object_name = 'photo_list' event = None paginate_by = 36 def get_context_data(self, **kwargs): context = super(EventPhotoList, self).get_context_data(**kwargs) context['form'] = forms.PhotoUploadForm( initial={'event': self.event, 'photographer': self.request.user}) return context def get_queryset(self): try: self.event = models.Event.objects.get(id=self.kwargs['event']) return models.Photo.objects.filter( Q(event=self.event) | Q(event__event_series=self.event) ) except models.Event.DoesNotExist: raise Http404(_('Event does not exist')) class EventPhotoUpload(mixins.EventDetailMixin, generic.FormView): form_class = forms.PhotoUploadForm template_name = 'events/photo_upload.html' permission_required = 'events.add_photo' def get_context_data(self, **kwargs): context = generic.FormView.get_context_data(self, **kwargs) context['event_list'] = models.Event.objects.archive()[:12] return context def get_initial(self): """ Set the current user as default value for the photographer.""" return {'photographer': self.request.user, } def post(self, *args, **kwargs): event = models.Event.objects.get(id=self.request.POST.get('event')) photographer = get_user_model().objects.get( id=self.request.POST.get('photographer', self.request.user.id)) counter = 0 for image_file in self.request.FILES.getlist('upload'): photo = models.Photo( event=event, photographer=photographer, image=image_file, name=image_file.name, created_date=event.start + timedelta(minutes=counter), description='' ) photo.save() counter += 1 return redirect('event-photo-list', event=event.id) class EventSeriesForm(mixins.EventDetailMixin, PermissionRequiredMixin, InlineFormSetView): model = models.Event inline_model = models.Event fk_name = 'event_series' fields = ('start', 'end') form_class = forms.EventForm extra = 3 permission_required = 'events.add_event' template_name = 'events/eventseries_form.html' def get_object(self, queryset=None): self.event = models.Event.objects.get(pk=self.kwargs['pk']) if self.event.event_series: self.event = self.event.event_series return self.event class UpcomingEvents(generic.ListView): queryset = models.Event.objects.upcoming(limit=None) paginate_by = 16