OpenSlides/openslides/utils/views.py

338 lines
11 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
openslides.utils.views
~~~~~~~~~~~~~~~~~~~~~~
2012-04-25 22:29:19 +02:00
Views for OpenSlides.
2012-04-25 22:29:19 +02:00
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
:license: GNU GPL, see LICENSE for more details.
"""
2012-02-20 17:46:45 +01:00
try:
import json
except ImportError:
# for python 2.5 support
2012-02-20 17:46:45 +01:00
import simplejson as json
try:
from cStringIO import StringIO
except ImportError:
# Is this exception realy necessary?
from StringIO import StringIO
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Frame, PageBreak,
Spacer, Table, LongTable, TableStyle, Image)
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
from django.core.context_processors import csrf
from django.core.urlresolvers import reverse
from django.conf import settings
2012-03-18 17:11:58 +01:00
from django.dispatch import receiver
from django.http import HttpResponseServerError, HttpResponse, HttpResponseRedirect
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
2012-04-15 11:24:40 +02:00
from django.utils.importlib import import_module
from django.template import loader, RequestContext
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,
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
from openslides.config.models import config
from openslides.utils.utils import render_to_forbitten
from openslides.utils.signals import template_manipulation
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):
response = TemplateResponseMixin.render_to_response(self, context, **response_kwargs)
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-04-15 11:24:40 +02:00
def has_permission(self, request):
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):
if not self.has_permission(request):
2012-03-18 14:33:53 +01:00
if not request.user.is_authenticated():
path = request.get_full_path()
2012-02-20 17:46:45 +01:00
return HttpResponseRedirect("%s?next=%s" % (settings.LOGIN_URL, path))
else:
return render_to_forbitten(request)
2012-03-18 14:33:53 +01:00
return _View.dispatch(self, request, *args, **kwargs)
2012-02-20 17:46:45 +01: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)))
2012-03-18 14:33:53 +01:00
class TemplateView(PermissionMixin, _TemplateView):
def get_context_data(self, **kwargs):
context = super(TemplateView, self).get_context_data(**kwargs)
template_manipulation.send(sender=self.__class__, request=self.request, context=context)
return context
2012-02-20 17:46:45 +01:00
2012-04-13 11:35:53 +02:00
class ListView(PermissionMixin, SetCookieMixin, _ListView):
2012-04-11 10:58:59 +02:00
def get_context_data(self, **kwargs):
context = super(ListView, self).get_context_data(**kwargs)
template_manipulation.send(sender=self.__class__, request=self.request, context=context)
2012-04-11 10:58:59 +02:00
return context
class AjaxView(PermissionMixin, AjaxMixin, View):
2012-04-12 14:20:05 +02:00
def get(self, request, *args, **kwargs):
return self.ajax_get(request, *args, **kwargs)
2012-04-12 14:20:05 +02:00
class RedirectView(PermissionMixin, AjaxMixin, _RedirectView):
2012-02-20 17:46:45 +01:00
permanent = False
allow_ajax = False
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':
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:
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):
return reverse(super(RedirectView, self).get_redirect_url(**kwargs))
2012-03-18 14:33:53 +01:00
class FormView(PermissionMixin, _FormView):
2012-03-16 14:31:59 +01:00
def get_success_url(self):
if not self.success_url:
return ''
return reverse(super(FormView, self).get_success_url())
def get_context_data(self, **kwargs):
context = super(FormView, self).get_context_data(**kwargs)
template_manipulation.send(sender=self.__class__, request=self.request, context=context)
2012-03-16 14:31:59 +01:00
return context
def form_invalid(self, form):
messages.error(self.request, _('Please check the form for errors.'))
return super(FormView, self).form_invalid(form)
2012-03-18 14:33:53 +01:00
class UpdateView(PermissionMixin, _UpdateView):
2012-02-20 17:46:45 +01:00
def get_success_url(self):
if 'apply' in self.request.POST:
return ''
return reverse(super(UpdateView, self).get_success_url())
2012-03-16 14:31:59 +01:00
def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs)
template_manipulation.send(sender=self.__class__, request=self.request, context=context)
2012-03-16 14:31:59 +01:00
return context
def form_invalid(self, form):
messages.error(self.request, _('Please check the form for errors.'))
return super(UpdateView, self).form_invalid(form)
2012-02-20 17:46:45 +01:00
2012-03-18 14:33:53 +01:00
class CreateView(PermissionMixin, _CreateView):
2012-02-20 17:46:45 +01:00
def get_success_url(self):
if 'apply' in self.request.POST:
2012-04-11 10:58:59 +02:00
return reverse(self.get_apply_url(), args=[self.object.id])
2012-02-20 17:46:45 +01:00
return reverse(super(CreateView, self).get_success_url())
2012-03-18 17:11:58 +01:00
def get_context_data(self, **kwargs):
context = super(CreateView, self).get_context_data(**kwargs)
template_manipulation.send(sender=self.__class__, request=self.request, context=context)
2012-03-18 17:11:58 +01:00
return context
2012-04-11 10:58:59 +02:00
def get_apply_url(self):
#todo: Versuche apply url automatisch anhand on self.object herauszufindne
return self.apply_url
def form_invalid(self, form):
messages.error(self.request, _('Please check the form for errors.'))
return super(CreateView, self).form_invalid(form)
2012-02-20 17:46:45 +01:00
class DeleteView(RedirectView, SingleObjectMixin):
def pre_redirect(self, request, *args, **kwargs):
self.confirm_form(request, self.object)
2012-04-12 20:11:05 +02:00
def pre_post_redirect(self, request, *args, **kwargs):
self.object.delete()
messages.success(request, _("Item <b>%s</b> was successfully deleted.") % self.object)
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(DeleteView, self).get(request, *args, **kwargs)
2012-04-12 20:11:05 +02:00
def confirm_form(self, request, object, name=None):
if name is None:
name = object
self.gen_confirm_form(request, _('Do you really want to delete <b>%s</b>?') % name, object.get_absolute_url('delete'))
def gen_confirm_form(self, request, message, url):
messages.warning(request, '%s<form action="%s" method="post"><input type="hidden" value="%s" name="csrfmiddlewaretoken"><input type="submit" value="%s" /> <input type="button" value="%s"></form>' % (message, url, csrf(request)['csrf_token'], _("Yes"), _("No")))
2012-02-20 17:46:45 +01:00
2012-04-15 10:02:53 +02:00
class DetailView(TemplateView, SingleObjectMixin):
2012-04-15 09:55:21 +02:00
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
2012-04-15 10:02:53 +02:00
return super(DetailView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(DetailView, self).get_context_data(**kwargs)
context.update(SingleObjectMixin.get_context_data(self, **kwargs))
return context
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')
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):
return self.document_title
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(mimetype='application/pdf')
2012-04-18 18:54:48 +02:00
filename = u'filename=%s.pdf;' % self.get_filename()
response['Content-Disposition'] = filename.encode('utf-8')
buffer = StringIO()
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 append_to_pdf(self, story):
pass
def get_filename(self):
return self.filename
def get(self, request, *args, **kwargs):
return self.render_to_response(self.get_filename())
2011-09-03 19:16:43 +02:00
2012-04-15 11:24:40 +02:00
class FrontPage(TemplateView):
template_name = 'front_page.html'
def has_permission(self, request):
if request.user.is_authenticated() or config['system_enable_anonymous']:
return True
return False
def get_context_data(self, **kwargs):
context = super(FrontPage, self).get_context_data(**kwargs)
apps = []
for app in settings.INSTALLED_APPS:
try:
mod = import_module(app + '.views')
tab = mod.register_tab(self.request)
except (ImportError, AttributeError):
continue
2012-04-15 12:52:59 +02:00
if tab.permission:
2012-04-15 11:24:40 +02:00
apps.append(tab)
2012-04-18 15:04:16 +02:00
if config['show_help_text']:
messages.info(self.request, config['help_text'])
2012-04-15 13:26:01 +02:00
context.update({
'apps': apps,
'title': config['frontpage_title'],
'welcometext': config['frontpage_welcometext'],
})
2012-04-15 11:24:40 +02:00
return context
2011-09-03 19:16:43 +02:00
def server_error(request, template_name='500.html'):
"""
500 error handler.
Templates: `500.html`
Context:
MEDIA_URL
Path of static media (e.g. "media.example.org")
"""
t = loader.get_template("500.html") # You need to create a 500.html template.
return HttpResponseServerError(render_to_string('500.html', 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):
tabs = []
for app in settings.INSTALLED_APPS:
try:
mod = import_module(app + '.views')
tabs.append(mod.register_tab(request))
except (ImportError, AttributeError):
continue
context.update({
'tabs': tabs,
})