generic views for the Agenda-App

This commit is contained in:
Oskar Hahn 2012-02-20 17:46:45 +01:00
parent 159e799a22
commit 8c52ecd669
5 changed files with 271 additions and 163 deletions

View File

@ -10,12 +10,7 @@
:license: GNU GPL, see LICENSE for more details. :license: GNU GPL, see LICENSE for more details.
""" """
from django.utils.translation import ugettext as _
from django.contrib import messages
from django.core.context_processors import csrf
from system import config from system import config
from projector.api import get_active_slide
def is_summary(): def is_summary():
@ -25,19 +20,3 @@ def is_summary():
if config['agenda_summary']: if config['agenda_summary']:
return True return True
return False return False
def gen_confirm_form_for_items(request, message, url, singleitem=None):
if singleitem:
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")))
else:
messages.warning(request, '%s<form action="%s" method="post"><input type="hidden" value="%s" name="csrfmiddlewaretoken"><input type="submit" value="%s" /> <input type="submit" name="all" value="%s" /> <input type="button" value="%s"></form>' % (message, url, csrf(request)['csrf_token'], _("Yes"), _("Yes, with all child items."), _("No")))
def del_confirm_form_for_items(request, object, name=None):
if name is None:
name = object
if object.children:
gen_confirm_form_for_items(request, _('Do you really want to delete <b>%s</b>?') % name, object.get_absolute_url('delete'), False)
else:
gen_confirm_form_for_items(request, _('Do you really want to delete <b>%s</b>?') % name, object.get_absolute_url('delete'), True)

View File

@ -18,7 +18,7 @@ from mptt.forms import TreeNodeChoiceField
from agenda.models import Item from agenda.models import Item
class ItemFormText(ModelForm): class ItemForm(ModelForm):
error_css_class = 'error' error_css_class = 'error'
required_css_class = 'required' required_css_class = 'required'

View File

@ -11,36 +11,60 @@
""" """
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
from agenda.views import Overview, View, SetActive, SetClosed, ItemUpdate, ItemCreate, ItemDelete
urlpatterns = patterns('agenda.views', urlpatterns = patterns('agenda.views',
url(r'^/$', 'overview', url(r'^$',
name='item_overview'), Overview.as_view(),
name='item_overview',
),
url(r'^(?P<item_id>\d+)/$', 'view', url(r'^(?P<item_id>\d+)/$',
name='item_view'), View.as_view(),
name='item_view',
),
url(r'^(?P<item_id>\d+)/activate/$', 'set_active', url(r'^(?P<item_id>\d+)/activate/$',
name='item_activate'), SetActive.as_view(),
{'summary': False},
name='item_activate',
),
url(r'^(?P<item_id>\d+)/activate/summary/$', 'set_active', url(r'^(?P<item_id>\d+)/activate/summary/$',
{'summary': True},\ SetActive.as_view(),
name='item_activate_summary'), {'summary': True},
name='item_activate_summary',
),
url(r'^(?P<item_id>\d+)/close/$', 'set_closed', {'closed': True}, url(r'^(?P<item_id>\d+)/close/$',
name='item_close'), SetClosed.as_view(),
{'closed': True},
name='item_close',
),
url(r'^(?P<item_id>\d+)/open/$', 'set_closed', {'closed': False}, url(r'^(?P<item_id>\d+)/open/$',
name='item_open'), SetClosed.as_view(),
{'closed': False},
name='item_open',
),
url(r'^(?P<item_id>\d+)/edit/$', 'edit', url(r'^(?P<pk>\d+)/edit/$',
name='item_edit'), ItemUpdate.as_view(),
name='item_edit',
),
url(r'^new/$', 'edit', url(r'^new/$',
name='item_new'), ItemCreate.as_view(),
name='item_new',
),
url(r'^(?P<item_id>\d+)/del/$', 'delete', url(r'^(?P<pk>\d+)/del/$',
name='item_delete'), ItemDelete.as_view(),
name='item_delete',
),
url(r'^print/$', 'print_agenda', url(r'^print/$',
name='print_agenda'), 'print_agenda',
name='print_agenda',
),
) )

View File

@ -9,44 +9,54 @@
:copyright: 2011 by the OpenSlides team, see AUTHORS. :copyright: 2011 by the OpenSlides team, see AUTHORS.
:license: GNU GPL, see LICENSE for more details. :license: GNU GPL, see LICENSE for more details.
""" """
from django.shortcuts import redirect
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.contrib import messages from django.contrib import messages
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.core.context_processors import csrf
from utils.pdf import print_agenda
from utils.views import TemplateView, RedirectView, UpdateView, CreateView, DeleteView
from system import config from system import config
from projector.api import get_active_slide, set_active_slide from projector.api import get_active_slide, set_active_slide
from agenda.models import Item from agenda.models import Item
from agenda.api import is_summary, del_confirm_form_for_items from agenda.api import is_summary
from agenda.forms import ItemOrderForm, ItemFormText from agenda.forms import ItemOrderForm, ItemForm
from utils.utils import template, permission_required, \
del_confirm_form, ajax_request
from utils.pdf import print_agenda
@permission_required('agenda.can_see_projector') class View(TemplateView):
@template('projector/AgendaText.html') permission_required = 'agenda.can_see_projector'
def view(request, item_id): template_name = 'projector/AgendaText.html'
"""
Shows the Slide. def get_context_data(self, **kwargs):
""" context = super(View, self).get_context_data(**kwargs)
item = Item.objects.get(pk=item_id) context.update({
return { 'item': Item.objects.get(pk=kwargs['item_id']),
'item': item,
'ajax': 'off', 'ajax': 'off',
} })
return context
@permission_required('agenda.can_see_agenda') class Overview(TemplateView):
@template('agenda/overview.html') permission_required = 'agenda.can_see_agenda'
def overview(request): template_name = 'agenda/overview.html'
"""
Shows an overview of all items. def get_context_data(self, **kwargs):
""" context = super(TemplateView, self).get_context_data(**kwargs)
if request.method == 'POST': context.update({
'items': Item.objects.all(),
'overview': get_active_slide(only_sid=True) == 'agenda_show',
'summary': is_summary(),
'countdown_visible': config['countdown_visible'],
'countdown_time': config['agenda_countdown_time'],
})
return context
def post(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
#todo: check for any erros in the forms befor saving the data
for item in Item.objects.all(): for item in Item.objects.all():
form = ItemOrderForm(request.POST, prefix="i%d" % item.id) form = ItemOrderForm(request.POST, prefix="i%d" % item.id)
if form.is_valid(): if form.is_valid():
@ -57,27 +67,28 @@ def overview(request):
item.parent = None item.parent = None
item.weight = form.cleaned_data['weight'] item.weight = form.cleaned_data['weight']
item.save() item.save()
return self.render_to_response(context)
items = Item.objects.all()
if get_active_slide(only_sid=True) == 'agenda_show':
overview = True
else:
overview = False
return {
'items': items,
'overview': overview,
'summary': is_summary(),
'countdown_visible': config['countdown_visible'],
'countdown_time': config['agenda_countdown_time'],
}
@permission_required('agenda.can_manage_agenda') class SetActive(RedirectView):
def set_active(request, item_id, summary=False):
""" """
Set an Item as the active one. Set an Item as the active one.
""" """
url = 'item_overview'
allow_ajax = True
permission_required = 'agenda.can_manage_agenda'
def get_ajax_context(self, **kwargs):
context = super(SetActive, self).get_ajax_context(**kwargs)
context.update({
'active': kwargs['item_id'],
'summary': is_summary(),
})
return context
def pre_redirect(self, request, *args, **kwargs):
item_id = kwargs['item_id']
summary = kwargs['summary']
if item_id == "0": if item_id == "0":
set_active_slide("agenda_show") set_active_slide("agenda_show")
else: else:
@ -88,93 +99,91 @@ def set_active(request, item_id, summary=False):
messages.error(request, _('Item ID %d does not exist.') % int(item_id)) messages.error(request, _('Item ID %d does not exist.') % int(item_id))
config["bigger"] = 100 config["bigger"] = 100
config["up"] = 0 config["up"] = 0
if request.is_ajax(): return super(SetActive, self).pre_redirect(request, *args, **kwargs)
return ajax_request({'active': item_id, 'summary': summary})
return redirect(reverse('item_overview'))
@permission_required('agenda.can_manage_agenda') class SetClosed(RedirectView):
def set_closed(request, item_id, closed=True):
""" """
Close or open an Item. Close or open an Item.
""" """
permission_required = 'agenda.can_manage_agenda'
allow_ajax = True
url = 'item_overview'
def get_ajax_context(self, **kwargs):
context = super(SetClosed, self).get_ajax_context(**kwargs)
closed = kwargs['closed']
if closed:
link = reverse('item_open', args=[self.item.id])
else:
link = reverse('item_close', args=[self.item.id])
context.update({
'closed': kwargs['closed'],
'link': link,
})
return context
def pre_redirect(self, request, *args, **kwargs):
item_id = kwargs['item_id']
closed = kwargs['closed']
try: try:
item = Item.objects.get(pk=item_id) item = Item.objects.get(pk=item_id)
item.set_closed(closed) item.set_closed(closed)
except Item.DoesNotExist: except Item.DoesNotExist:
messages.error(request, _('Item ID %d does not exist.') % int(item_id)) messages.error(request, _('Item ID %d does not exist.') % int(item_id))
self.item = item
if request.is_ajax(): return super(SetClosed, self).pre_redirect(request, *args, **kwargs)
if closed:
link = reverse('item_open', args=[item.id])
else:
link = reverse('item_close', args=[item.id])
return ajax_request({'closed': closed,
'link': link})
return redirect(reverse('item_overview'))
@permission_required('agenda.can_manage_agenda') class ItemUpdate(UpdateView):
@template('agenda/edit.html') permission_required = 'agenda.can_manage_agenda'
def edit(request, item_id=None): template_name = 'agenda/edit.html'
""" model = Item
Show a form to edit an existing Item, or create a new one. context_object_name = 'item'
""" form_class = ItemForm
if item_id is not None: success_url = 'item_overview'
try:
item = Item.objects.get(pk=item_id)
except Item.DoesNotExist:
messages.error(request, _('Item ID %d does not exist.') % int(item_id))
return redirect(reverse('item_overview'))
else:
item = None
if request.method == 'POST':
form = ItemFormText(request.POST, instance=item)
if form.is_valid():
item = form.save()
if item_id is None:
messages.success(request, _('New item was successfully created.'))
else:
messages.success(request, _('Item was successfully modified.'))
if not 'apply' in request.POST:
return redirect(reverse('item_overview'))
if item_id is None:
return redirect(reverse('item_edit', args=[item.id]))
else:
messages.error(request, _('Please check the form for errors.'))
else:
form = ItemFormText(instance=item)
return {
'form': form,
'item': item,
}
@permission_required('agenda.can_manage_agenda') class ItemCreate(CreateView):
def delete(request, item_id): permission_required = 'agenda.can_manage_agenda'
template_name = 'agenda/edit.html'
model = Item
context_object_name = 'item'
form_class = ItemForm
success_url = 'item_overview'
class ItemDelete(DeleteView):
""" """
Delete an Item. Delete an Item.
""" """
try: permission_required = 'agenda.can_manage_agenda'
item = Item.objects.get(pk=item_id) model = Item
except Item.DoesNotExist: url = 'item_overview'
messages.error(request, _('Item ID %d does not exist.') % int(item_id))
return redirect(reverse('item_overview')) def pre_post_redirect(self, request, *args, **kwargs):
self.object = self.get_object()
if request.method == 'POST':
if 'all' in request.POST: if 'all' in request.POST:
item.delete() self.object.delete()
messages.success(request, _("Item <b>%s</b> and his children were successfully deleted.") % item) messages.success(request, _("Item <b>%s</b> and his children were successfully deleted.") % self.object)
else: else:
for child in item.children: for child in self.object.children:
child.parent = item.parent child.parent = self.object.parent
child.save() child.save()
item.delete() self.object.delete()
messages.success(request, _("Item <b>%s</b> was successfully deleted.") % item) messages.success(request, _("Item <b>%s</b> was successfully deleted.") % self.object)
def gen_confirm_form(self, request, message, url, singleitem=None):
if singleitem:
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")))
else: else:
del_confirm_form_for_items(request, item) messages.warning(request, '%s<form action="%s" method="post"><input type="hidden" value="%s" name="csrfmiddlewaretoken"><input type="submit" value="%s" /> <input type="submit" name="all" value="%s" /> <input type="button" value="%s"></form>' % (message, url, csrf(request)['csrf_token'], _("Yes"), _("Yes, with all child items."), _("No")))
return redirect(reverse('item_overview'))
def confirm_form(self, request, object, name=None):
if name is None:
name = object
if object.children:
self.gen_confirm_form(request, _('Do you really want to delete <b>%s</b>?') % name, object.get_absolute_url('delete'), False)
else:
self.gen_confirm_form(request, _('Do you really want to delete <b>%s</b>?') % name, object.get_absolute_url('delete'), True)

View File

@ -1,7 +1,103 @@
try:
import json
except ImportError:
import simplejson as json
from django.conf import settings from django.conf import settings
from django.http import HttpResponseServerError from django.http import HttpResponseServerError, HttpResponse
from django.template import Context, loader, RequestContext from django.core.urlresolvers import reverse
from django.template import loader, RequestContext
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import (TemplateView as _TemplateView,
RedirectView as _RedirectView,
UpdateView as _UpdateView,
CreateView as _CreateView,)
from django.views.generic.detail import SingleObjectMixin
from utils import render_to_forbitten
FREE_TO_GO = 'free to go'
class LoginMixin(object):
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(LoginMixin, self).dispatch(request, *args, **kwargs)
class PermissionMixin(object):
permission_required = FREE_TO_GO
def dispatch(self, request, *args, **kwargs):
if self.permission_required == FREE_TO_GO:
has_permission = True
else:
has_permission = request.user.has_perm(self.permission_required)
if has_permission:
if request.user.is_authenticated():
path = urlquote(request.get_full_path())
return HttpResponseRedirect("%s?next=%s" % (settings.LOGIN_URL, path))
else:
return render_to_forbitten(request)
return super(LoginMixin, self).dispatch(request, *args, **kwargs)
class TemplateView(_TemplateView, PermissionMixin):
pass
class RedirectView(_RedirectView, PermissionMixin):
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)
elif request.method == 'POST':
self.pre_post_redirect(request, *args, **kwargs)
if self.request.is_ajax() and self.allow_ajax:
return HttpResponse(json.dumps(self.get_ajax_context(**kwargs)))
return super(RedirectView, self).get(request, *args, **kwargs)
def get_redirect_url(self, **kwargs):
return reverse(super(RedirectView, self).get_redirect_url(**kwargs))
def get_ajax_context(self, **kwargs):
return {}
class UpdateView(_UpdateView, PermissionMixin):
def get_success_url(self):
if 'apply' in self.request.POST:
return ''
return reverse(super(UpdateView, self).get_success_url())
class CreateView(_CreateView, PermissionMixin):
def get_success_url(self):
if 'apply' in self.request.POST:
return reverse('item_edit', args=[self.object.id])
return reverse(super(CreateView, self).get_success_url())
class DeleteView(RedirectView, SingleObjectMixin):
def pre_redirect(self, request, *args, **kwargs):
self.object = self.get_object()
self.confirm_form(request, self.object)
def pre_post_redirect(self, request, *args, **kwargs):
pass
def server_error(request, template_name='500.html'): def server_error(request, template_name='500.html'):
""" """