diff --git a/openslides/participant/api.py b/openslides/participant/api.py index 46edf756e..2f94eb8fe 100644 --- a/openslides/participant/api.py +++ b/openslides/participant/api.py @@ -17,6 +17,9 @@ from django.contrib.auth.models import User def gen_password(): + """ + generates a random passwort. + """ chars = string.letters + string.digits newpassword = '' for i in range(8): @@ -25,6 +28,9 @@ def gen_password(): def gen_username(first_name, last_name): + """ + generates the username for new users. + """ testname = "%s%s" % (first_name, last_name) try: User.objects.get(username=testname) diff --git a/openslides/participant/forms.py b/openslides/participant/forms.py index 15f7a0673..6ee1ce58a 100644 --- a/openslides/participant/forms.py +++ b/openslides/participant/forms.py @@ -10,16 +10,15 @@ :license: GNU GPL, see LICENSE for more details. """ -from django.forms import Form, ModelForm, CharField, EmailField, FileField, FileInput, TextInput, Textarea, MultipleChoiceField, ModelMultipleChoiceField, ChoiceField, BooleanField -from django.contrib.auth.models import User, Group, Permission +from django import forms from django.contrib.auth.forms import AdminPasswordChangeForm +from django.contrib.auth.models import User, Group, Permission +from django.utils.translation import ugettext as _, ugettext_noop -from utils.forms import CssClassMixin -from utils.translation_ext import LocalizedModelMultipleChoiceField, ugettext as _ - -# required for USER_VISIBLE_PERMISSIONS -from participant.models import Profile +from openslides.utils.forms import CssClassMixin +from openslides.utils.translation_ext import LocalizedModelMultipleChoiceField +from openslides.participant.models import Profile USER_APPLICATION_IMPORT_OPTIONS = [ @@ -28,71 +27,85 @@ USER_APPLICATION_IMPORT_OPTIONS = [ ('DISCARD' , _('Discard applications')) ] -class UserNewForm(ModelForm, CssClassMixin): - first_name = CharField(label=_("First name")) - last_name = CharField(label=_("Last name")) - groups = ModelMultipleChoiceField(queryset=Group.objects.all(), label=_("User groups"), required=False) - is_active = BooleanField(label=_("Active"), required=False, initial=True) +class UserNewForm(forms.ModelForm, CssClassMixin): + first_name = forms.CharField(label=_("First name")) + last_name = forms.CharField(label=_("Last name")) + groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all(), + label=_("User groups"), required=False) + is_active = forms.BooleanField(label=_("Active"), required=False, + initial=True) class Meta: model = User - exclude = ('username', 'password', 'is_staff', 'is_superuser', 'last_login', 'date_joined', 'user_permissions') + exclude = ('username', 'password', 'is_staff', 'is_superuser', + 'last_login', 'date_joined', 'user_permissions') -class UserEditForm(ModelForm, CssClassMixin): - first_name = CharField(label=_("First name")) - last_name = CharField(label=_("Last name")) - groups = ModelMultipleChoiceField(queryset=Group.objects.all(), label=_("User groups"), required=False) - is_active = BooleanField(label=_("Active"), required=False) +class UserEditForm(forms.ModelForm, CssClassMixin): + first_name = forms.CharField(label=_("First name")) + last_name = forms.CharField(label=_("Last name")) + groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all(), + label=_("User groups"), required=False) + is_active = forms.BooleanField(label=_("Active"), required=False) class Meta: model = User - exclude = ('password', 'is_staff', 'is_superuser', 'last_login', 'date_joined', 'user_permissions') + exclude = ('password', 'is_staff', 'is_superuser', 'last_login', + 'date_joined', 'user_permissions') -class UsernameForm(ModelForm, CssClassMixin): +class UsernameForm(forms.ModelForm, CssClassMixin): class Meta: model = User - exclude = ('first_name', 'last_name', 'email', 'is_active', 'is_superuser', 'groups', 'password', 'is_staff', 'last_login', 'date_joined', 'user_permissions') + exclude = ('first_name', 'last_name', 'email', 'is_active', + 'is_superuser', 'groups', 'password', 'is_staff', 'last_login', + 'date_joined', 'user_permissions') -class ProfileForm(ModelForm, CssClassMixin): +class ProfileForm(forms.ModelForm, CssClassMixin): class Meta: model = Profile -class GroupForm(ModelForm, CssClassMixin): - permissions = LocalizedModelMultipleChoiceField(queryset=Permission.objects.all(), label=_("Persmissions")) +class GroupForm(forms.ModelForm, CssClassMixin): + permissions = LocalizedModelMultipleChoiceField( + queryset=Permission.objects.all(), label=_("Persmissions")) def __init__(self, *args, **kwargs): super(GroupForm, self).__init__(*args, **kwargs) if kwargs.get('instance', None) is not None: - self.fields['permissions'].initial = [p.pk for p in kwargs['instance'].permissions.all()] + self.fields['permissions'].initial = \ + [p.pk for p in kwargs['instance'].permissions.all()] class Meta: model = Group exclude = ('permissions',) -class UsersettingsForm(ModelForm, CssClassMixin): +class UsersettingsForm(forms.ModelForm, CssClassMixin): class Meta: model = User fields = ('username', 'first_name', 'last_name', 'email') -class UserImportForm(Form, CssClassMixin): - csvfile = FileField(widget=FileInput(attrs={'size':'50'}), label=_("CSV File")) - application_handling = ChoiceField(required=True, choices=USER_APPLICATION_IMPORT_OPTIONS, label=_("For existing applications")) +class UserImportForm(forms.Form, CssClassMixin): + csvfile = forms.FileField(widget=forms.FileInput(attrs={'size':'50'}), + label=_("CSV File")) + application_handling = forms.ChoiceField( + required=True, + choices=USER_APPLICATION_IMPORT_OPTIONS, + label=_("For existing applications"), + ) -class ConfigForm(Form, CssClassMixin): - participant_pdf_system_url = CharField( - widget=TextInput(), +class ConfigForm(forms.Form, CssClassMixin): + participant_pdf_system_url = forms.CharField( + widget=forms.TextInput(), required=False, label=_("System URL"), help_text=_("Printed in PDF of first time passwords only."), ) - participant_pdf_welcometext = CharField( - widget=Textarea(), + participant_pdf_welcometext = forms.CharField( + widget=forms.Textarea(), required=False, label=_("Welcome text"), help_text=_("Printed in PDF of first time passwords only."), diff --git a/openslides/participant/models.py b/openslides/participant/models.py index 32e34ab0a..231c78f40 100644 --- a/openslides/participant/models.py +++ b/openslides/participant/models.py @@ -10,12 +10,17 @@ :license: GNU GPL, see LICENSE for more details. """ +from django.contrib.auth.models import User from django.db import models from django.db.models import Q -from django.contrib.auth.models import User +from django.dispatch import receiver +from django.utils.translation import ugettext as _, ugettext_noop + +from openslides.config.signals import default_config_value + +from openslides.participant.api import gen_password + -from utils.translation_ext import ugettext as _ -from participant.api import gen_password class Profile(models.Model): GENDER_CHOICES = ( @@ -33,18 +38,23 @@ class Profile(models.Model): group = models.CharField(max_length=100, null=True, blank=True, verbose_name = _("Group"), help_text=_('Shown behind the name.')) gender = models.CharField(max_length=50, choices=GENDER_CHOICES, blank=True, - verbose_name = _("Gender"), help_text=_('Only for filter the userlist.')) + verbose_name = _("Gender"), + help_text=_('Only for filter the userlist.')) type = models.CharField(max_length=100, choices=TYPE_CHOICE, blank=True, verbose_name = _("Typ"), help_text=_('Only for filter the userlist.')) committee = models.CharField(max_length=100, null=True, blank=True, - verbose_name = _("Committee"), help_text=_('Only for filter the userlist.')) - comment = models.TextField(null=True, blank=True, verbose_name = _('Comment'), - help_text=_('Only for notes.')) + verbose_name = _("Committee"), + help_text=_('Only for filter the userlist.')) + comment = models.TextField(null=True, blank=True, + verbose_name = _('Comment'), help_text=_('Only for notes.')) firstpassword = models.CharField(max_length=100, null=True, blank=True, verbose_name = _("First Password")) def reset_password(self): + """ + Reset the password for the user to his default-password. + """ self.user.set_password(self.firstpassword) self.user.save() @@ -71,17 +81,16 @@ class Profile(models.Model): class Meta: permissions = ( - ('can_see_participant', _("Can see participant", fixstr=True)), - ('can_manage_participant', _("Can manage participant", fixstr=True)), + ('can_see_participant', ugettext_noop("Can see participant")), + ('can_manage_participant', ugettext_noop("Can manage participant")), ) -from django.dispatch import receiver -from openslides.config.signals import default_config_value - - @receiver(default_config_value, dispatch_uid="participant_default_config") def default_config(sender, key, **kwargs): + """ + Default values for the participant app. + """ return { 'participant_pdf_system_url': 'http://example.com:8000', 'participant_pdf_welcometext': _('Welcome to OpenSlides!'), diff --git a/openslides/participant/tests.py b/openslides/participant/tests.py deleted file mode 100644 index f9c261861..000000000 --- a/openslides/participant/tests.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" - openslides.participant.tests - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Unit tests for the participant app. - - :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. - :license: GNU GPL, see LICENSE for more details. -""" - -from django.test import TestCase - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.failUnlessEqual(1 + 1, 2) - -__test__ = {"doctest": """ -Another way to test that 1 + 1 is equal to 2. - ->>> 1 + 1 == 2 -True -"""} - diff --git a/openslides/participant/urls.py b/openslides/participant/urls.py index a7d152c21..b779b5e53 100644 --- a/openslides/participant/urls.py +++ b/openslides/participant/urls.py @@ -10,7 +10,7 @@ :license: GNU GPL, see LICENSE for more details. """ -from django.conf.urls.defaults import * +from django.conf.urls.defaults import url, patterns from django.core.urlresolvers import reverse from participant.views import ParticipantsListPDF, ParticipantsPasswordsPDF @@ -21,22 +21,22 @@ urlpatterns = patterns('participant.views', name='user_overview', ), - url(r'^new$', + url(r'^new/$', 'edit', name='user_new', ), - url(r'^(?P\d+)/edit$', + url(r'^(?P\d+)/edit/$', 'edit', name='user_edit', ), - url(r'^print$', + url(r'^print/$', ParticipantsListPDF.as_view(), name='user_print', ), - url(r'^(?P\d+)/del$', + url(r'^(?P\d+)/del/$', 'user_delete', name='user_delete', ), @@ -46,7 +46,7 @@ urlpatterns = patterns('participant.views', name='user_status', ), - url(r'^import$', + url(r'^import/$', 'user_import', name='user_import', ), @@ -56,27 +56,27 @@ urlpatterns = patterns('participant.views', name='user_group_overview', ), - url(r'^group/new$', + url(r'^group/new/$', 'group_edit', name='user_group_new', ), - url(r'^group/(?P\d+)/edit$', + url(r'^group/(?P\d+)/edit/$', 'group_edit', name='user_group_edit', ), - url(r'^group/(?P\d+)/del$', + url(r'^group/(?P\d+)/del/$', 'group_delete', name='user_group_delete', ), - url(r'^resetpassword/(?P\d+)$', + url(r'^resetpassword/(?P\d+)/$', 'reset_password', name='user_reset_password', ), - url(r'^passwords/print$', + url(r'^passwords/print/$', ParticipantsPasswordsPDF.as_view(), name='print_passwords', ), diff --git a/openslides/participant/views.py b/openslides/participant/views.py index 59f4d6568..cfe2d37ca 100644 --- a/openslides/participant/views.py +++ b/openslides/participant/views.py @@ -10,10 +10,10 @@ :license: GNU GPL, see LICENSE for more details. """ +# for python 2.5 support from __future__ import with_statement import csv -import utils.csv_ext from urllib import urlencode try: @@ -21,47 +21,50 @@ try: except ImportError: # python <= 2.5 grab it from cgi from cgi import parse_qs -from django.http import HttpResponse -from django.shortcuts import redirect -from django.template import RequestContext -from django.contrib.auth.models import User, Group -from django.contrib.auth.decorators import login_required -from django.contrib import messages -from django.core.urlresolvers import reverse -from django.utils.translation import ugettext as _, ungettext -from django.db import transaction -from django.db.models import Avg, Max, Min, Count - from reportlab.lib import colors from reportlab.lib.units import cm -from reportlab.platypus import SimpleDocTemplate, PageBreak, Paragraph, LongTable, Spacer, Table, TableStyle +from reportlab.platypus import (SimpleDocTemplate, PageBreak, Paragraph, + LongTable, Spacer, Table, TableStyle) -from participant.models import Profile -from participant.api import gen_username, gen_password -from participant.forms import (UserNewForm, UserEditForm, ProfileForm, - UsersettingsForm, UserImportForm, GroupForm, - AdminPasswordChangeForm, ConfigForm) -from application.models import Application +from django.db import transaction +from django.contrib import messages +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User, Group +from django.core.urlresolvers import reverse +from django.shortcuts import redirect +from django.utils.translation import ugettext as _, ungettext -from config.models import config +from openslides.utils import csv_ext +from openslides.utils.pdf import stylesheet +from openslides.utils.template import Tab +from openslides.utils.utils import (template, permission_required, + gen_confirm_form, ajax_request, decodedict, encodedict, + delete_default_permissions) +from openslides.utils.views import FormView, PDFView -from utils.utils import (template, permission_required, gen_confirm_form, - ajax_request, decodedict, encodedict) -from utils.pdf import stylesheet -from utils.template import Tab -from utils.views import (FormView, PDFView) -from utils.utils import delete_default_permissions +from openslides.config.models import config + +from openslides.participant.models import Profile +from openslides.participant.api import gen_username, gen_password +from openslides.participant.forms import (UserNewForm, UserEditForm, + ProfileForm, sersettingsForm, UserImportForm, GroupForm, + AdminPasswordChangeForm, ConfigForm) @permission_required('participant.can_see_participant') @template('participant/overview.html') def get_overview(request): + """ + Show all users. + """ try: - sortfilter = encodedict(parse_qs(request.COOKIES['participant_sortfilter'])) + sortfilter = encodedict(parse_qs( + request.COOKIES['participant_sortfilter'])) except KeyError: sortfilter = {} - for value in [u'gender', u'group', u'type', u'committee', u'status', u'sort', u'reverse']: + for value in [u'gender', u'group', u'type', u'committee', u'status', + u'sort', u'reverse']: if value in request.REQUEST: if request.REQUEST[value] == '---': try: @@ -79,7 +82,8 @@ def get_overview(request): if 'type' in sortfilter: query = query.filter(profile__type__iexact=sortfilter['type'][0]) if 'committee' in sortfilter: - query = query.filter(profile__committee__iexact=sortfilter['committee'][0]) + query = query. \ + filter(profile__committee__iexact=sortfilter['committee'][0]) if 'status' in sortfilter: query = query.filter(is_active=sortfilter['status'][0]) if 'sort' in sortfilter: @@ -115,19 +119,23 @@ def get_overview(request): else: percent = 0 # list of all existing groups - groups = [p['group'] for p in Profile.objects.values('group').exclude(group='').distinct()] + groups = [p['group'] for p in Profile.objects.values('group') \ + .exclude(group='').distinct()] # list of all existing committees - committees = [p['committee'] for p in Profile.objects.values('committee').exclude(committee='').distinct()] + committees = [p['committee'] for p in Profile.objects.values('committee') \ + .exclude(committee='').distinct()] return { 'users': users, 'allusers': allusers, 'percent': round(percent, 1), 'groups': groups, 'committees': committees, - 'cookie': ['participant_sortfilter', urlencode(decodedict(sortfilter), doseq=True)], + 'cookie': ['participant_sortfilter', urlencode(decodedict(sortfilter), + doseq=True)], 'sortfilter': sortfilter, } + @permission_required('participant.can_manage_participant') @template('participant/edit.html') def edit(request, user_id=None): @@ -145,7 +153,8 @@ def edit(request, user_id=None): profileform = ProfileForm(request.POST, prefix="profile") else: userform = UserEditForm(request.POST, instance=user, prefix="user") - profileform = ProfileForm(request.POST, instance=user.profile, prefix="profile") + profileform = ProfileForm(request.POST, instance=user.profile, + prefix="profile") if userform.is_valid() and profileform.is_valid(): user = userform.save() @@ -161,9 +170,11 @@ def edit(request, user_id=None): profile.user.save() profile.save() if user_id is None: - messages.success(request, _('New participant was successfully created.')) + messages.success(request, + _('New participant was successfully created.')) else: - messages.success(request, _('Participant was successfully modified.')) + messages.success(request, + _('Participant was successfully modified.')) if not 'apply' in request.POST: return redirect(reverse('user_overview')) if user_id is None: @@ -184,20 +195,31 @@ def edit(request, user_id=None): 'edituser': user, } + @permission_required('participant.can_manage_participant') @template('confirm.html') def user_delete(request, user_id): + """ + Delete an user. + """ user = User.objects.get(pk=user_id) if request.method == 'POST': user.delete() - messages.success(request, _('Participant %s was successfully deleted.') % user) + messages.success(request, + _('Participant %s was successfully deleted.') % user) else: - gen_confirm_form(request, _('Do you really want to delete %s?') % user, reverse('user_delete', args=[user_id])) + gen_confirm_form(request, + _('Do you really want to delete %s?') % user, + reverse('user_delete', args=[user_id])) return redirect(reverse('user_overview')) + @permission_required('participant.can_manage_participant') @template('confirm.html') def user_set_status(request, user_id): + """ + Set the status of an user. + """ try: user = User.objects.get(pk=user_id) if user.is_active: @@ -206,7 +228,8 @@ def user_set_status(request, user_id): user.is_active = True user.save() except User.DoesNotExist: - messages.error(request, _('Participant ID %d does not exist.') % int(user_id)) + messages.error(request, + _('Participant ID %d does not exist.') % int(user_id)) return redirect(reverse('user_overview')) if request.is_ajax(): @@ -218,9 +241,13 @@ def user_set_status(request, user_id): messages.success(request, _('%s is now absent.') % user) return redirect(reverse('user_overview')) + @permission_required('participant.can_manage_participant') @template('participant/group_overview.html') def get_group_overview(request): + """ + Show all groups. + """ if config['system_enable_anonymous']: groups = Group.objects.all() else: @@ -229,9 +256,13 @@ def get_group_overview(request): 'groups': groups, } + @permission_required('participant.can_manage_participant') @template('participant/group_edit.html') def group_edit(request, group_id=None): + """ + Edit a group. + """ if group_id is not None: try: group = Group.objects.get(id=group_id) @@ -254,7 +285,9 @@ def group_edit(request, group_id=None): # special handling for anonymous auth if group is None and group_name.strip().lower() == 'anonymous': # don't allow to create this group - messages.error(request, _('Group name "%s" is reserved for internal use.') % group_name) + messages.error(request, + _('Group name "%s" is reserved for internal use.') + % group_name) return { 'form' : form, 'group': group @@ -263,12 +296,14 @@ def group_edit(request, group_id=None): group = form.save() if anonymous_group is not None and \ anonymous_group.id == group.id: - # prevent name changes - XXX: I'm sure this could be done as *one* group.save() + # prevent name changes - + # XXX: I'm sure this could be done as *one* group.save() group.name = 'Anonymous' group.save() if group_id is None: - messages.success(request, _('New group was successfully created.')) + messages.success(request, + _('New group was successfully created.')) else: messages.success(request, _('Group was successfully modified.')) if not 'apply' in request.POST: @@ -284,19 +319,30 @@ def group_edit(request, group_id=None): 'group': group, } + @permission_required('participant.can_manage_participant') def group_delete(request, group_id): + """ + Delete a group. + """ group = Group.objects.get(pk=group_id) if request.method == 'POST': group.delete() - messages.success(request, _('Group %s was successfully deleted.') % group) + messages.success(request, + _('Group %s was successfully deleted.') % group) else: - gen_confirm_form(request, _('Do you really want to delete %s?') % group, reverse('user_group_delete', args=[group_id])) + gen_confirm_form(request, + _('Do you really want to delete %s?') % group, + reverse('user_group_delete', args=[group_id])) return redirect(reverse('user_group_overview')) + @login_required @template('participant/settings.html') def user_settings(request): + """ + Edit own user account. + """ if request.method == 'POST': form_user = UsersettingsForm(request.POST,instance=request.user) if form_user.is_valid(): @@ -312,9 +358,14 @@ def user_settings(request): 'edituser': request.user, } + @permission_required('participant.can_manage_participant') @template('participant/import.html') def user_import(request): + """ + Import Users via csv. + """ + from openslides.application.models import Application try: request.user.profile messages.error(request, _('The import function is available for the superuser (without user profile) only.')) @@ -377,7 +428,7 @@ def user_import(request): profile.delete() i = -1 dialect = csv.Sniffer().sniff(request.FILES['csvfile'].readline()) - dialect = utils.csv_ext.patchup(dialect) + dialect = csv_ext.patchup(dialect) request.FILES['csvfile'].seek(0) for (lno, line) in enumerate(csv.reader(request.FILES['csvfile'], dialect=dialect)): @@ -473,33 +524,46 @@ def user_import(request): @permission_required('participant.can_manage_participant') def reset_password(request, user_id): + """ + Reset the Password. + """ user = User.objects.get(pk=user_id) if request.method == 'POST': user.profile.reset_password() - messages.success(request, _('The Password for %s was successfully reset.') % user) + messages.success(request, + _('The Password for %s was successfully reset.') % user) else: - gen_confirm_form(request, _('Do you really want to reset the password for %s?') % user, - reverse('user_reset_password', args=[user_id])) + gen_confirm_form(request, + _('Do you really want to reset the password for %s?') % user, + reverse('user_reset_password', args=[user_id])) return redirect(reverse('user_edit', args=[user_id])) def register_tab(request): - selected = True if request.path.startswith('/participant/') else False + """ + Register the participant tab. + """ + selected = request.path.startswith('/participant/') return Tab( title=_('Participants'), url=reverse('user_overview'), - permission=request.user.has_perm('participant.can_see_participant') or request.user.has_perm('participant.can_manage_participant'), + permission=request.user.has_perm('participant.can_see_participant') + or request.user.has_perm('participant.can_manage_participant'), selected=selected, ) class ParticipantsListPDF(PDFView): + """ + Generate the userliste as PDF. + """ permission_required = 'participant.can_see_participant' filename = _("Participant-list") document_title = _('List of Participants') def append_to_pdf(self, story): - data= [['#', _('Last Name'), _('First Name'), _('Group'), _('Type'), _('Committee')]] + data= [['#', _('Last Name'), _('First Name'), _('Group'), _('Type'), + _('Committee')]] sort = 'last_name' counter = 0 for user in User.objects.all().order_by(sort): @@ -507,34 +571,40 @@ class ParticipantsListPDF(PDFView): counter += 1 user.get_profile() data.append([counter, - Paragraph(user.last_name, stylesheet['Tablecell']), - Paragraph(user.first_name, stylesheet['Tablecell']), - Paragraph(user.profile.group, stylesheet['Tablecell']), - Paragraph(user.profile.get_type_display(), stylesheet['Tablecell']), - Paragraph(user.profile.committee, stylesheet['Tablecell']), - ]) + Paragraph(user.last_name, stylesheet['Tablecell']), + Paragraph(user.first_name, stylesheet['Tablecell']), + Paragraph(user.profile.group, stylesheet['Tablecell']), + Paragraph(user.profile.get_type_display(), + stylesheet['Tablecell']), + Paragraph(user.profile.committee, stylesheet['Tablecell']), + ]) except Profile.DoesNotExist: counter -= 1 pass - t=LongTable(data, - style=[ - ('VALIGN',(0,0),(-1,-1), 'TOP'), - ('LINEABOVE',(0,0),(-1,0),2,colors.black), - ('LINEABOVE',(0,1),(-1,1),1,colors.black), - ('LINEBELOW',(0,-1),(-1,-1),2,colors.black), - ('ROWBACKGROUNDS', (0, 1), (-1, -1), (colors.white, (.9, .9, .9))), - ]) + t = LongTable(data, + style=[ + ('VALIGN',(0,0),(-1,-1), 'TOP'), + ('LINEABOVE',(0,0),(-1,0),2,colors.black), + ('LINEABOVE',(0,1),(-1,1),1,colors.black), + ('LINEBELOW',(0,-1),(-1,-1),2,colors.black), + ('ROWBACKGROUNDS', (0, 1), (-1, -1), + (colors.white, (.9, .9, .9))), + ]) t._argW[0]=0.75*cm story.append(t) class ParticipantsPasswordsPDF(PDFView): + """ + Generate the Welcomepaper for the users. + """ permission_required = 'participant.can_manage_participant' filename = _("Participant-passwords") top_space = 0 def get_template(self, buffer): - return SimpleDocTemplate(buffer, topMargin=-6, bottomMargin=-6, leftMargin=0, rightMargin=0, showBoundary=False) + return SimpleDocTemplate(buffer, topMargin=-6, bottomMargin=-6, + leftMargin=0, rightMargin=0, showBoundary=False) def build_document(self, pdf_document, story): pdf_document.build(story) @@ -548,34 +618,45 @@ class ParticipantsPasswordsPDF(PDFView): user.get_profile() cell = [] cell.append(Spacer(0,0.8*cm)) - cell.append(Paragraph(_("Account for OpenSlides"), stylesheet['Ballot_title'])) - cell.append(Paragraph(_("for %s") % (user.profile), stylesheet['Ballot_subtitle'])) + cell.append(Paragraph(_("Account for OpenSlides"), + stylesheet['Ballot_title'])) + cell.append(Paragraph(_("for %s") % (user.profile), + stylesheet['Ballot_subtitle'])) cell.append(Spacer(0,0.5*cm)) - cell.append(Paragraph(_("User: %s") % (user.username), stylesheet['Monotype'])) - cell.append(Paragraph(_("Password: %s") % (user.profile.firstpassword), stylesheet['Monotype'])) + cell.append(Paragraph(_("User: %s") % (user.username), + stylesheet['Monotype'])) + cell.append(Paragraph(_("Password: %s") + % (user.profile.firstpassword), stylesheet['Monotype'])) cell.append(Spacer(0,0.5*cm)) - cell.append(Paragraph(_("URL: %s") % (participant_pdf_system_url), stylesheet['Ballot_option'])) + cell.append(Paragraph(_("URL: %s") + % (participant_pdf_system_url), + stylesheet['Ballot_option'])) cell.append(Spacer(0,0.5*cm)) cell2 = [] cell2.append(Spacer(0,0.8*cm)) if participant_pdf_welcometext is not None: - cell2.append(Paragraph(participant_pdf_welcometext.replace('\r\n','
'), stylesheet['Ballot_subtitle'])) + cell2.append(Paragraph( + participant_pdf_welcometext.replace('\r\n','
'), + stylesheet['Ballot_subtitle'])) data.append([cell,cell2]) except Profile.DoesNotExist: pass t=Table(data, 10.5*cm, 7.42*cm) - t.setStyle(TableStyle([ ('LINEBELOW', (0,0), (-1,0), 0.25, colors.grey), - ('LINEBELOW', (0,1), (-1,1), 0.25, colors.grey), - ('LINEBELOW', (0,1), (-1,-1), 0.25, colors.grey), - ('VALIGN', (0,0), (-1,-1), 'TOP'), - ])) + t.setStyle(TableStyle([ + ('LINEBELOW', (0,0), (-1,0), 0.25, colors.grey), + ('LINEBELOW', (0,1), (-1,1), 0.25, colors.grey), + ('LINEBELOW', (0,1), (-1,-1), 0.25, colors.grey), + ('VALIGN', (0,0), (-1,-1), 'TOP'), + ])) story.append(t) - class Config(FormView): + """ + Config page for the participant app. + """ permission_required = 'config.can_manage_config' form_class = ConfigForm template_name = 'participant/config.html' @@ -583,11 +664,14 @@ class Config(FormView): def get_initial(self): return { 'participant_pdf_system_url': config['participant_pdf_system_url'], - 'participant_pdf_welcometext': config['participant_pdf_welcometext'], + 'participant_pdf_welcometext': config['participant_pdf_welcometext'] } def form_valid(self, form): - config['participant_pdf_system_url'] = form.cleaned_data['participant_pdf_system_url'] - config['participant_pdf_welcometext'] = form.cleaned_data['participant_pdf_welcometext'] - messages.success(self.request, _('Participants settings successfully saved.')) + config['participant_pdf_system_url'] = \ + form.cleaned_data['participant_pdf_system_url'] + config['participant_pdf_welcometext'] = \ + form.cleaned_data['participant_pdf_welcometext'] + messages.success(self.request, + _('Participants settings successfully saved.')) return super(Config, self).form_valid(form)