2014-08-16 09:25:18 +02:00
|
|
|
from io import BytesIO
|
2012-02-21 13:17:42 +01:00
|
|
|
|
2015-06-16 10:37:23 +02:00
|
|
|
from django.core.exceptions import PermissionDenied
|
2015-07-01 23:18:48 +02:00
|
|
|
from django.http import HttpResponse
|
2015-02-17 20:07:44 +01:00
|
|
|
from django.utils.translation import ugettext_lazy
|
2013-09-25 12:53:44 +02:00
|
|
|
from django.views import generic as django_views
|
2015-02-17 20:07:44 +01:00
|
|
|
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
|
2015-02-12 22:42:54 +01:00
|
|
|
from rest_framework.response import Response
|
2015-02-17 20:07:44 +01:00
|
|
|
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
|
|
|
|
|
|
|
|
2014-12-22 18:09:05 +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()
|
2015-01-02 22:03:34 +01:00
|
|
|
return super().dispatch(*args, **kwargs)
|
2014-12-22 18:09:05 +01:00
|
|
|
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
|
|
"""
|
|
|
|
Returns the single object from database or cache.
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
obj = self._object
|
|
|
|
except AttributeError:
|
2015-01-02 22:03:34 +01:00
|
|
|
obj = super().get_object(*args, **kwargs)
|
2014-12-22 18:09:05 +01:00
|
|
|
self._object = obj
|
|
|
|
return obj
|
|
|
|
|
|
|
|
|
2015-02-17 20:07:44 +01:00
|
|
|
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)
|
|
|
|
|
|
|
|
|
2015-07-01 23:18:48 +02:00
|
|
|
class PDFView(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')
|
2012-04-13 23:52:34 +02:00
|
|
|
top_space = 3
|
2012-04-14 18:13:55 +02:00
|
|
|
document_title = None
|
2015-07-01 23:18:48 +02:00
|
|
|
required_permission = None
|
|
|
|
|
|
|
|
def check_permission(self, request, *args, **kwargs):
|
|
|
|
"""
|
|
|
|
Checks if the user has the required permission.
|
|
|
|
"""
|
|
|
|
if self.required_permission is None:
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return request.user.has_perm(self.required_permission)
|
|
|
|
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
"""
|
|
|
|
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):
|
|
|
|
raise PermissionDenied
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
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:
|
2014-08-16 09:25:18 +02:00
|
|
|
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
|
|
|
|
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):
|
2014-05-17 13:42:18 +02:00
|
|
|
response = HttpResponse(content_type='application/pdf')
|
2014-08-16 09:25:18 +02:00
|
|
|
filename = 'filename=%s.pdf;' % self.get_filename()
|
2012-02-21 13:17:42 +01:00
|
|
|
response['Content-Disposition'] = filename.encode('utf-8')
|
|
|
|
|
2014-08-16 09:25:18 +02:00
|
|
|
buffer = BytesIO()
|
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())
|
2014-03-27 20:30:15 +01:00
|
|
|
|
|
|
|
|
2015-02-12 22:42:54 +01:00
|
|
|
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
|