OpenSlides/openslides/utils/views.py

170 lines
4.9 KiB
Python
Raw Normal View History

from io import BytesIO
2013-09-25 12:53:44 +02:00
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, HttpResponseRedirect
from django.utils.translation import ugettext_lazy
2013-09-25 12:53:44 +02:00
from django.views import generic as django_views
from django.views.decorators.csrf import ensure_csrf_cookie
2013-09-25 12:53:44 +02:00
from reportlab.lib.units import cm
from reportlab.platypus import SimpleDocTemplate, Spacer
from rest_framework.response import Response
from rest_framework.views import APIView as _APIView
2012-02-20 17:46:45 +01:00
2013-09-25 12:53:44 +02:00
from .pdf import firstPage, laterPages
2012-04-15 11:24:40 +02:00
2013-09-25 12:53:44 +02:00
View = django_views.View
2012-04-13 11:35:53 +02:00
class PermissionMixin:
2013-09-25 12:53:44 +02:00
"""
Mixin for views, that only can be visited from users with special
permissions.
2013-09-25 12:53:44 +02:00
Set the attribute 'required_permission' to the required permission
string or override the method 'check_permission'.
2013-09-25 12:53:44 +02:00
"""
required_permission = None
2012-02-20 17:46:45 +01:00
def check_permission(self, request, *args, **kwargs):
2013-09-25 12:53:44 +02:00
"""
Checks if the user has the required permission.
"""
if self.required_permission is None:
2012-04-15 11:24:40 +02:00
return True
2012-02-20 17:46:45 +01:00
else:
return request.user.has_perm(self.required_permission)
2012-02-20 17:46:45 +01:00
2012-04-15 11:24:40 +02:00
def dispatch(self, request, *args, **kwargs):
2013-09-25 12:53:44 +02:00
"""
Check if the user has the permission.
If the user is not logged in, redirect the user to the login page.
"""
if not self.check_permission(request, *args, **kwargs):
2012-03-18 14:33:53 +01:00
if not request.user.is_authenticated():
path = request.get_full_path()
return HttpResponseRedirect(
"%s?next=%s" % (settings.LOGIN_URL, path))
2012-02-20 17:46:45 +01:00
else:
2013-09-25 12:53:44 +02:00
raise PermissionDenied
return super().dispatch(request, *args, **kwargs)
2012-02-20 17:46:45 +01:00
class SingleObjectMixin(django_views.detail.SingleObjectMixin):
"""
Mixin for single objects from the database.
"""
def dispatch(self, *args, **kwargs):
if not hasattr(self, 'object'):
# Save the object not only in the cache but in the public
# attribute self.object because Django expects this later.
# Because get_object() has an internal cache this line is not a
# performance problem.
self.object = self.get_object()
return super().dispatch(*args, **kwargs)
def get_object(self, *args, **kwargs):
"""
Returns the single object from database or cache.
"""
try:
obj = self._object
except AttributeError:
obj = super().get_object(*args, **kwargs)
self._object = obj
return obj
class CSRFMixin:
"""
Adds the csrf cookie to the response.
"""
@classmethod
def as_view(cls, *args, **kwargs):
view = super().as_view(*args, **kwargs)
return ensure_csrf_cookie(view)
2012-03-18 14:33:53 +01:00
class PDFView(PermissionMixin, View):
2013-09-25 12:53:44 +02:00
"""
View to generate an PDF.
"""
2014-10-12 11:11:54 +02:00
filename = ugettext_lazy('undefined-filename')
top_space = 3
2012-04-14 18:13:55 +02:00
document_title = None
def get_top_space(self):
return self.top_space
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 str(self.document_title)
2012-07-23 12:35:15 +02:00
else:
2012-07-23 22:59:31 +02:00
return ''
2012-04-14 10:54:22 +02:00
def get_filename(self):
2012-04-18 20:57:44 +02:00
return self.filename
def get_template(self, buffer):
return SimpleDocTemplate(buffer)
def build_document(self, pdf_document, story):
pdf_document.build(
story, onFirstPage=firstPage, onLaterPages=laterPages)
def render_to_response(self, filename):
response = HttpResponse(content_type='application/pdf')
filename = 'filename=%s.pdf;' % self.get_filename()
response['Content-Disposition'] = filename.encode('utf-8')
buffer = BytesIO()
pdf_document = self.get_template(buffer)
2012-04-14 10:54:22 +02:00
pdf_document.title = self.get_document_title()
story = [Spacer(1, self.get_top_space() * cm)]
self.append_to_pdf(story)
self.build_document(pdf_document, story)
pdf = buffer.getvalue()
buffer.close()
response.write(pdf)
return response
def get(self, request, *args, **kwargs):
return self.render_to_response(self.get_filename())
class APIView(_APIView):
"""
The Django Rest framework APIView with improvements for OpenSlides.
"""
http_method_names = []
"""
The allowed actions have to be explicitly defined.
Django allowes the following:
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
"""
def get_context_data(self, **context):
"""
Returns the context for the response.
"""
return context
def method_call(self, request, *args, **kwargs):
"""
Http method that returns the response object with the context data.
"""
return Response(self.get_context_data())
# Add the http-methods and delete the method "method_call"
get = post = put = patch = delete = head = options = trace = method_call
del method_call