328 lines
13 KiB
Python
328 lines
13 KiB
Python
# -*- coding: utf-8 -*-
|
|
import datetime
|
|
import logging
|
|
import os
|
|
from django.apps import apps
|
|
from django.contrib import messages
|
|
from django.contrib.auth import login
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.core.exceptions import PermissionDenied, SuspiciousOperation
|
|
from django.db.models import Q
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
from django.shortcuts import get_object_or_404
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.utils.decorators import method_decorator
|
|
from django.utils.translation import ugettext as _
|
|
from django.views import generic
|
|
|
|
from .. import choices
|
|
from .. import forms
|
|
from .. import models
|
|
from ..utils import has_role
|
|
|
|
app_config = apps.get_containing_app_config(__package__)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class EventListView(generic.ListView):
|
|
model = models.Event
|
|
|
|
def get_queryset(self):
|
|
user = self.request.user
|
|
if user.is_superuser:
|
|
qs = self.model.objects.all()
|
|
elif has_role(user, 'manage_all'):
|
|
qs = self.model.objects.all()
|
|
else:
|
|
filter = Q(owner=user)
|
|
|
|
user_sports_list = list()
|
|
for k in ('W', 'S', 'M', 'K', 'B'):
|
|
role = 'manage_{}'.format(k.lower())
|
|
if has_role(user, role):
|
|
user_sports_list.append(k)
|
|
|
|
filter |= Q(sport__in=user_sports_list)
|
|
|
|
if has_role(user, 'publish') or has_role(user, 'publish_incremental'):
|
|
filter |= Q(accepted=True)
|
|
|
|
qs = self.model.objects.filter(filter)
|
|
|
|
return qs
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(EventListView, self).get_context_data(**kwargs)
|
|
user = self.request.user
|
|
context['has_permission_export'] = user.is_superuser or has_role(user, 'publish')
|
|
return context
|
|
|
|
@method_decorator(login_required)
|
|
def dispatch(self, request, *args, **kwargs):
|
|
return super(EventListView, self).dispatch(request, *args, **kwargs)
|
|
|
|
|
|
class EventListExportView(generic.FormView):
|
|
form_class = forms.events.EventListExportForm
|
|
template_name = 'dav_events/event_list_export_form.html'
|
|
|
|
def form_valid(self, form):
|
|
filename = _(u'Veranstaltungen')
|
|
filter_kwargs = {
|
|
'accepted': True,
|
|
}
|
|
if form.cleaned_data['sport']:
|
|
sport = form.cleaned_data['sport']
|
|
filter_kwargs['sport'] = sport
|
|
filename += u'--%s' % choices.SPORT_CHOICES.get_label(sport)
|
|
if form.cleaned_data['begin']:
|
|
date = form.cleaned_data['begin']
|
|
filter_kwargs['first_day__gte'] = date
|
|
filename += u'--%s' % date.strftime('%Y-%m-%d')
|
|
if form.cleaned_data['end']:
|
|
date = form.cleaned_data['end']
|
|
filter_kwargs['first_day__lte'] = date
|
|
filename += u'--%s' % date.strftime('%Y-%m-%d')
|
|
|
|
exclude_expired = not form.cleaned_data.get('expired', False)
|
|
|
|
txt = u''
|
|
event_qs = models.Event.objects.filter(**filter_kwargs).order_by('sport', 'first_day')
|
|
for event in event_qs:
|
|
if exclude_expired and event.get_status() == 'expired':
|
|
continue
|
|
txt += event.render_as_text(format='ka-alpin')
|
|
if event.internal_note:
|
|
txt += u'\n> Bearbeitungshinweis:\n> ' + event.internal_note.replace('\n', '\n> ') + u'\n'
|
|
txt += u'\n' + (u'-' * 72) + '\n\n'
|
|
|
|
filename += u'.txt'
|
|
|
|
response = HttpResponse(txt, content_type='text/plain')
|
|
response['Content-Disposition'] = 'attachment; filename="{filename}"'.format(filename=filename)
|
|
return response
|
|
|
|
@method_decorator(login_required)
|
|
def dispatch(self, request, *args, **kwargs):
|
|
user = request.user
|
|
if not user.is_superuser and not has_role(user, 'publish'):
|
|
raise PermissionDenied('publish')
|
|
return super(EventListExportView, self).dispatch(request, *args, **kwargs)
|
|
|
|
|
|
class EventPermissionMixin(object):
|
|
permission = 'view'
|
|
|
|
def has_permission(self, permission, obj):
|
|
user = self.request.user
|
|
|
|
if user.is_superuser:
|
|
return True
|
|
|
|
if permission == 'view':
|
|
if obj.owner == user:
|
|
return True
|
|
if has_role(user, 'manage_all'):
|
|
return True
|
|
if has_role(user, 'manage_{}'.format(obj.sport.lower())):
|
|
return True
|
|
if obj.accepted and (has_role(user, 'publish') or has_role(user, 'publish_incremental')):
|
|
return True
|
|
elif permission == 'accept':
|
|
if has_role(user, 'manage_all'):
|
|
return True
|
|
if has_role(user, 'manage_{}'.format(obj.sport.lower())):
|
|
return True
|
|
elif permission == 'update':
|
|
if not obj.accepted and not obj.publication_confirmed:
|
|
if has_role(user, 'manage_all'):
|
|
return True
|
|
if has_role(user, 'manage_{}'.format(obj.sport.lower())):
|
|
return True
|
|
elif has_role(user, 'publish') or has_role(user, 'publish_incremental'):
|
|
return True
|
|
elif permission == 'publish':
|
|
if has_role(user, 'publish') or has_role(user, 'publish_incremental'):
|
|
return True
|
|
|
|
return False
|
|
|
|
def enforce_permission(self, obj):
|
|
permission = self.permission
|
|
if not self.has_permission(permission, obj):
|
|
raise PermissionDenied(permission)
|
|
|
|
|
|
class EventDetailView(EventPermissionMixin, generic.DetailView):
|
|
model = models.Event
|
|
|
|
def get_object(self, queryset=None):
|
|
obj = super(EventDetailView, self).get_object(queryset=queryset)
|
|
self.enforce_permission(obj)
|
|
return obj
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(EventDetailView, self).get_context_data(**kwargs)
|
|
obj = context.get('event')
|
|
context['has_permission_accept'] = self.has_permission('accept', obj)
|
|
context['has_permission_update'] = self.has_permission('update', obj)
|
|
context['has_permission_publish'] = self.has_permission('publish', obj)
|
|
return context
|
|
|
|
@method_decorator(login_required)
|
|
def dispatch(self, request, *args, **kwargs):
|
|
return super(EventDetailView, self).dispatch(request, *args, **kwargs)
|
|
|
|
|
|
class EventAcceptView(EventDetailView):
|
|
permission = 'accept'
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
event = self.get_object()
|
|
event.accept(request.user)
|
|
messages.success(request, _(u'Veranstaltung freigegeben.'))
|
|
return HttpResponseRedirect(event.get_absolute_url())
|
|
|
|
|
|
class EventConfirmPublicationView(EventDetailView):
|
|
permission = 'publish'
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
event = self.get_object()
|
|
if event.accepted:
|
|
event.confirm_publication(request.user)
|
|
messages.success(request, _(u'Veröffentlichung registriert.'))
|
|
else:
|
|
messages.error(request, _(u'Veranstaltung ist noch nicht freigegeben.'))
|
|
return HttpResponseRedirect(event.get_absolute_url())
|
|
|
|
|
|
class EventUpdateView(EventPermissionMixin, generic.UpdateView):
|
|
permission = 'update'
|
|
model = models.Event
|
|
form_class = forms.events.EventUpdateForm
|
|
template_name_suffix = '_update_form'
|
|
|
|
def get_object(self, queryset=None):
|
|
obj = super(EventUpdateView, self).get_object(queryset=queryset)
|
|
self.enforce_permission(obj)
|
|
return obj
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(EventUpdateView, self).get_context_data(**kwargs)
|
|
obj = context.get('event')
|
|
context['has_permission_accept'] = self.has_permission('accept', obj)
|
|
context['has_permission_update'] = self.has_permission('update', obj)
|
|
context['has_permission_publish'] = self.has_permission('publish', obj)
|
|
return context
|
|
|
|
@method_decorator(login_required)
|
|
def dispatch(self, request, *args, **kwargs):
|
|
return super(EventUpdateView, self).dispatch(request, *args, **kwargs)
|
|
|
|
|
|
class EventCreateView(EventPermissionMixin, generic.FormView):
|
|
form_class = forms.events.EventCreateForm
|
|
template_dir = os.path.join('dav_events', 'event_create')
|
|
default_template_name = 'default.html'
|
|
abort_url = reverse_lazy('dav_events:home')
|
|
|
|
def get_template_names(self):
|
|
form = self.get_form()
|
|
form_name = form.form_name
|
|
template = os.path.join(self.template_dir, '{}.html'.format(form_name))
|
|
default_template = os.path.join(self.template_dir, self.default_template_name)
|
|
return [
|
|
template, default_template
|
|
]
|
|
|
|
def get_form_class(self, form_name=None):
|
|
if form_name is not None:
|
|
form_class = getattr(forms.events, form_name)
|
|
elif 'dav_events_event_create_next_form_name' in self.request.session:
|
|
form_name = self.request.session['dav_events_event_create_next_form_name']
|
|
form_class = getattr(forms.events, form_name)
|
|
if not issubclass(form_class, self.form_class):
|
|
raise SuspiciousOperation('Invalid next form: {}'.format(form_name))
|
|
else:
|
|
base_form_class = self.form_class
|
|
initial_form_name = base_form_class.get_initial_form_name()
|
|
form_class = getattr(forms.events, initial_form_name)
|
|
|
|
return form_class
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super(EventCreateView, self).get_form_kwargs()
|
|
if 'request' not in kwargs:
|
|
kwargs['request'] = self.request
|
|
return kwargs
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super(EventCreateView, self).get_context_data(**kwargs)
|
|
context['abort_url'] = self.abort_url
|
|
return context
|
|
|
|
def form_valid(self, form):
|
|
event = form.get_instance()
|
|
|
|
next_form_name = form.next_form_name
|
|
if next_form_name:
|
|
self.request.session['dav_events_event_create_next_form_name'] = next_form_name
|
|
next_form_class = self.get_form_class(next_form_name)
|
|
next_form = next_form_class(request=self.request)
|
|
return self.render_to_response(self.get_context_data(form=next_form, event=event))
|
|
else:
|
|
event.save()
|
|
form.flush_session_data()
|
|
messages.success(self.request, _(u'Veranstaltung angelegt.'))
|
|
owner = event.owner
|
|
self.clean_session_data()
|
|
if self.request.user.is_authenticated:
|
|
next_url = reverse('dav_events:event_list')
|
|
elif owner.has_usable_password():
|
|
next_url = reverse('dav_events:event_list')
|
|
else:
|
|
login(self.request, owner)
|
|
next_url = reverse('dav_events:set_password')
|
|
messages.success(self.request,
|
|
_(u'Neuen Benutzer angemeldet: %(username)s') % {'username': owner.username})
|
|
messages.warning(self.request, _(u'Bitte neues Passwort setzen!'))
|
|
return HttpResponseRedirect(next_url)
|
|
|
|
def clean_session_data(self, session=None):
|
|
if session is None:
|
|
session = self.request.session
|
|
if 'dav_events_event_create_next_form_name' in session:
|
|
del session['dav_events_event_create_next_form_name']
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
self.clean_session_data(request.session)
|
|
if 'abort' in request.GET:
|
|
form = self.get_form()
|
|
form.flush_session_data()
|
|
return HttpResponseRedirect(self.abort_url)
|
|
elif 'copy' in request.GET:
|
|
event = get_object_or_404(models.Event, pk=request.GET.get('copy'))
|
|
if not self.has_permission('view', event):
|
|
raise PermissionDenied('copy')
|
|
|
|
for field in ('id',
|
|
'owner', 'created_at',
|
|
'accepted_at', 'accepted_by',
|
|
'publication_confirmed_at', 'publication_confirmed_by',
|
|
'number',
|
|
'planned_publication_date', 'internal_note',):
|
|
if hasattr(event, field):
|
|
setattr(event, field, None)
|
|
for field in ('accepted', 'publication_confirmed'):
|
|
if hasattr(event, field):
|
|
setattr(event, field, False)
|
|
|
|
initial_form_name = self.form_class.get_initial_form_name()
|
|
form_class = getattr(forms.events, initial_form_name)
|
|
form = form_class(request=self.request, instance=event)
|
|
form.save_session_data()
|
|
return super(EventCreateView, self).get(request, *args, **kwargs)
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
return super(EventCreateView, self).post(request, *args, **kwargs) |