2011-07-31 10:46:29 +02:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
openslides . application . views
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Views for the application app .
2012-04-25 22:29:19 +02:00
: copyright : 2011 , 2012 by OpenSlides team , see AUTHORS .
2011-07-31 10:46:29 +02:00
: license : GNU GPL , see LICENSE for more details .
"""
2012-07-08 09:21:39 +02:00
# for python 2.5 support
2011-11-14 16:37:12 +01:00
from __future__ import with_statement
2011-07-31 10:46:29 +02:00
2011-11-09 22:53:10 +01:00
import csv
2012-04-13 23:52:34 +02:00
import os
2011-11-24 19:38:25 +01:00
2012-04-18 19:57:39 +02:00
try :
from urlparse import parse_qs
except ImportError : # python <= 2.5
from cgi import parse_qs
2012-06-11 13:43:48 +02:00
from reportlab . lib import colors
from reportlab . lib . units import cm
2012-07-08 09:21:39 +02:00
from reportlab . platypus import ( SimpleDocTemplate , PageBreak , Paragraph , Spacer ,
Table , TableStyle )
2012-06-11 13:43:48 +02:00
2012-07-08 09:21:39 +02:00
from django . conf import settings
2011-07-31 10:46:29 +02:00
from django . contrib import messages
from django . contrib . auth . decorators import login_required
2011-11-09 22:53:10 +01:00
from django . contrib . auth . models import User , Group
2012-04-27 21:22:44 +02:00
from django . core . context_processors import csrf
2012-07-08 09:21:39 +02:00
from django . core . urlresolvers import reverse
2011-11-09 22:53:10 +01:00
from django . db import transaction
2012-07-08 09:21:39 +02:00
from django . shortcuts import redirect
2012-07-10 01:33:03 +02:00
from django . utils . translation import ugettext_lazy as _ , ungettext
2012-06-11 13:43:48 +02:00
2012-07-08 09:21:39 +02:00
from openslides . utils import csv_ext
2012-07-01 15:35:05 +02:00
from openslides . utils . pdf import stylesheet
2012-07-08 09:21:39 +02:00
from openslides . utils . template import Tab
from openslides . utils . utils import ( template , permission_required ,
del_confirm_form , gen_confirm_form )
2012-07-01 15:35:05 +02:00
from openslides . utils . views import PDFView , RedirectView , DeleteView , FormView
2012-06-11 13:43:48 +02:00
2012-07-08 09:21:39 +02:00
from openslides . config . models import config
2012-07-01 15:35:05 +02:00
from openslides . projector . projector import Widget
2012-06-11 13:43:48 +02:00
2012-07-01 15:35:05 +02:00
from openslides . poll . views import PollFormView
2012-06-11 13:43:48 +02:00
2012-07-01 15:35:05 +02:00
from openslides . participant . api import gen_username , gen_password
2012-07-08 09:21:39 +02:00
from openslides . participant . models import Profile
2012-02-15 12:04:11 +01:00
2012-07-01 15:35:05 +02:00
from openslides . agenda . models import Item
2012-02-15 12:04:11 +01:00
2012-07-01 15:35:05 +02:00
from openslides . application . models import Application , AVersion , ApplicationPoll
2012-07-08 09:21:39 +02:00
from openslides . application . forms import ( ApplicationForm ,
ApplicationFormTrivialChanges , ApplicationManagerForm ,
ApplicationManagerFormSupporter , ApplicationImportForm , ConfigForm )
2012-02-15 12:04:11 +01:00
2012-04-15 13:10:24 +02:00
2011-09-04 12:21:58 +02:00
@permission_required ( ' application.can_see_application ' )
2011-07-31 10:46:29 +02:00
@template ( ' application/overview.html ' )
def overview ( request ) :
"""
View all applications
"""
try :
2012-04-18 19:57:39 +02:00
sortfilter = parse_qs ( request . COOKIES [ ' votecollector_sortfilter ' ] )
for value in sortfilter :
sortfilter [ value ] = sortfilter [ value ] [ 0 ]
2011-07-31 10:46:29 +02:00
except KeyError :
2012-04-18 19:57:39 +02:00
sortfilter = { }
for value in [ u ' sort ' , u ' reverse ' , u ' number ' , u ' status ' , u ' needsup ' , u ' statusvalue ' ] :
if value in request . REQUEST :
if request . REQUEST [ value ] == ' 0 ' :
try :
del sortfilter [ value ]
except KeyError :
pass
else :
sortfilter [ value ] = request . REQUEST [ value ]
query = Application . objects . all ( )
if ' number ' in sortfilter :
query = query . filter ( number = None )
if ' status ' in sortfilter :
if ' statusvalue ' in sortfilter and ' on ' in sortfilter [ ' status ' ] :
query = query . filter ( status__iexact = sortfilter [ ' statusvalue ' ] )
if ' sort ' in sortfilter :
if sortfilter [ ' sort ' ] == ' title ' :
sort = ' aversion__title '
elif sortfilter [ ' sort ' ] == ' time ' :
sort = ' aversion__time '
else :
sort = sortfilter [ ' sort ' ]
query = query . order_by ( sort )
2012-04-28 08:45:11 +02:00
if sort . startswith ( ' aversion_ ' ) :
# limit result to last version of an application
query = query . filter ( aversion__id__in = [ x . last_version . id for x in Application . objects . all ( ) ] )
2012-04-18 19:57:39 +02:00
if ' reverse ' in sortfilter :
2011-07-31 10:46:29 +02:00
query = query . reverse ( )
2012-04-18 19:57:39 +02:00
# todo: rewrite this with a .filter()
if ' needsup ' in sortfilter :
2011-07-31 10:46:29 +02:00
applications = [ ]
for application in query . all ( ) :
if not application . enough_supporters :
applications . append ( application )
else :
2012-04-18 19:57:39 +02:00
applications = query
2012-04-27 22:46:27 +02:00
if type ( applications ) is not list :
applications = list ( query . all ( ) )
# not the most efficient way to do this but 'get_allowed_actions'
# is not callable from within djangos templates..
for ( i , application ) in enumerate ( applications ) :
try :
2012-06-03 10:19:08 +02:00
applications [ i ] = {
2012-04-27 22:46:27 +02:00
' actions ' : application . get_allowed_actions ( request . user ) ,
' application ' : application
}
except :
# todo: except what?
2012-06-03 10:19:08 +02:00
applications [ i ] = {
2012-04-27 22:46:27 +02:00
' actions ' : [ ] ,
' application ' : application
}
2011-07-31 10:46:29 +02:00
return {
' applications ' : applications ,
2012-02-15 12:04:11 +01:00
' min_supporters ' : int ( config [ ' application_min_supporters ' ] ) ,
2011-07-31 10:46:29 +02:00
}
2011-09-04 12:21:58 +02:00
@permission_required ( ' application.can_see_application ' )
2011-07-31 10:46:29 +02:00
@template ( ' application/view.html ' )
2011-09-06 10:41:06 +02:00
def view ( request , application_id , newest = False ) :
2011-07-31 10:46:29 +02:00
"""
View one application .
"""
application = Application . objects . get ( pk = application_id )
2011-09-06 10:41:06 +02:00
if newest :
version = application . last_version
else :
version = application . public_version
2011-07-31 10:46:29 +02:00
revisions = application . versions
actions = application . get_allowed_actions ( user = request . user )
2011-11-01 06:47:10 +01:00
2011-07-31 10:46:29 +02:00
return {
' application ' : application ,
' revisions ' : revisions ,
' actions ' : actions ,
2012-02-15 12:04:11 +01:00
' min_supporters ' : int ( config [ ' application_min_supporters ' ] ) ,
2011-09-06 22:22:29 +02:00
' version ' : version ,
2012-02-14 16:31:21 +01:00
#'results': application.results
2011-07-31 10:46:29 +02:00
}
@login_required
@template ( ' application/edit.html ' )
def edit ( request , application_id = None ) :
"""
View a form to edit or create a application .
"""
if request . user . has_perm ( ' application.can_manage_application ' ) :
is_manager = True
else :
is_manager = False
if not is_manager \
2011-09-04 12:21:58 +02:00
and not request . user . has_perm ( ' application.can_create_application ' ) :
messages . error ( request , _ ( " You have not the necessary rights to create or edit applications. " ) )
2011-07-31 10:46:29 +02:00
return redirect ( reverse ( ' application_overview ' ) )
if application_id is not None :
application = Application . objects . get ( id = application_id )
if not request . user == application . submitter and not is_manager :
messages . error ( request , _ ( " You can not edit this application. You are not the submitter. " ) )
return redirect ( reverse ( ' application_view ' , args = [ application . id ] ) )
2012-04-20 22:13:47 +02:00
actions = application . get_allowed_actions ( user = request . user )
2011-07-31 10:46:29 +02:00
else :
application = None
2012-04-20 22:13:47 +02:00
actions = None
2011-07-31 10:46:29 +02:00
2012-06-30 11:31:35 +02:00
formclass = ApplicationFormTrivialChanges \
2012-07-08 09:21:39 +02:00
if config [ ' application_allow_trivial_change ' ] and application_id \
else ApplicationForm
2012-06-30 11:31:35 +02:00
2012-06-30 11:50:46 +02:00
managerformclass = ApplicationManagerFormSupporter \
if config [ ' application_min_supporters ' ] \
else ApplicationManagerForm
2011-07-31 10:46:29 +02:00
if request . method == ' POST ' :
2012-06-30 11:31:35 +02:00
dataform = formclass ( request . POST , prefix = " data " )
2011-07-31 10:46:29 +02:00
valid = dataform . is_valid ( )
if is_manager :
2012-06-30 11:50:46 +02:00
managerform = managerformclass ( request . POST ,
2012-06-30 11:31:35 +02:00
instance = application ,
2011-07-31 10:46:29 +02:00
prefix = " manager " )
valid = valid and managerform . is_valid ( )
else :
managerform = None
if valid :
del_supporters = True
2011-09-08 17:39:57 +02:00
original_supporters = [ ]
2011-07-31 10:46:29 +02:00
if is_manager :
2012-07-01 17:20:02 +02:00
if application : # Edit application
2011-09-08 17:39:57 +02:00
for s in application . supporter . all ( ) :
original_supporters . append ( s )
2012-07-01 17:20:02 +02:00
application = managerform . save ( commit = False )
2011-07-31 10:46:29 +02:00
elif application_id is None :
application = Application ( submitter = request . user )
application . title = dataform . cleaned_data [ ' title ' ]
application . text = dataform . cleaned_data [ ' text ' ]
application . reason = dataform . cleaned_data [ ' reason ' ]
2012-06-30 14:50:14 +02:00
try :
trivial_change = config [ ' application_allow_trivial_change ' ] \
and dataform . cleaned_data [ ' trivial_change ' ]
except KeyError :
trivial_change = False
2012-06-30 11:31:35 +02:00
application . save ( request . user , trivial_change = trivial_change )
2011-09-08 17:39:57 +02:00
if is_manager :
# log added supporters
supporters_added = [ ]
for s in application . supporter . all ( ) :
if s not in original_supporters :
try :
supporters_added . append ( unicode ( s . profile ) )
except Profile . DoesNotExist :
pass
if len ( supporters_added ) > 0 :
2011-09-11 22:43:15 +02:00
log_added = " , " . join ( supporters_added )
2011-09-08 17:39:57 +02:00
application . writelog ( _ ( " Supporter: + %s " ) % log_added , request . user )
# log removed supporters
supporters_removed = [ ]
for s in original_supporters :
if s not in application . supporter . all ( ) :
try :
supporters_removed . append ( unicode ( s . profile ) )
except Profile . DoesNotExist :
pass
if len ( supporters_removed ) > 0 :
2011-09-21 21:01:27 +02:00
log_removed = " , " . join ( supporters_removed )
2011-09-08 17:39:57 +02:00
application . writelog ( _ ( " Supporter: - %s " ) % log_removed , request . user )
2011-07-31 10:46:29 +02:00
if application_id is None :
messages . success ( request , _ ( ' New application was successfully created. ' ) )
else :
messages . success ( request , _ ( ' Application was successfully modified. ' ) )
2011-09-04 10:02:54 +02:00
2011-09-03 19:25:05 +02:00
if not ' apply ' in request . POST :
return redirect ( reverse ( ' application_view ' , args = [ application . id ] ) )
if application_id is None :
return redirect ( reverse ( ' application_edit ' , args = [ application . id ] ) )
2011-11-24 19:42:32 +01:00
else :
messages . error ( request , _ ( ' Please check the form for errors. ' ) )
2011-07-31 10:46:29 +02:00
else :
if application_id is None :
2012-02-15 12:04:11 +01:00
initial = { ' text ' : config [ ' application_preamble ' ] }
2011-07-31 10:46:29 +02:00
else :
2012-06-30 11:50:46 +02:00
if application . status == " pub " and application . supporter . exists ( ) :
2011-09-07 22:17:19 +02:00
if request . user . has_perm ( ' application.can_manage_application ' ) :
messages . warning ( request , _ ( " Attention: Do you really want to edit this application? The supporters will <b>not</b> be removed automatically because you can manage applications. Please check if the supports are valid after your changing! " ) )
2011-07-31 10:46:29 +02:00
else :
messages . warning ( request , _ ( " Attention: Do you really want to edit this application? All <b> %s </b> supporters will be removed! Try to convince the supporters again. " ) % application . supporter . count ( ) )
initial = { ' title ' : application . title ,
' text ' : application . text ,
' reason ' : application . reason }
2012-06-30 11:31:35 +02:00
dataform = formclass ( initial = initial , prefix = " data " )
2011-07-31 10:46:29 +02:00
if is_manager :
if application_id is None :
initial = { ' submitter ' : str ( request . user . id ) }
else :
initial = { }
2012-06-30 11:50:46 +02:00
managerform = managerformclass ( initial = initial , \
2011-07-31 10:46:29 +02:00
instance = application , \
prefix = " manager " )
else :
managerform = None
return {
' form ' : dataform ,
' managerform ' : managerform ,
' application ' : application ,
2012-04-20 22:13:47 +02:00
' actions ' : actions ,
2011-07-31 10:46:29 +02:00
}
2012-06-30 14:50:14 +02:00
2011-07-31 10:46:29 +02:00
@permission_required ( ' application.can_manage_application ' )
@template ( ' application/view.html ' )
def set_number ( request , application_id ) :
"""
set a number for an application .
"""
try :
Application . objects . get ( pk = application_id ) . set_number ( user = request . user )
messages . success ( request , _ ( " Application number was successfully set. " ) )
except Application . DoesNotExist :
pass
except NameError :
pass
return redirect ( reverse ( ' application_view ' , args = [ application_id ] ) )
@permission_required ( ' application.can_manage_application ' )
@template ( ' application/view.html ' )
def permit ( request , application_id ) :
"""
permit an application .
"""
try :
Application . objects . get ( pk = application_id ) . permit ( user = request . user )
messages . success ( request , _ ( " Application was successfully permitted. " ) )
except Application . DoesNotExist :
pass
return redirect ( reverse ( ' application_view ' , args = [ application_id ] ) )
@permission_required ( ' application.can_manage_application ' )
@template ( ' application/view.html ' )
def notpermit ( request , application_id ) :
"""
reject ( not permit ) an application .
"""
try :
Application . objects . get ( pk = application_id ) . notpermit ( user = request . user )
messages . success ( request , _ ( " Application was successfully rejected. " ) )
except Application . DoesNotExist :
pass
return redirect ( reverse ( ' application_view ' , args = [ application_id ] ) )
@template ( ' application/view.html ' )
def set_status ( request , application_id = None , status = None ) :
"""
set a status of an application .
"""
try :
if status is not None :
application = Application . objects . get ( pk = application_id )
application . set_status ( user = request . user , status = status )
messages . success ( request , _ ( " Application status was set to: <b> %s </b>. " ) % application . get_status_display ( ) )
except Application . DoesNotExist :
pass
return redirect ( reverse ( ' application_view ' , args = [ application_id ] ) )
@permission_required ( ' application.can_manage_application ' )
@template ( ' application/view.html ' )
def reset ( request , application_id ) :
"""
reset an application .
"""
try :
Application . objects . get ( pk = application_id ) . reset ( user = request . user )
messages . success ( request , _ ( " Application status was reset. " ) )
except Application . DoesNotExist :
pass
return redirect ( reverse ( ' application_view ' , args = [ application_id ] ) )
@permission_required ( ' application.can_support_application ' )
@template ( ' application/view.html ' )
def support ( request , application_id ) :
"""
support an application .
"""
try :
Application . objects . get ( pk = application_id ) . support ( user = request . user )
messages . success ( request , _ ( " You have support the application successfully. " ) )
except Application . DoesNotExist :
pass
return redirect ( reverse ( ' application_view ' , args = [ application_id ] ) )
@permission_required ( ' application.can_support_application ' )
@template ( ' application/view.html ' )
def unsupport ( request , application_id ) :
"""
unsupport an application .
"""
try :
Application . objects . get ( pk = application_id ) . unsupport ( user = request . user )
messages . success ( request , _ ( " You have unsupport the application successfully. " ) )
except Application . DoesNotExist :
pass
return redirect ( reverse ( ' application_view ' , args = [ application_id ] ) )
@permission_required ( ' application.can_manage_application ' )
@template ( ' application/view.html ' )
def gen_poll ( request , application_id ) :
"""
gen a poll for this application .
"""
try :
2011-09-03 16:20:10 +02:00
poll = Application . objects . get ( pk = application_id ) . gen_poll ( user = request . user )
messages . success ( request , _ ( " New vote was successfully created. " ) )
2011-07-31 10:46:29 +02:00
except Application . DoesNotExist :
2012-02-14 16:31:21 +01:00
pass # TODO: do not call poll after this excaption
2011-09-03 16:20:10 +02:00
return redirect ( reverse ( ' application_poll_view ' , args = [ poll . id ] ) )
2011-07-31 10:46:29 +02:00
@permission_required ( ' application.can_manage_application ' )
def delete_poll ( request , poll_id ) :
"""
delete a poll from this application
"""
2012-02-15 13:44:55 +01:00
poll = ApplicationPoll . objects . get ( pk = poll_id )
2011-07-31 10:46:29 +02:00
application = poll . application
2012-02-15 13:44:55 +01:00
count = application . polls . filter ( id__lte = poll_id ) . count ( )
2011-07-31 10:46:29 +02:00
if request . method == ' POST ' :
poll . delete ( )
2012-05-20 23:12:50 +02:00
application . writelog ( _ ( " Poll deleted " ) , request . user )
2011-07-31 10:46:29 +02:00
messages . success ( request , _ ( ' Poll was successfully deleted. ' ) )
else :
2012-02-15 13:44:55 +01:00
del_confirm_form ( request , poll , name = _ ( " the %s . poll " ) % count , delete_link = reverse ( ' application_poll_delete ' , args = [ poll_id ] ) )
2011-07-31 10:46:29 +02:00
return redirect ( reverse ( ' application_view ' , args = [ application . id ] ) )
2012-06-09 19:39:52 +02:00
2012-04-27 21:22:44 +02:00
class ApplicationDelete ( DeleteView ) :
"""
Delete one or more Applications .
"""
permission_required = ' application.can_manage_application '
model = Application
url = ' application_overview '
def get_object ( self ) :
self . applications = [ ]
if self . kwargs . get ( ' application_id ' , None ) :
try :
return Application . objects . get ( id = int ( self . kwargs [ ' application_id ' ] ) )
except Application . DoesNotExist :
return None
if self . kwargs . get ( ' application_ids ' , [ ] ) :
for appid in self . kwargs [ ' application_ids ' ] :
try :
self . applications . append ( Application . objects . get ( id = int ( appid ) ) )
except Application . DoesNotExist :
pass
if self . applications :
return self . applications [ 0 ]
return None
def pre_post_redirect ( self , request , * args , * * kwargs ) :
self . object = self . get_object ( )
if len ( self . applications ) :
for application in self . applications :
if not ' delete ' in application . get_allowed_actions ( user = request . user ) :
messages . error ( request , _ ( " You can not delete application <b> %s </b>. " ) % application )
continue
title = application . title
application . delete ( force = True )
messages . success ( request , _ ( " Application <b> %s </b> was successfully deleted. " ) % title )
elif self . object :
if not ' delete ' in self . object . get_allowed_actions ( user = request . user ) :
messages . error ( request , _ ( " You can not delete application <b> %s </b>. " ) % self . object )
else :
title = self . object . title
self . object . delete ( force = True )
messages . success ( request , _ ( " Application <b> %s </b> was successfully deleted. " ) % title )
else :
messages . error ( request , _ ( " Invalid request " ) )
def gen_confirm_form ( self , request , message , url ) :
formbase = ' %s <form action= " %s " method= " post " ><input type= " hidden " value= " %s " name= " csrfmiddlewaretoken " > ' % ( message , url , csrf ( request ) [ ' csrf_token ' ] )
2012-06-03 10:19:08 +02:00
2012-04-27 21:22:44 +02:00
if len ( self . applications ) :
for application in self . applications :
formbase + = ' <input type= " hidden " name= " application_ids " value= " %s " > ' % application . id
elif self . object :
formbase + = ' <input type= " hidden " name= " application_id " value= " %s " > ' % self . object . id
2012-04-30 08:50:35 +02:00
formbase + = ' <input type= " submit " value= " %s " /> <input type= " button " value= " %s " ></form> ' % ( _ ( " Yes " ) , _ ( " No " ) )
2012-04-27 21:22:44 +02:00
messages . warning ( request , formbase )
def confirm_form ( self , request , object , item = None ) :
self . object = self . get_object ( )
if len ( self . applications ) :
self . gen_confirm_form ( request , _ ( ' Do you really want to delete multiple applications? ' ) % self . object . get_absolute_url ( ' delete ' ) )
else :
self . gen_confirm_form ( request , _ ( ' Do you really want to delete <b> %s </b>? ' ) % self . object , self . object . get_absolute_url ( ' delete ' ) )
2011-07-31 10:46:29 +02:00
2012-02-14 16:31:21 +01:00
class ViewPoll ( PollFormView ) :
2012-04-18 19:30:32 +02:00
permission_required = ' application.can_manage_application '
2012-02-14 16:31:21 +01:00
poll_class = ApplicationPoll
template_name = ' application/poll_view.html '
def get_context_data ( self , * * kwargs ) :
2012-02-19 17:31:17 +01:00
context = super ( ViewPoll , self ) . get_context_data ( * * kwargs )
2012-02-15 12:36:50 +01:00
self . application = self . poll . get_application ( )
2012-02-14 16:31:21 +01:00
context [ ' application ' ] = self . application
2012-04-18 19:30:32 +02:00
context [ ' ballot ' ] = self . poll . get_ballot ( )
2012-04-20 22:13:47 +02:00
context [ ' actions ' ] = self . application . get_allowed_actions ( user = self . request . user )
2012-02-14 16:31:21 +01:00
return context
2012-05-20 23:12:50 +02:00
def get_modelform_class ( self ) :
cls = super ( ViewPoll , self ) . get_modelform_class ( )
user = self . request . user
class ViewPollFormClass ( cls ) :
def save ( self , commit = True ) :
instance = super ( ViewPollFormClass , self ) . save ( commit )
application = instance . application
application . writelog ( _ ( " Poll was updated " ) , user )
return instance
return ViewPollFormClass
2012-02-14 16:31:21 +01:00
def get_success_url ( self ) :
if not ' apply ' in self . request . POST :
2012-02-19 17:31:17 +01:00
return reverse ( ' application_view ' , args = [ self . poll . application . id ] )
2012-02-14 16:31:21 +01:00
return ' '
2011-09-03 18:11:42 +02:00
@permission_required ( ' application.can_manage_application ' )
def permit_version ( request , aversion_id ) :
aversion = AVersion . objects . get ( pk = aversion_id )
application = aversion . application
2011-09-04 10:43:25 +02:00
if request . method == ' POST ' :
2012-05-19 12:46:54 +02:00
application . accept_version ( aversion , user = request . user )
2011-09-04 10:43:25 +02:00
messages . success ( request , _ ( " Version <b> %s </b> accepted. " ) % ( aversion . aid ) )
else :
gen_confirm_form ( request , _ ( ' Do you really want to permit version <b> %s </b>? ' ) % aversion . aid , reverse ( ' application_version_permit ' , args = [ aversion . id ] ) )
2011-09-03 18:11:42 +02:00
return redirect ( reverse ( ' application_view ' , args = [ application . id ] ) )
@permission_required ( ' application.can_manage_application ' )
def reject_version ( request , aversion_id ) :
aversion = AVersion . objects . get ( pk = aversion_id )
2011-09-06 10:41:06 +02:00
application = aversion . application
2011-09-04 19:07:45 +02:00
if request . method == ' POST ' :
2012-05-19 12:46:54 +02:00
if application . reject_version ( aversion , user = request . user ) :
2011-09-04 19:07:45 +02:00
messages . success ( request , _ ( " Version <b> %s </b> rejected. " ) % ( aversion . aid ) )
else :
messages . error ( request , _ ( " ERROR by rejecting the version. " ) )
2011-09-03 18:11:42 +02:00
else :
2011-09-04 19:07:45 +02:00
gen_confirm_form ( request , _ ( ' Do you really want to reject version <b> %s </b>? ' ) % aversion . aid , reverse ( ' application_version_reject ' , args = [ aversion . id ] ) )
2011-09-03 18:11:42 +02:00
return redirect ( reverse ( ' application_view ' , args = [ application . id ] ) )
2012-02-15 12:04:11 +01:00
2012-04-13 23:52:34 +02:00
@permission_required ( ' application.can_manage_application ' )
2011-11-09 22:53:10 +01:00
@template ( ' application/import.html ' )
def application_import ( request ) :
try :
request . user . profile
messages . error ( request , _ ( ' The import function is available for the superuser (without user profile) only. ' ) )
return redirect ( reverse ( ' application_overview ' ) )
except Profile . DoesNotExist :
pass
2011-11-14 16:37:12 +01:00
except AttributeError :
# AnonymousUser
pass
2011-11-09 22:53:10 +01:00
if request . method == ' POST ' :
form = ApplicationImportForm ( request . POST , request . FILES )
if form . is_valid ( ) :
2012-04-13 21:55:13 +02:00
import_permitted = form . cleaned_data [ ' import_permitted ' ]
2011-11-09 22:53:10 +01:00
try :
2012-04-13 22:33:47 +02:00
# check for valid encoding (will raise UnicodeDecodeError if not)
request . FILES [ ' csvfile ' ] . read ( ) . decode ( ' utf-8 ' )
request . FILES [ ' csvfile ' ] . seek ( 0 )
2012-04-14 12:52:56 +02:00
2011-11-09 22:53:10 +01:00
users_generated = 0
applications_generated = 0
applications_modified = 0
with transaction . commit_on_success ( ) :
2011-11-22 18:49:36 +01:00
dialect = csv . Sniffer ( ) . sniff ( request . FILES [ ' csvfile ' ] . readline ( ) )
2011-11-24 19:38:25 +01:00
dialect = utils . csv_ext . patchup ( dialect )
2011-11-22 18:49:36 +01:00
request . FILES [ ' csvfile ' ] . seek ( 0 )
for ( lno , line ) in enumerate ( csv . reader ( request . FILES [ ' csvfile ' ] , dialect = dialect ) ) :
2011-11-09 22:53:10 +01:00
# basic input verification
if lno < 1 :
continue
try :
( number , title , text , reason , first_name , last_name ) = line [ : 6 ]
except ValueError :
messages . error ( request , _ ( ' Ignoring malformed line %d in import file. ' ) % ( lno + 1 ) )
continue
2012-04-15 12:11:03 +02:00
form = ApplicationForm ( { ' title ' : title , ' text ' : text , ' reason ' : reason } )
2011-11-09 22:53:10 +01:00
if not form . is_valid ( ) :
messages . error ( request , _ ( ' Ignoring malformed line %d in import file. ' ) % ( lno + 1 ) )
continue
if number :
try :
number = abs ( long ( number ) )
if number < 1 :
messages . error ( request , _ ( ' Ignoring malformed line %d in import file. ' ) % ( lno + 1 ) )
continue
except ValueError :
messages . error ( request , _ ( ' Ignoring malformed line %d in import file. ' ) % ( lno + 1 ) )
continue
# fetch existing users or create new users as needed
try :
user = User . objects . get ( first_name = first_name , last_name = last_name )
except User . DoesNotExist :
user = None
if user is None :
user = User ( )
user . last_name = last_name
user . first_name = first_name
user . username = gen_username ( first_name , last_name )
user . save ( )
profile = Profile ( )
profile . user = user
profile . group = ' '
profile . committee = ' '
profile . gender = ' none '
profile . type = ' guest '
2011-11-14 21:54:42 +01:00
profile . firstpassword = gen_password ( )
profile . user . set_password ( profile . firstpassword )
2011-11-09 22:53:10 +01:00
profile . save ( )
users_generated + = 1
# create / modify the application
application = None
if number :
try :
application = Application . objects . get ( number = number )
applications_modified + = 1
except Application . DoesNotExist :
application = None
if application is None :
application = Application ( submitter = user )
if number :
application . number = number
applications_generated + = 1
application . title = form . cleaned_data [ ' title ' ]
application . text = form . cleaned_data [ ' text ' ]
application . reason = form . cleaned_data [ ' reason ' ]
2012-04-13 21:55:13 +02:00
if import_permitted :
application . status = ' per '
2011-11-09 22:53:10 +01:00
application . save ( user , trivial_change = True )
if applications_generated :
messages . success ( request , ungettext ( ' %d application was successfully imported. ' ,
' %d applications were successfully imported. ' , applications_generated ) % applications_generated )
if applications_modified :
messages . success ( request , ungettext ( ' %d application was successfully modified. ' ,
' %d applications were successfully modified. ' , applications_modified ) % applications_modified )
if users_generated :
messages . success ( request , ungettext ( ' %d new user was added. ' , ' %d new users were added. ' , users_generated ) % users_generated )
return redirect ( reverse ( ' application_overview ' ) )
except csv . Error :
message . error ( request , _ ( ' Import aborted because of severe errors in the input file. ' ) )
2012-04-13 22:33:47 +02:00
except UnicodeDecodeError :
messages . error ( request , _ ( ' Import file has wrong character encoding, only UTF-8 is supported! ' ) )
2011-11-09 22:53:10 +01:00
else :
messages . error ( request , _ ( ' Please check the form for errors. ' ) )
else :
messages . warning ( request , _ ( " Attention: Existing applications will be modified if you import new applications with the same number. " ) )
messages . warning ( request , _ ( " Attention: Importing an application without a number multiple times will create duplicates. " ) )
form = ApplicationImportForm ( )
return {
' form ' : form ,
}
2012-04-19 12:46:04 +02:00
class CreateAgendaItem ( RedirectView ) :
permission_required = ' agenda.can_manage_agenda '
def pre_redirect ( self , request , * args , * * kwargs ) :
self . application = Application . objects . get ( pk = kwargs [ ' application_id ' ] )
2012-07-04 11:00:58 +02:00
self . item = Item ( related_sid = self . application . sid )
2012-04-19 12:46:04 +02:00
self . item . save ( )
def get_redirect_url ( self , * * kwargs ) :
2012-06-03 10:19:08 +02:00
return reverse ( ' item_overview ' )
2012-04-19 12:46:04 +02:00
2012-04-13 23:52:34 +02:00
class ApplicationPDF ( PDFView ) :
2012-05-14 22:00:22 +02:00
permission_required = ' application.can_see_application '
2012-04-13 23:52:34 +02:00
top_space = 0
2012-04-18 18:54:48 +02:00
def get_filename ( self ) :
application_id = self . kwargs [ ' application_id ' ]
if application_id is None :
filename = _ ( " Applications " )
else :
application = Application . objects . get ( id = application_id )
if application . number :
number = application . number
else :
number = " "
filename = u ' %s %s ' % ( _ ( " Application " ) , str ( number ) )
return filename
2012-04-15 12:11:03 +02:00
2012-04-18 18:54:48 +02:00
def append_to_pdf ( self , story ) :
application_id = self . kwargs [ ' application_id ' ]
2012-04-13 23:52:34 +02:00
if application_id is None : #print all applications
title = config [ " application_pdf_title " ]
story . append ( Paragraph ( title , stylesheet [ ' Heading1 ' ] ) )
preamble = config [ " application_pdf_preamble " ]
if preamble :
story . append ( Paragraph ( " %s " % preamble . replace ( ' \r \n ' , ' <br/> ' ) , stylesheet [ ' Paragraph ' ] ) )
story . append ( Spacer ( 0 , 0.75 * cm ) )
2012-06-30 12:04:58 +02:00
applications = Application . objects . order_by ( ' number ' )
if not applications : # No applications existing
story . append ( Paragraph ( _ ( " No applications available. " ) , stylesheet [ ' Heading3 ' ] ) )
2012-06-29 11:42:28 +02:00
else : # Print all Applications
# List of applications
2012-06-30 12:04:58 +02:00
for application in applications :
2012-06-29 11:42:28 +02:00
if application . number :
story . append ( Paragraph ( _ ( " Application No. " ) + " %s : %s " % ( application . number , application . title ) , stylesheet [ ' Heading3 ' ] ) )
else :
story . append ( Paragraph ( _ ( " Application No. " ) + " : %s " % ( application . title ) , stylesheet [ ' Heading3 ' ] ) )
# Applications details (each application on single page)
2012-06-30 12:04:58 +02:00
for application in applications :
2012-06-29 11:42:28 +02:00
story . append ( PageBreak ( ) )
story = self . get_application ( application , story )
2012-04-13 23:52:34 +02:00
else : # print selected application
application = Application . objects . get ( id = application_id )
story = self . get_application ( application , story )
def get_application ( self , application , story ) :
# application number
if application . number :
story . append ( Paragraph ( _ ( " Application No. " ) + " %s " % application . number , stylesheet [ ' Heading1 ' ] ) )
else :
story . append ( Paragraph ( _ ( " Application No. " ) , stylesheet [ ' Heading1 ' ] ) )
# submitter
cell1a = [ ]
cell1a . append ( Spacer ( 0 , 0.2 * cm ) )
cell1a . append ( Paragraph ( " <font name= ' Ubuntu-Bold ' > %s :</font> " % _ ( " Submitter " ) , stylesheet [ ' Heading4 ' ] ) )
cell1b = [ ]
cell1b . append ( Spacer ( 0 , 0.2 * cm ) )
if application . status == " pub " :
cell1b . append ( Paragraph ( " __________________________________________ " , stylesheet [ ' Signaturefield ' ] ) )
cell1b . append ( Spacer ( 0 , 0.1 * cm ) )
cell1b . append ( Paragraph ( " " + unicode ( application . submitter . profile ) , stylesheet [ ' Small ' ] ) )
cell1b . append ( Spacer ( 0 , 0.2 * cm ) )
else :
cell1b . append ( Paragraph ( unicode ( application . submitter . profile ) , stylesheet [ ' Normal ' ] ) )
# supporters
cell2a = [ ]
cell2b = [ ]
2012-06-30 11:57:07 +02:00
if config [ ' application_min_supporters ' ] :
cell2a . append ( Paragraph ( " <font name= ' Ubuntu-Bold ' > %s :</font><seqreset id= ' counter ' > " % _ ( " Supporters " ) , stylesheet [ ' Heading4 ' ] ) )
for s in application . supporter . all ( ) :
cell2b . append ( Paragraph ( " <seq id= ' counter ' />. %s " % unicode ( s . profile ) , stylesheet [ ' Signaturefield ' ] ) )
if application . status == " pub " :
for x in range ( 0 , application . missing_supporters ) :
cell2b . append ( Paragraph ( " <seq id= ' counter ' />. __________________________________________ " , stylesheet [ ' Signaturefield ' ] ) )
cell2b . append ( Spacer ( 0 , 0.2 * cm ) )
2012-04-13 23:52:34 +02:00
# status
note = " "
for n in application . notes :
note + = " %s " % unicode ( n )
cell3a = [ ]
cell3a . append ( Paragraph ( " <font name= ' Ubuntu-Bold ' > %s :</font> " % _ ( " Status " ) , stylesheet [ ' Heading4 ' ] ) )
cell3b = [ ]
if note != " " :
if application . status == " pub " :
cell3b . append ( Paragraph ( note , stylesheet [ ' Normal ' ] ) )
else :
cell3b . append ( Paragraph ( " %s | %s " % ( application . get_status_display ( ) , note ) , stylesheet [ ' Normal ' ] ) )
else :
cell3b . append ( Paragraph ( " %s " % application . get_status_display ( ) , stylesheet [ ' Normal ' ] ) )
# table
data = [ ]
data . append ( [ cell1a , cell1b ] )
data . append ( [ cell2a , cell2b ] )
data . append ( [ cell3a , cell3b ] )
2012-06-29 11:22:47 +02:00
# Version number (aid)
if application . public_version . aid > 1 :
cell4a = [ ]
cell4a . append ( Paragraph ( " <font name= ' Ubuntu-Bold ' > %s :</font> " % _ ( " Version " ) , stylesheet [ ' Heading4 ' ] ) )
cell4b = [ ]
cell4b . append ( Paragraph ( " %s " % application . public_version . aid , stylesheet [ ' Normal ' ] ) )
data . append ( [ cell4a , cell4b ] )
2012-06-30 11:57:07 +02:00
2012-04-15 12:11:03 +02:00
poll_results = application . get_poll_results ( )
2012-06-29 11:22:47 +02:00
2012-04-13 23:52:34 +02:00
# voting results
2012-04-15 12:11:03 +02:00
if poll_results :
2012-06-29 11:22:47 +02:00
cell5a = [ ]
cell5a . append ( Paragraph ( " <font name= ' Ubuntu-Bold ' > %s :</font> " % _ ( " Vote results " ) , stylesheet [ ' Heading4 ' ] ) )
cell5b = [ ]
2012-04-13 23:52:34 +02:00
ballotcounter = 0
2012-04-15 12:11:03 +02:00
for result in poll_results :
2012-04-13 23:52:34 +02:00
ballotcounter + = 1
2012-04-15 12:11:03 +02:00
if len ( poll_results ) > 1 :
2012-06-29 11:22:47 +02:00
cell5b . append ( Paragraph ( " %s . %s " % ( ballotcounter , _ ( " Vote " ) ) , stylesheet [ ' Bold ' ] ) )
cell5b . append ( Paragraph ( " %s : %s <br/> %s : %s <br/> %s : %s <br/> %s : %s <br/> %s : %s " % ( _ ( " Yes " ) , result [ 0 ] , _ ( " No " ) , result [ 1 ] , _ ( " Abstention " ) , result [ 2 ] , _ ( " Invalid " ) , result [ 3 ] , _ ( " Votes cast " ) , result [ 4 ] ) , stylesheet [ ' Normal ' ] ) )
cell5b . append ( Spacer ( 0 , 0.2 * cm ) )
data . append ( [ cell5a , cell5b ] )
2012-04-13 23:52:34 +02:00
t = Table ( data )
t . _argW [ 0 ] = 4.5 * cm
t . _argW [ 1 ] = 11 * cm
t . setStyle ( TableStyle ( [ ( ' BOX ' , ( 0 , 0 ) , ( - 1 , - 1 ) , 1 , colors . black ) ,
( ' VALIGN ' , ( 0 , 0 ) , ( - 1 , - 1 ) , ' TOP ' ) ,
] ) )
story . append ( t )
story . append ( Spacer ( 0 , 1 * cm ) )
# title
2012-06-29 11:22:47 +02:00
story . append ( Paragraph ( application . public_version . title , stylesheet [ ' Heading3 ' ] ) )
2012-04-13 23:52:34 +02:00
# text
2012-06-29 11:22:47 +02:00
story . append ( Paragraph ( " %s " % application . public_version . text . replace ( ' \r \n ' , ' <br/> ' ) , stylesheet [ ' Paragraph ' ] ) )
2012-04-13 23:52:34 +02:00
# reason
2012-07-06 15:30:14 +02:00
if application . public_version . reason :
story . append ( Paragraph ( _ ( " Reason " ) + " : " , stylesheet [ ' Heading3 ' ] ) )
story . append ( Paragraph ( " %s " % application . public_version . reason . replace ( ' \r \n ' , ' <br/> ' ) , stylesheet [ ' Paragraph ' ] ) )
2012-04-13 23:52:34 +02:00
return story
class ApplicationPollPDF ( PDFView ) :
permission_required = ' application.can_manage_application '
top_space = 0
def get ( self , request , * args , * * kwargs ) :
self . poll = ApplicationPoll . objects . get ( id = self . kwargs [ ' poll_id ' ] )
return super ( ApplicationPollPDF , self ) . get ( request , * args , * * kwargs )
def get_filename ( self ) :
2012-04-18 19:30:32 +02:00
filename = u ' %s %s _ %s ' % ( _ ( " Application " ) , str ( self . poll . application . number ) , _ ( " Poll " ) )
2012-04-13 23:52:34 +02:00
return filename
2012-04-29 18:54:42 +02:00
def get_template ( self , buffer ) :
return SimpleDocTemplate ( buffer , topMargin = - 6 , bottomMargin = - 6 , leftMargin = 0 , rightMargin = 0 , showBoundary = False )
def build_document ( self , pdf_document , story ) :
pdf_document . build ( story )
2012-04-13 23:52:34 +02:00
def append_to_pdf ( self , story ) :
2012-07-01 15:35:05 +02:00
imgpath = os . path . join ( settings . SITE_ROOT , ' static/images/circle.png ' )
2012-04-13 23:52:34 +02:00
circle = " <img src= ' %s ' width= ' 15 ' height= ' 15 ' /> " % imgpath
cell = [ ]
cell . append ( Spacer ( 0 , 0.8 * cm ) )
cell . append ( Paragraph ( _ ( " Application No. " ) + " " + str ( self . poll . application . number ) , stylesheet [ ' Ballot_title ' ] ) )
cell . append ( Paragraph ( self . poll . application . title , stylesheet [ ' Ballot_subtitle ' ] ) )
2012-04-18 19:30:32 +02:00
cell . append ( Paragraph ( str ( self . poll . get_ballot ( ) ) + " . " + _ ( " Vote " ) , stylesheet [ ' Ballot_description ' ] ) )
2012-04-13 23:52:34 +02:00
cell . append ( Spacer ( 0 , 0.5 * cm ) )
cell . append ( Paragraph ( circle + _ ( " Yes " ) , stylesheet [ ' Ballot_option ' ] ) )
cell . append ( Paragraph ( circle + _ ( " No " ) , stylesheet [ ' Ballot_option ' ] ) )
cell . append ( Paragraph ( circle + _ ( " Abstention " ) , stylesheet [ ' Ballot_option ' ] ) )
data = [ ]
# get ballot papers config values
ballot_papers_selection = config [ " application_pdf_ballot_papers_selection " ]
ballot_papers_number = config [ " application_pdf_ballot_papers_number " ]
2012-06-29 00:19:06 +02:00
2012-04-13 23:52:34 +02:00
# set number of ballot papers
2012-06-29 00:19:06 +02:00
if ballot_papers_selection == " NUMBER_OF_DELEGATES " :
2012-04-13 23:52:34 +02:00
number = User . objects . filter ( profile__type__iexact = " delegate " ) . count ( )
2012-06-29 00:19:06 +02:00
elif ballot_papers_selection == " NUMBER_OF_ALL_PARTICIPANTS " :
number = int ( Profile . objects . count ( ) )
else : # ballot_papers_selection == "CUSTOM_NUMBER"
2012-04-13 23:52:34 +02:00
number = int ( ballot_papers_number )
2012-06-29 00:19:06 +02:00
number = max ( 1 , number )
2012-04-13 23:52:34 +02:00
# print ballot papers
2012-04-18 19:30:32 +02:00
if number > 0 :
for user in xrange ( number / 2 ) :
data . append ( [ cell , cell ] )
rest = number % 2
if rest :
data . append ( [ cell , ' ' ] )
t = Table ( data , 10.5 * cm , 7.42 * cm )
t . setStyle ( TableStyle ( [ ( ' GRID ' , ( 0 , 0 ) , ( - 1 , - 1 ) , 0.25 , colors . grey ) ,
2012-04-13 23:52:34 +02:00
( ' VALIGN ' , ( 0 , 0 ) , ( - 1 , - 1 ) , ' TOP ' ) ,
] ) )
2012-04-18 19:30:32 +02:00
story . append ( t )
2012-04-13 23:52:34 +02:00
2012-03-16 14:31:59 +01:00
class Config ( FormView ) :
2012-04-14 12:52:56 +02:00
permission_required = ' config.can_manage_config '
2012-03-16 14:31:59 +01:00
form_class = ConfigForm
template_name = ' application/config.html '
def get_initial ( self ) :
return {
' application_min_supporters ' : config [ ' application_min_supporters ' ] ,
' application_preamble ' : config [ ' application_preamble ' ] ,
' application_pdf_ballot_papers_selection ' : config [ ' application_pdf_ballot_papers_selection ' ] ,
' application_pdf_ballot_papers_number ' : config [ ' application_pdf_ballot_papers_number ' ] ,
' application_pdf_title ' : config [ ' application_pdf_title ' ] ,
' application_pdf_preamble ' : config [ ' application_pdf_preamble ' ] ,
2012-06-30 11:31:35 +02:00
' application_allow_trivial_change ' : config [ ' application_allow_trivial_change ' ] ,
2012-03-16 14:31:59 +01:00
}
def form_valid ( self , form ) :
config [ ' application_min_supporters ' ] = form . cleaned_data [ ' application_min_supporters ' ]
config [ ' application_preamble ' ] = form . cleaned_data [ ' application_preamble ' ]
config [ ' application_pdf_ballot_papers_selection ' ] = form . cleaned_data [ ' application_pdf_ballot_papers_selection ' ]
config [ ' application_pdf_ballot_papers_number ' ] = form . cleaned_data [ ' application_pdf_ballot_papers_number ' ]
config [ ' application_pdf_title ' ] = form . cleaned_data [ ' application_pdf_title ' ]
config [ ' application_pdf_preamble ' ] = form . cleaned_data [ ' application_pdf_preamble ' ]
2012-06-30 11:31:35 +02:00
config [ ' application_allow_trivial_change ' ] = form . cleaned_data [ ' application_allow_trivial_change ' ]
2012-03-16 14:31:59 +01:00
messages . success ( self . request , _ ( ' Application settings successfully saved. ' ) )
return super ( Config , self ) . form_valid ( form )
2012-03-18 17:11:58 +01:00
def register_tab ( request ) :
selected = True if request . path . startswith ( ' /application/ ' ) else False
return Tab (
2012-03-19 09:34:13 +01:00
title = _ ( ' Applications ' ) ,
2012-03-18 17:11:58 +01:00
url = reverse ( ' application_overview ' ) ,
permission = request . user . has_perm ( ' application.can_see_application ' ) or request . user . has_perm ( ' application.can_support_application ' ) or request . user . has_perm ( ' application.can_support_application ' ) or request . user . has_perm ( ' application.can_manage_application ' ) ,
selected = selected ,
)
2012-06-11 13:43:48 +02:00
def get_widgets ( request ) :
2012-06-11 14:22:09 +02:00
return [
Widget ( name = ' applications ' , template = ' application/widget.html ' ,
context = { ' applications ' : Application . objects . all ( ) } )
]