2012-04-13 23:52:34 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
openslides.utils.views
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2012-04-25 22:29:19 +02:00
|
|
|
Views for OpenSlides.
|
2012-04-13 23:52:34 +02:00
|
|
|
|
2012-04-25 22:29:19 +02:00
|
|
|
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
2012-04-13 23:52:34 +02:00
|
|
|
:license: GNU GPL, see LICENSE for more details.
|
|
|
|
"""
|
|
|
|
|
2012-12-14 14:21:53 +01:00
|
|
|
import json
|
2013-02-02 10:59:07 +01:00
|
|
|
from cStringIO import StringIO
|
2012-11-24 14:01:21 +01:00
|
|
|
from reportlab.platypus import SimpleDocTemplate, Spacer
|
2012-02-21 13:17:42 +01:00
|
|
|
from reportlab.lib.units import cm
|
|
|
|
|
2012-03-16 14:31:59 +01:00
|
|
|
from django.contrib import messages
|
2012-02-20 17:46:45 +01:00
|
|
|
from django.contrib.auth.decorators import login_required
|
2012-07-01 15:35:05 +02:00
|
|
|
from django.core.context_processors import csrf
|
2013-01-26 16:19:53 +01:00
|
|
|
from django.core.exceptions import ImproperlyConfigured
|
2012-07-01 15:35:05 +02:00
|
|
|
from django.core.urlresolvers import reverse
|
|
|
|
from django.conf import settings
|
2012-03-18 17:11:58 +01:00
|
|
|
from django.dispatch import receiver
|
2012-07-01 15:35:05 +02:00
|
|
|
from django.http import HttpResponseServerError, HttpResponse, HttpResponseRedirect
|
|
|
|
from django.utils.decorators import method_decorator
|
2012-11-24 14:01:21 +01:00
|
|
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
2012-04-15 11:24:40 +02:00
|
|
|
from django.utils.importlib import import_module
|
2012-11-24 14:01:21 +01:00
|
|
|
from django.template import RequestContext
|
2012-07-01 15:35:05 +02:00
|
|
|
from django.template.loader import render_to_string
|
2012-03-16 14:31:59 +01:00
|
|
|
from django.views.generic import (
|
|
|
|
TemplateView as _TemplateView,
|
|
|
|
RedirectView as _RedirectView,
|
|
|
|
UpdateView as _UpdateView,
|
|
|
|
CreateView as _CreateView,
|
2012-03-18 14:33:53 +01:00
|
|
|
View as _View,
|
2012-03-16 14:31:59 +01:00
|
|
|
FormView as _FormView,
|
2012-04-11 10:58:59 +02:00
|
|
|
ListView as _ListView,
|
2013-01-06 12:07:37 +01:00
|
|
|
DetailView as _DetailView,
|
2012-03-16 14:31:59 +01:00
|
|
|
)
|
2012-02-20 17:46:45 +01:00
|
|
|
from django.views.generic.detail import SingleObjectMixin
|
2012-04-13 11:35:53 +02:00
|
|
|
from django.views.generic.list import TemplateResponseMixin
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2012-10-24 11:39:27 +02:00
|
|
|
from openslides.utils.utils import render_to_forbidden, html_strong
|
2012-03-06 12:16:03 +01:00
|
|
|
from openslides.utils.signals import template_manipulation
|
2012-07-01 15:35:05 +02:00
|
|
|
from openslides.utils.pdf import firstPage, laterPages
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2012-04-15 11:24:40 +02:00
|
|
|
|
2012-04-14 18:13:55 +02:00
|
|
|
NO_PERMISSION_REQUIRED = 'No permission required'
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2012-03-18 14:33:53 +01:00
|
|
|
View = _View
|
|
|
|
|
2012-04-12 14:20:05 +02:00
|
|
|
|
2012-04-13 11:35:53 +02:00
|
|
|
class SetCookieMixin(object):
|
|
|
|
def render_to_response(self, context, **response_kwargs):
|
2012-11-24 14:01:21 +01:00
|
|
|
response = TemplateResponseMixin.render_to_response(
|
|
|
|
self, context, **response_kwargs)
|
2012-04-13 11:35:53 +02:00
|
|
|
if 'cookie' in context:
|
|
|
|
response.set_cookie(context['cookie'][0], context['cookie'][1])
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2012-02-20 17:46:45 +01:00
|
|
|
class LoginMixin(object):
|
|
|
|
@method_decorator(login_required)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
return super(LoginMixin, self).dispatch(request, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
class PermissionMixin(object):
|
2012-04-14 18:13:55 +02:00
|
|
|
permission_required = NO_PERMISSION_REQUIRED
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2012-10-24 12:45:40 +02:00
|
|
|
def has_permission(self, request, *args, **kwargs):
|
2012-04-14 18:13:55 +02:00
|
|
|
if self.permission_required == NO_PERMISSION_REQUIRED:
|
2012-04-15 11:24:40 +02:00
|
|
|
return True
|
2012-02-20 17:46:45 +01:00
|
|
|
else:
|
2012-04-15 11:24:40 +02:00
|
|
|
return request.user.has_perm(self.permission_required)
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2012-04-15 11:24:40 +02:00
|
|
|
def dispatch(self, request, *args, **kwargs):
|
2012-10-24 12:45:40 +02:00
|
|
|
if not self.has_permission(request, *args, **kwargs):
|
2012-03-18 14:33:53 +01:00
|
|
|
if not request.user.is_authenticated():
|
|
|
|
path = request.get_full_path()
|
2012-11-24 14:01:21 +01:00
|
|
|
return HttpResponseRedirect(
|
|
|
|
"%s?next=%s" % (settings.LOGIN_URL, path))
|
2012-02-20 17:46:45 +01:00
|
|
|
else:
|
2012-10-24 11:39:27 +02:00
|
|
|
return render_to_forbidden(request)
|
2013-04-28 09:37:15 +02:00
|
|
|
return super(PermissionMixin, self).dispatch(request, *args, **kwargs)
|
2012-02-20 17:46:45 +01:00
|
|
|
|
|
|
|
|
2012-07-01 15:35:05 +02:00
|
|
|
class AjaxMixin(object):
|
|
|
|
def get_ajax_context(self, **kwargs):
|
|
|
|
return {}
|
|
|
|
|
|
|
|
def ajax_get(self, request, *args, **kwargs):
|
|
|
|
return HttpResponse(json.dumps(self.get_ajax_context(**kwargs)))
|
|
|
|
|
|
|
|
|
2013-01-06 12:07:37 +01:00
|
|
|
class ExtraContextMixin(object):
|
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
context = super(ExtraContextMixin, self).get_context_data(**kwargs)
|
2013-05-06 20:17:13 +02:00
|
|
|
context.setdefault('extra_javascript', [])
|
2013-01-06 12:07:37 +01:00
|
|
|
template_manipulation.send(
|
|
|
|
sender=self.__class__, request=self.request, context=context)
|
|
|
|
return context
|
|
|
|
|
|
|
|
|
2013-01-26 16:19:53 +01:00
|
|
|
class UrlMixin(object):
|
2013-05-11 00:59:07 +02:00
|
|
|
"""
|
|
|
|
Mixin to provide the use of url names in views with success url and
|
|
|
|
apply url.
|
|
|
|
|
|
|
|
The initial value of url_name_args is None, but the default given by
|
|
|
|
the used get_url_name_args method is [], because in the future, the
|
|
|
|
method might return another default value. Compare this with the QuestionMixin.
|
|
|
|
"""
|
2013-01-26 16:19:53 +01:00
|
|
|
apply_url_name = None
|
|
|
|
success_url_name = None
|
2013-05-11 00:59:07 +02:00
|
|
|
url_name_args = None
|
2013-01-26 16:19:53 +01:00
|
|
|
success_url = None
|
|
|
|
apply_url = None
|
|
|
|
|
|
|
|
def get_apply_url(self):
|
|
|
|
if self.apply_url_name:
|
2013-02-01 12:51:01 +01:00
|
|
|
return reverse(self.apply_url_name, args=self.get_url_name_args())
|
2013-01-26 16:19:53 +01:00
|
|
|
elif self.apply_url:
|
|
|
|
return self.apply_url
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
return self.object.get_absolute_url('edit')
|
|
|
|
except AttributeError:
|
|
|
|
raise ImproperlyConfigured(
|
|
|
|
"No URL to redirect to. Provide an apply_url_name.")
|
|
|
|
|
2013-01-06 12:07:37 +01:00
|
|
|
def get_success_url(self):
|
|
|
|
if 'apply' in self.request.POST:
|
2013-01-26 16:19:53 +01:00
|
|
|
return self.get_apply_url()
|
2013-01-26 16:33:55 +01:00
|
|
|
|
2013-01-26 16:19:53 +01:00
|
|
|
if self.success_url_name:
|
2013-02-01 12:51:01 +01:00
|
|
|
return reverse(self.success_url_name, args=self.get_url_name_args())
|
2013-01-26 16:19:53 +01:00
|
|
|
elif self.success_url:
|
|
|
|
return self.success_url
|
2013-01-06 12:07:37 +01:00
|
|
|
else:
|
|
|
|
try:
|
2013-02-01 12:51:01 +01:00
|
|
|
return self.object.get_absolute_url()
|
2013-01-06 12:07:37 +01:00
|
|
|
except AttributeError:
|
|
|
|
raise ImproperlyConfigured(
|
2013-05-11 00:59:07 +02:00
|
|
|
"No URL to redirect to. Either provide an URL or define "
|
|
|
|
"a get_absolute_url method of the model.")
|
2013-02-01 12:51:01 +01:00
|
|
|
|
|
|
|
def get_url_name_args(self):
|
2013-05-11 00:59:07 +02:00
|
|
|
"""
|
|
|
|
Returns the arguments for the url name. Default is an empty list.
|
|
|
|
"""
|
|
|
|
if self.url_name_args is not None:
|
|
|
|
return self.url_name_args
|
2013-02-01 12:51:01 +01:00
|
|
|
return []
|
2013-01-06 12:07:37 +01:00
|
|
|
|
|
|
|
|
2012-08-10 21:00:13 +02:00
|
|
|
class QuestionMixin(object):
|
2013-05-11 00:59:07 +02:00
|
|
|
"""
|
|
|
|
Mixin for questions to the requesting user.
|
|
|
|
|
|
|
|
The initial value of url_name_args is None, but the default given by
|
|
|
|
the used get_url_name_args method is [self.object.pk] if it exist, else
|
|
|
|
an empty list. Set url_name_args to an empty list, if you use an url
|
|
|
|
name which does not need any arguments.
|
|
|
|
"""
|
2012-08-10 21:00:13 +02:00
|
|
|
question = ugettext_lazy('Are you sure?')
|
2012-08-10 21:24:26 +02:00
|
|
|
success_message = ugettext_lazy('Thank you for your answer')
|
2012-08-10 21:00:13 +02:00
|
|
|
answer_options = [('yes', ugettext_lazy("Yes")), ('no', ugettext_lazy("No"))]
|
2013-02-03 13:23:55 +01:00
|
|
|
question_url_name = None
|
|
|
|
success_url_name = None
|
2013-05-11 00:59:07 +02:00
|
|
|
url_name_args = None
|
2013-02-03 13:23:55 +01:00
|
|
|
|
|
|
|
def get_redirect_url(self, **kwargs):
|
2013-06-13 15:43:17 +02:00
|
|
|
# TODO: raise error when question_url_name/success_url_name is not present
|
2013-02-03 13:23:55 +01:00
|
|
|
if self.request.method == 'GET':
|
2013-03-18 12:34:47 +01:00
|
|
|
return reverse(self.question_url_name, args=self.get_question_url_name_args())
|
2013-02-03 13:23:55 +01:00
|
|
|
else:
|
2013-03-18 12:34:47 +01:00
|
|
|
return reverse(self.success_url_name, args=self.get_success_url_name_args())
|
|
|
|
|
|
|
|
def get_question_url_name_args(self):
|
|
|
|
return self.get_url_name_args()
|
|
|
|
|
|
|
|
def get_success_url_name_args(self):
|
|
|
|
return self.get_url_name_args()
|
2013-02-03 13:23:55 +01:00
|
|
|
|
|
|
|
def get_url_name_args(self):
|
2013-05-11 00:59:07 +02:00
|
|
|
"""
|
|
|
|
Returns the arguments for the url name. Default is an empty list
|
|
|
|
or [self.object.pk] if this exist.
|
|
|
|
"""
|
|
|
|
if self.url_name_args is not None:
|
|
|
|
return self.url_name_args
|
2013-03-18 12:34:47 +01:00
|
|
|
try:
|
|
|
|
return [self.object.pk]
|
|
|
|
except AttributeError:
|
|
|
|
return []
|
2012-08-10 21:00:13 +02:00
|
|
|
|
2012-10-28 19:59:41 +01:00
|
|
|
def pre_redirect(self, request, *args, **kwargs):
|
2013-03-18 12:34:47 +01:00
|
|
|
"""
|
|
|
|
Prints the question in a GET request.
|
|
|
|
"""
|
2012-10-28 19:59:41 +01:00
|
|
|
self.confirm_form()
|
2012-08-10 21:00:13 +02:00
|
|
|
|
2012-08-10 21:24:26 +02:00
|
|
|
def get_question(self):
|
|
|
|
return unicode(self.question)
|
2012-08-10 21:00:13 +02:00
|
|
|
|
2012-10-28 19:59:41 +01:00
|
|
|
def get_answer_options(self):
|
|
|
|
return self.answer_options
|
2012-08-10 21:00:13 +02:00
|
|
|
|
|
|
|
def get_answer_url(self):
|
2012-10-28 19:59:41 +01:00
|
|
|
try:
|
|
|
|
return self.answer_url
|
|
|
|
except AttributeError:
|
|
|
|
return self.request.path
|
2012-08-10 21:00:13 +02:00
|
|
|
|
|
|
|
def confirm_form(self):
|
|
|
|
option_fields = "\n".join([
|
2013-01-08 23:05:35 +01:00
|
|
|
'<button type="submit" class="btn btn-mini" name="%s">%s</button>' % (option[0], unicode(option[1]))
|
2012-08-10 21:00:13 +02:00
|
|
|
for option in self.get_answer_options()])
|
2012-11-24 14:01:21 +01:00
|
|
|
messages.warning(
|
|
|
|
self.request,
|
2012-08-10 21:00:13 +02:00
|
|
|
"""
|
|
|
|
%(message)s
|
|
|
|
<form action="%(url)s" method="post">
|
|
|
|
<input type="hidden" value="%(csrf)s" name="csrfmiddlewaretoken">
|
|
|
|
%(option_fields)s
|
|
|
|
</form>
|
2012-11-24 14:01:21 +01:00
|
|
|
""" % {'message': self.get_question(),
|
|
|
|
'url': self.get_answer_url(),
|
|
|
|
'csrf': csrf(self.request)['csrf_token'],
|
|
|
|
'option_fields': option_fields})
|
2012-08-10 21:00:13 +02:00
|
|
|
|
|
|
|
def pre_post_redirect(self, request, *args, **kwargs):
|
2012-10-28 19:59:41 +01:00
|
|
|
# Reacts on the response of the user in a POST-request.
|
|
|
|
# TODO: call the methodes for all possible answers.
|
|
|
|
if self.get_answer() == 'yes':
|
|
|
|
self.case_yes()
|
|
|
|
messages.success(request, self.get_success_message())
|
|
|
|
|
|
|
|
def get_answer(self):
|
|
|
|
for option in self.get_answer_options():
|
|
|
|
if option[0] in self.request.POST:
|
|
|
|
return option[0]
|
|
|
|
return None
|
|
|
|
|
|
|
|
def case_yes(self):
|
|
|
|
# TODO: raise a warning
|
|
|
|
pass
|
|
|
|
|
|
|
|
def get_success_message(self):
|
|
|
|
return self.success_message
|
2012-08-10 21:00:13 +02:00
|
|
|
|
|
|
|
|
2013-01-06 12:07:37 +01:00
|
|
|
class TemplateView(PermissionMixin, ExtraContextMixin, _TemplateView):
|
|
|
|
pass
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2012-04-11 10:58:59 +02:00
|
|
|
|
2013-01-06 12:07:37 +01:00
|
|
|
class ListView(PermissionMixin, SetCookieMixin, ExtraContextMixin, _ListView):
|
|
|
|
pass
|
2012-04-11 10:58:59 +02:00
|
|
|
|
2013-02-02 10:52:13 +01:00
|
|
|
|
2012-07-01 15:35:05 +02:00
|
|
|
class AjaxView(PermissionMixin, AjaxMixin, View):
|
2012-04-12 14:20:05 +02:00
|
|
|
def get(self, request, *args, **kwargs):
|
2012-07-01 15:35:05 +02:00
|
|
|
return self.ajax_get(request, *args, **kwargs)
|
2012-04-12 14:20:05 +02:00
|
|
|
|
|
|
|
|
2012-07-01 15:35:05 +02:00
|
|
|
class RedirectView(PermissionMixin, AjaxMixin, _RedirectView):
|
2013-05-11 00:59:07 +02:00
|
|
|
"""
|
|
|
|
View to redirect to another url.
|
|
|
|
|
|
|
|
The initial value of url_name_args is None, but the default given by
|
|
|
|
the used get_url_name_args method is [self.object.pk] if it exist, else
|
|
|
|
an empty list. Set url_name_args to an empty list, if you use an url
|
|
|
|
name which does not need any arguments.
|
|
|
|
"""
|
2012-02-20 17:46:45 +01:00
|
|
|
permanent = False
|
|
|
|
allow_ajax = False
|
2013-02-01 12:51:01 +01:00
|
|
|
url_name = None
|
2013-05-11 00:59:07 +02:00
|
|
|
url_name_args = None
|
2012-02-20 17:46:45 +01:00
|
|
|
|
|
|
|
def pre_redirect(self, request, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def pre_post_redirect(self, request, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
if request.method == 'GET':
|
2012-04-19 12:46:04 +02:00
|
|
|
self.pre_redirect(request, *args, **kwargs)
|
2012-02-20 17:46:45 +01:00
|
|
|
elif request.method == 'POST':
|
|
|
|
self.pre_post_redirect(request, *args, **kwargs)
|
|
|
|
|
|
|
|
if self.request.is_ajax() and self.allow_ajax:
|
2012-07-01 15:35:05 +02:00
|
|
|
return self.ajax_get(request, *args, **kwargs)
|
2012-02-20 17:46:45 +01:00
|
|
|
return super(RedirectView, self).get(request, *args, **kwargs)
|
|
|
|
|
|
|
|
def get_redirect_url(self, **kwargs):
|
2013-02-01 12:51:01 +01:00
|
|
|
if self.url_name is not None:
|
2013-02-01 17:20:11 +01:00
|
|
|
return reverse(self.url_name, args=self.get_url_name_args())
|
2013-02-01 12:51:01 +01:00
|
|
|
else:
|
|
|
|
return super(RedirectView, self).get_redirect_url(**kwargs)
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2013-02-01 17:20:11 +01:00
|
|
|
def get_url_name_args(self):
|
2013-05-11 00:59:07 +02:00
|
|
|
"""
|
|
|
|
Returns the arguments for the url name. Default is an empty list
|
|
|
|
or [self.object.pk] if this exist.
|
|
|
|
"""
|
|
|
|
if self.url_name_args is not None:
|
|
|
|
return self.url_name_args
|
2013-03-18 12:34:47 +01:00
|
|
|
try:
|
|
|
|
return [self.object.pk]
|
|
|
|
except AttributeError:
|
|
|
|
return []
|
2013-02-01 17:20:11 +01:00
|
|
|
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2013-01-26 16:19:53 +01:00
|
|
|
class FormView(PermissionMixin, ExtraContextMixin, UrlMixin, _FormView):
|
2012-03-16 14:31:59 +01:00
|
|
|
def form_invalid(self, form):
|
|
|
|
messages.error(self.request, _('Please check the form for errors.'))
|
|
|
|
return super(FormView, self).form_invalid(form)
|
|
|
|
|
|
|
|
|
2013-01-06 12:07:37 +01:00
|
|
|
class ModelFormMixin(object):
|
|
|
|
def form_valid(self, form):
|
|
|
|
self.object = form.save(commit=False)
|
|
|
|
self.manipulate_object(form)
|
|
|
|
self.object.save()
|
2013-01-26 15:25:54 +01:00
|
|
|
self.post_save(form)
|
2013-01-06 12:07:37 +01:00
|
|
|
return HttpResponseRedirect(self.get_success_url())
|
|
|
|
|
|
|
|
def manipulate_object(self, form):
|
|
|
|
pass
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2013-01-26 15:25:54 +01:00
|
|
|
def post_save(self, form):
|
|
|
|
form.save_m2m()
|
|
|
|
|
2012-03-16 14:31:59 +01:00
|
|
|
|
2013-01-26 16:19:53 +01:00
|
|
|
class UpdateView(PermissionMixin, UrlMixin, ExtraContextMixin,
|
2013-02-02 10:52:13 +01:00
|
|
|
ModelFormMixin, _UpdateView):
|
2013-09-07 22:57:29 +02:00
|
|
|
success_message = None
|
|
|
|
|
2012-04-27 21:40:42 +02:00
|
|
|
def form_invalid(self, form):
|
|
|
|
messages.error(self.request, _('Please check the form for errors.'))
|
|
|
|
return super(UpdateView, self).form_invalid(form)
|
|
|
|
|
2013-09-07 22:57:29 +02:00
|
|
|
def form_valid(self, form):
|
|
|
|
value = super(UpdateView, self).form_valid(form)
|
|
|
|
messages.success(self.request, self.get_success_message())
|
|
|
|
return value
|
|
|
|
|
2012-07-07 14:01:40 +02:00
|
|
|
def get_success_message(self):
|
2013-09-07 22:57:29 +02:00
|
|
|
if self.success_message is None:
|
|
|
|
message = _('%s was successfully modified.') % html_strong(self.object)
|
|
|
|
else:
|
|
|
|
message = self.success_message
|
|
|
|
return message
|
2012-07-07 14:01:40 +02:00
|
|
|
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2013-01-26 16:19:53 +01:00
|
|
|
class CreateView(PermissionMixin, UrlMixin, ExtraContextMixin,
|
2013-02-02 10:52:13 +01:00
|
|
|
ModelFormMixin, _CreateView):
|
2013-09-07 22:57:29 +02:00
|
|
|
success_message = None
|
|
|
|
|
2012-04-27 21:40:42 +02:00
|
|
|
def form_invalid(self, form):
|
|
|
|
messages.error(self.request, _('Please check the form for errors.'))
|
|
|
|
return super(CreateView, self).form_invalid(form)
|
|
|
|
|
2013-09-07 22:57:29 +02:00
|
|
|
def form_valid(self, form):
|
|
|
|
value = super(CreateView, self).form_valid(form)
|
|
|
|
messages.success(self.request, self.get_success_message())
|
|
|
|
return value
|
|
|
|
|
2012-07-07 14:01:40 +02:00
|
|
|
def get_success_message(self):
|
2013-09-07 22:57:29 +02:00
|
|
|
if self.success_message is None:
|
|
|
|
message = _('%s was successfully created.') % html_strong(self.object)
|
|
|
|
else:
|
|
|
|
message = self.success_message
|
|
|
|
return message
|
2012-07-07 14:01:40 +02:00
|
|
|
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2012-10-28 19:59:41 +01:00
|
|
|
class DeleteView(SingleObjectMixin, QuestionMixin, RedirectView):
|
2013-02-01 13:24:30 +01:00
|
|
|
question_url_name = None
|
|
|
|
success_url_name = None
|
|
|
|
|
2012-04-14 14:24:13 +02:00
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
self.object = self.get_object()
|
|
|
|
return super(DeleteView, self).get(request, *args, **kwargs)
|
|
|
|
|
2013-02-01 13:24:30 +01:00
|
|
|
def get_redirect_url(self, **kwargs):
|
2013-03-11 21:38:07 +01:00
|
|
|
if self.question_url_name is None and (self.request.method == 'GET' or
|
|
|
|
self.get_answer() == 'no'):
|
2013-02-03 13:23:55 +01:00
|
|
|
return self.object.get_absolute_url()
|
2013-02-01 13:24:30 +01:00
|
|
|
else:
|
2013-02-03 13:23:55 +01:00
|
|
|
return super(DeleteView, self).get_redirect_url(**kwargs)
|
2013-02-01 13:24:30 +01:00
|
|
|
|
2012-10-28 19:59:41 +01:00
|
|
|
def get_question(self):
|
|
|
|
return _('Do you really want to delete %s?') % html_strong(self.object)
|
|
|
|
|
|
|
|
def case_yes(self):
|
|
|
|
self.object.delete()
|
|
|
|
|
|
|
|
def get_success_message(self):
|
|
|
|
return _('%s was successfully deleted.') % html_strong(self.object)
|
2012-04-12 20:11:05 +02:00
|
|
|
|
2013-03-18 12:34:47 +01:00
|
|
|
def get_url_name_args(self):
|
|
|
|
return []
|
|
|
|
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2013-01-06 12:07:37 +01:00
|
|
|
class DetailView(PermissionMixin, ExtraContextMixin, _DetailView):
|
2012-04-15 09:55:21 +02:00
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
self.object = self.get_object()
|
2012-04-15 10:02:53 +02:00
|
|
|
return super(DetailView, self).get(request, *args, **kwargs)
|
|
|
|
|
2012-04-15 09:55:21 +02:00
|
|
|
|
2012-03-18 14:33:53 +01:00
|
|
|
class PDFView(PermissionMixin, View):
|
2012-04-14 18:13:55 +02:00
|
|
|
filename = _('undefined-filename')
|
2012-04-13 23:52:34 +02:00
|
|
|
top_space = 3
|
2012-04-14 18:13:55 +02:00
|
|
|
document_title = None
|
2012-04-13 23:52:34 +02:00
|
|
|
|
|
|
|
def get_top_space(self):
|
|
|
|
return self.top_space
|
2012-02-21 13:17:42 +01:00
|
|
|
|
2012-04-14 10:54:22 +02:00
|
|
|
def get_document_title(self):
|
2012-07-23 12:35:15 +02:00
|
|
|
if self.document_title:
|
|
|
|
return unicode(self.document_title)
|
|
|
|
else:
|
2012-07-23 22:59:31 +02:00
|
|
|
return ''
|
2012-04-14 10:54:22 +02:00
|
|
|
|
2012-04-29 18:54:42 +02:00
|
|
|
def get_filename(self):
|
2012-04-18 20:57:44 +02:00
|
|
|
return self.filename
|
|
|
|
|
2012-04-29 18:54:42 +02:00
|
|
|
def get_template(self, buffer):
|
|
|
|
return SimpleDocTemplate(buffer)
|
|
|
|
|
|
|
|
def build_document(self, pdf_document, story):
|
2012-11-24 14:01:21 +01:00
|
|
|
pdf_document.build(
|
|
|
|
story, onFirstPage=firstPage, onLaterPages=laterPages)
|
2012-04-29 18:54:42 +02:00
|
|
|
|
2012-02-21 13:17:42 +01:00
|
|
|
def render_to_response(self, filename):
|
|
|
|
response = HttpResponse(mimetype='application/pdf')
|
2012-04-18 18:54:48 +02:00
|
|
|
filename = u'filename=%s.pdf;' % self.get_filename()
|
2012-02-21 13:17:42 +01:00
|
|
|
response['Content-Disposition'] = filename.encode('utf-8')
|
|
|
|
|
|
|
|
buffer = StringIO()
|
2012-04-29 18:54:42 +02:00
|
|
|
pdf_document = self.get_template(buffer)
|
2012-04-14 10:54:22 +02:00
|
|
|
pdf_document.title = self.get_document_title()
|
2012-11-24 14:01:21 +01:00
|
|
|
story = [Spacer(1, self.get_top_space() * cm)]
|
2012-02-21 13:17:42 +01:00
|
|
|
|
|
|
|
self.append_to_pdf(story)
|
|
|
|
|
2012-04-29 18:54:42 +02:00
|
|
|
self.build_document(pdf_document, story)
|
2012-02-21 13:17:42 +01:00
|
|
|
|
|
|
|
pdf = buffer.getvalue()
|
|
|
|
buffer.close()
|
|
|
|
response.write(pdf)
|
|
|
|
return response
|
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
return self.render_to_response(self.get_filename())
|
|
|
|
|
2011-09-03 19:16:43 +02:00
|
|
|
|
|
|
|
def server_error(request, template_name='500.html'):
|
|
|
|
"""
|
|
|
|
500 error handler.
|
|
|
|
|
|
|
|
Templates: `500.html`
|
|
|
|
"""
|
2012-11-24 14:01:21 +01:00
|
|
|
return HttpResponseServerError(render_to_string(
|
|
|
|
template_name, context_instance=RequestContext(request)))
|
2012-03-18 17:11:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
@receiver(template_manipulation, dispatch_uid="send_register_tab")
|
|
|
|
def send_register_tab(sender, request, context, **kwargs):
|
2013-02-16 16:19:20 +01:00
|
|
|
"""
|
|
|
|
Receiver to the template_manipulation signal. Collects from the file
|
|
|
|
views.py in all apps the tabs setup by the function register_tab.
|
|
|
|
Inserts the tab objects and also the extra_stylefiles to the context.
|
|
|
|
"""
|
2012-03-18 17:11:58 +01:00
|
|
|
tabs = []
|
2013-03-01 17:13:12 +01:00
|
|
|
if 'extra_stylefiles' in context:
|
|
|
|
extra_stylefiles = context['extra_stylefiles']
|
|
|
|
else:
|
|
|
|
extra_stylefiles = []
|
2013-08-04 12:59:11 +02:00
|
|
|
# TODO: Do not go over the filesystem by any request
|
2012-03-18 17:11:58 +01:00
|
|
|
for app in settings.INSTALLED_APPS:
|
|
|
|
try:
|
|
|
|
mod = import_module(app + '.views')
|
2013-02-16 16:19:20 +01:00
|
|
|
tab = mod.register_tab(request)
|
|
|
|
tabs.append(tab)
|
|
|
|
if tab.stylefile:
|
|
|
|
extra_stylefiles.append(tab.stylefile)
|
2012-03-18 17:11:58 +01:00
|
|
|
except (ImportError, AttributeError):
|
|
|
|
continue
|
|
|
|
context.update({
|
|
|
|
'tabs': tabs,
|
2013-03-01 17:13:12 +01:00
|
|
|
'extra_stylefiles': extra_stylefiles})
|