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.
"""
from django.utils.translation import ugettext as _
from django.contrib import messages
from django.core.context_processors import csrf
from system import config
from projector.api import get_active_slide
def is_summary():
@ -25,19 +20,3 @@ def is_summary():
if config['agenda_summary']:
return True
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
class ItemFormText(ModelForm):
class ItemForm(ModelForm):
error_css_class = 'error'
required_css_class = 'required'

View File

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

View File

@ -9,44 +9,54 @@
:copyright: 2011 by the OpenSlides team, see AUTHORS.
:license: GNU GPL, see LICENSE for more details.
"""
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from django.contrib import messages
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 projector.api import get_active_slide, set_active_slide
from agenda.models import Item
from agenda.api import is_summary, del_confirm_form_for_items
from agenda.forms import ItemOrderForm, ItemFormText
from utils.utils import template, permission_required, \
del_confirm_form, ajax_request
from utils.pdf import print_agenda
from agenda.api import is_summary
from agenda.forms import ItemOrderForm, ItemForm
@permission_required('agenda.can_see_projector')
@template('projector/AgendaText.html')
def view(request, item_id):
"""
Shows the Slide.
"""
item = Item.objects.get(pk=item_id)
return {
'item': item,
class View(TemplateView):
permission_required = 'agenda.can_see_projector'
template_name = 'projector/AgendaText.html'
def get_context_data(self, **kwargs):
context = super(View, self).get_context_data(**kwargs)
context.update({
'item': Item.objects.get(pk=kwargs['item_id']),
'ajax': 'off',
}
})
return context
@permission_required('agenda.can_see_agenda')
@template('agenda/overview.html')
def overview(request):
"""
Shows an overview of all items.
"""
if request.method == 'POST':
class Overview(TemplateView):
permission_required = 'agenda.can_see_agenda'
template_name = 'agenda/overview.html'
def get_context_data(self, **kwargs):
context = super(TemplateView, self).get_context_data(**kwargs)
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():
form = ItemOrderForm(request.POST, prefix="i%d" % item.id)
if form.is_valid():
@ -57,27 +67,28 @@ def overview(request):
item.parent = None
item.weight = form.cleaned_data['weight']
item.save()
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'],
}
return self.render_to_response(context)
@permission_required('agenda.can_manage_agenda')
def set_active(request, item_id, summary=False):
class SetActive(RedirectView):
"""
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":
set_active_slide("agenda_show")
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))
config["bigger"] = 100
config["up"] = 0
if request.is_ajax():
return ajax_request({'active': item_id, 'summary': summary})
return redirect(reverse('item_overview'))
return super(SetActive, self).pre_redirect(request, *args, **kwargs)
@permission_required('agenda.can_manage_agenda')
def set_closed(request, item_id, closed=True):
class SetClosed(RedirectView):
"""
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:
item = Item.objects.get(pk=item_id)
item.set_closed(closed)
except Item.DoesNotExist:
messages.error(request, _('Item ID %d does not exist.') % int(item_id))
if request.is_ajax():
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'))
self.item = item
return super(SetClosed, self).pre_redirect(request, *args, **kwargs)
@permission_required('agenda.can_manage_agenda')
@template('agenda/edit.html')
def edit(request, item_id=None):
"""
Show a form to edit an existing Item, or create a new one.
"""
if item_id is not None:
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,
}
class ItemUpdate(UpdateView):
permission_required = 'agenda.can_manage_agenda'
template_name = 'agenda/edit.html'
model = Item
context_object_name = 'item'
form_class = ItemForm
success_url = 'item_overview'
@permission_required('agenda.can_manage_agenda')
def delete(request, item_id):
class ItemCreate(CreateView):
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.
"""
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'))
permission_required = 'agenda.can_manage_agenda'
model = Item
url = 'item_overview'
def pre_post_redirect(self, request, *args, **kwargs):
self.object = self.get_object()
if request.method == 'POST':
if 'all' in request.POST:
item.delete()
messages.success(request, _("Item <b>%s</b> and his children were successfully deleted.") % item)
self.object.delete()
messages.success(request, _("Item <b>%s</b> and his children were successfully deleted.") % self.object)
else:
for child in item.children:
child.parent = item.parent
for child in self.object.children:
child.parent = self.object.parent
child.save()
item.delete()
messages.success(request, _("Item <b>%s</b> was successfully deleted.") % item)
self.object.delete()
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:
del_confirm_form_for_items(request, item)
return redirect(reverse('item_overview'))
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 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.http import HttpResponseServerError
from django.template import Context, loader, RequestContext
from django.http import HttpResponseServerError, HttpResponse
from django.core.urlresolvers import reverse
from django.template import loader, RequestContext
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'):
"""