diff --git a/openslides/application/urls.py b/openslides/application/urls.py index da779d6b0..88038cafd 100644 --- a/openslides/application/urls.py +++ b/openslides/application/urls.py @@ -13,7 +13,7 @@ from django.conf.urls.defaults import * from django.utils.translation import ugettext as _ -from application.views import ViewPoll, ActivatePoll +from application.views import ViewPoll, ActivatePoll, ApplicationPDF, ApplicationPollPDF urlpatterns = patterns('application.views', url(r'^$', @@ -108,17 +108,17 @@ urlpatterns = patterns('application.views', ), url(r'^print/$', - 'print_application', + ApplicationPDF.as_view(), name='print_applications', ), url(r'^(?P\d+)/print/$', - 'print_application', + ApplicationPDF.as_view(), name='print_application', ), url(r'^poll/(?P\d+)/print/$', - 'print_application_poll', + ApplicationPollPDF.as_view(), name='print_application_poll', ), diff --git a/openslides/application/views.py b/openslides/application/views.py index eb802555a..5c800f09b 100644 --- a/openslides/application/views.py +++ b/openslides/application/views.py @@ -13,6 +13,7 @@ from __future__ import with_statement import csv import utils.csv_ext +import os from django.shortcuts import redirect from django.contrib import messages @@ -24,7 +25,14 @@ from django.utils.translation import ungettext from django.db import transaction from django.views.generic.base import RedirectView +from reportlab.lib import colors +from reportlab.lib.units import cm +from reportlab.platypus import PageBreak, Paragraph, Spacer, Table, TableStyle + from system import config +from settings import SITE_ROOT +from utils.pdf import stylesheet +from utils.views import PDFView from agenda.models import Item @@ -45,8 +53,6 @@ from utils.utils import template, permission_required, \ from utils.views import FormView from utils.template import Tab -from utils.pdf import print_application, print_application_poll - from participant.api import gen_username, gen_password @permission_required('application.can_see_application') @@ -479,7 +485,7 @@ def reject_version(request, aversion_id): return redirect(reverse('application_view', args=[application.id])) -@permission_required('application.can_manage_applications') +@permission_required('application.can_manage_application') @template('application/import.html') def application_import(request): try: @@ -588,6 +594,177 @@ def application_import(request): } +class ApplicationPDF(PDFView): + permission_required = 'application.can_manage_application' + filename = u'filename=%s.pdf;' % _("Applications") + top_space = 0 + + def append_to_pdf(self, story): + try: + application_id = self.kwargs['application_id'] + except KeyError: + application_id = None + 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','
'), stylesheet['Paragraph'])) + story.append(Spacer(0,0.75*cm)) + # List of applications + for application in Application.objects.order_by('number'): + 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) + for application in Application.objects.order_by('number'): + story.append(PageBreak()) + story = self.get_application(application, story) + else: # print selected application + application = Application.objects.get(id=application_id) + if application.number: + number = application.number + else: + number = "" + filename = u'filename=%s%s.pdf;' % (_("Application"), str(number)) + 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("%s:" % _("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 = [] + cell2a.append(Paragraph("%s:" % _("Supporters"), stylesheet['Heading4'])) + cell2b = [] + for s in application.supporter.all(): + cell2b.append(Paragraph(".  %s" % unicode(s.profile), stylesheet['Signaturefield'])) + if application.status == "pub": + for x in range(0,application.missing_supporters): + cell2b.append(Paragraph(".  __________________________________________",stylesheet['Signaturefield'])) + cell2b.append(Spacer(0,0.2*cm)) + + # status + note = "" + for n in application.notes: + note += "%s " % unicode(n) + cell3a = [] + cell3a.append(Paragraph("%s:" % _("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]) + + # voting results + if len(application.results) > 0: + cell4a = [] + cell4a.append(Paragraph("%s:" % _("Vote results"), stylesheet['Heading4'])) + cell4b = [] + ballotcounter = 0 + for result in application.results: + ballotcounter += 1 + if len(application.results) > 1: + cell4b.append(Paragraph("%s. %s" % (ballotcounter, _("Vote")), stylesheet['Bold'])) + cell4b.append(Paragraph("%s: %s
%s: %s
%s: %s
%s: %s
%s: %s" % (_("Yes"), result[0], _("No"), result[1], _("Abstention"), result[2], _("Invalid"), result[3], _("Votes cast"), result[4]), stylesheet['Normal'])) + cell4b.append(Spacer(0,0.2*cm)) + data.append([cell4a,cell4b]) + + 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 + story.append(Paragraph(application.title, stylesheet['Heading3'])) + # text + story.append(Paragraph("%s" % application.text.replace('\r\n','
'), stylesheet['Paragraph'])) + # reason + story.append(Paragraph(_("Reason")+":", stylesheet['Heading3'])) + story.append(Paragraph("%s" % application.reason.replace('\r\n','
'), stylesheet['Paragraph'])) + 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): + filename = u'filename=%s%s_%s.pdf;' % (_("Application"), str(self.poll.application.number), _("Poll")) + return filename + + def append_to_pdf(self, story): + imgpath = os.path.join(SITE_ROOT, 'static/images/circle.png') + circle = "  " % 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'])) + #cell.append(Paragraph(str(self.poll.ballot)+". "+_("Vote"), stylesheet['Ballot_description'])) + 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= [] + number = 1 + # get ballot papers config values + ballot_papers_selection = config["application_pdf_ballot_papers_selection"] + ballot_papers_number = config["application_pdf_ballot_papers_number"] + # set number of ballot papers + if ballot_papers_selection == "1": + number = User.objects.filter(profile__type__iexact="delegate").count() + if ballot_papers_selection == "2": + number = int(User.objects.count() - 1) + if ballot_papers_selection == "0": + number = int(ballot_papers_number) + # print ballot papers + 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), + ('VALIGN', (0,0), (-1,-1), 'TOP'), + ])) + story.append(t) + + class Config(FormView): permission_required = 'system.can_manage_system' form_class = ConfigForm diff --git a/openslides/utils/pdf.py b/openslides/utils/pdf.py index 60e028a03..2d6632d8c 100755 --- a/openslides/utils/pdf.py +++ b/openslides/utils/pdf.py @@ -35,7 +35,6 @@ from reportlab.pdfbase.ttfonts import TTFont from openslides.agenda.models import Item from openslides.application.models import Application from openslides.assignment.models import Assignment -#from openslides.poll.models import Poll, Option from openslides.participant.models import Profile from system import config from openslides.settings import SITE_ROOT @@ -297,180 +296,6 @@ def print_passwords(request): return response -def get_application(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("%s:" % _("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 = [] - cell2a.append(Paragraph("%s:" % _("Supporters"), stylesheet['Heading4'])) - cell2b = [] - for s in application.supporter.all(): - cell2b.append(Paragraph(".  %s" % unicode(s.profile), stylesheet['Signaturefield'])) - if application.status == "pub": - for x in range(0,application.missing_supporters): - cell2b.append(Paragraph(".  __________________________________________",stylesheet['Signaturefield'])) - cell2b.append(Spacer(0,0.2*cm)) - - # status - note = "" - for n in application.notes: - note += "%s " % unicode(n) - cell3a = [] - cell3a.append(Paragraph("%s:" % _("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]) - - # voting results - if len(application.results) > 0: - cell4a = [] - cell4a.append(Paragraph("%s:" % _("Vote results"), stylesheet['Heading4'])) - cell4b = [] - ballotcounter = 0 - for result in application.results: - ballotcounter += 1 - if len(application.results) > 1: - cell4b.append(Paragraph("%s. %s" % (ballotcounter, _("Vote")), stylesheet['Bold'])) - cell4b.append(Paragraph("%s: %s
%s: %s
%s: %s
%s: %s
%s: %s" % (_("Yes"), result[0], _("No"), result[1], _("Abstention"), result[2], _("Invalid"), result[3], _("Votes cast"), result[4]), stylesheet['Normal'])) - cell4b.append(Spacer(0,0.2*cm)) - data.append([cell4a,cell4b]) - - 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 - story.append(Paragraph(application.title, stylesheet['Heading3'])) - # text - story.append(Paragraph("%s" % application.text.replace('\r\n','
'), stylesheet['Paragraph'])) - # reason - story.append(Paragraph(_("Reason")+":", stylesheet['Heading3'])) - story.append(Paragraph("%s" % application.reason.replace('\r\n','
'), stylesheet['Paragraph'])) - return story - - -@permission_required('application.can_see_application') -def print_application(request, application_id=None): - response = HttpResponse(mimetype='application/pdf') - filename = u'filename=%s.pdf;' % _("Applications") - response['Content-Disposition'] = filename.encode('utf-8') - doc = SimpleDocTemplate(response) - doc.title = None - story = [] - - 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','
'), stylesheet['Paragraph'])) - story.append(Spacer(0,0.75*cm)) - # List of applications - for application in Application.objects.order_by('number'): - 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) - for application in Application.objects.order_by('number'): - story.append(PageBreak()) - story = get_application(application, story) - else: # print selected application - application = Application.objects.get(id=application_id) - if application.number: - number = application.number - else: - number = "" - filename = u'filename=%s%s.pdf;' % (_("Application"), str(number)) - response['Content-Disposition'] = filename.encode('utf-8') - story = get_application(application, story) - - doc.build(story, onFirstPage=firstPage, onLaterPages=firstPage) - return response - - -@permission_required('application.can_manage_application') -def print_application_poll(request, poll_id=None): - poll = Poll.objects.get(id=poll_id) - response = HttpResponse(mimetype='application/pdf') - filename = u'filename=%s%s_%s.pdf;' % (_("Application"), str(poll.application.number), _("Poll")) - response['Content-Disposition'] = filename.encode('utf-8') - doc = SimpleDocTemplate(response, pagesize=A4, topMargin=-6, bottomMargin=-6, leftMargin=0, rightMargin=0, showBoundary=False) - story = [Spacer(0,0*cm)] - - imgpath = os.path.join(SITE_ROOT, 'static/images/circle.png') - circle = "  " % imgpath - cell = [] - cell.append(Spacer(0,0.8*cm)) - cell.append(Paragraph(_("Application No.")+" "+str(poll.application.number), stylesheet['Ballot_title'])) - cell.append(Paragraph(poll.application.title, stylesheet['Ballot_subtitle'])) - cell.append(Paragraph(str(poll.ballot)+". "+_("Vote"), stylesheet['Ballot_description'])) - 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= [] - number = 1 - # get ballot papers config values - ballot_papers_selection = config["application_pdf_ballot_papers_selection"] - ballot_papers_number = config["application_pdf_ballot_papers_number"] - # set number of ballot papers - if ballot_papers_selection == "1": - number = User.objects.filter(profile__type__iexact="delegate").count() - if ballot_papers_selection == "2": - number = int(User.objects.count() - 1) - if ballot_papers_selection == "0": - number = int(ballot_papers_number) - # print ballot papers - 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), - ('VALIGN', (0,0), (-1,-1), 'TOP'), - ])) - story.append(t) - doc.build(story) - return response - def get_assignment_votes(assignment): votes = [] for candidate in assignment.candidates: diff --git a/openslides/utils/views.py b/openslides/utils/views.py index e5ea0d7d5..40cff226e 100644 --- a/openslides/utils/views.py +++ b/openslides/utils/views.py @@ -1,3 +1,15 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" + openslides.utils.views + ~~~~~~~~~~~~~~~~~~~~~~ + + Views for utils. + + :copyright: 2011 by the OpenSlides team, see AUTHORS. + :license: GNU GPL, see LICENSE for more details. +""" + try: import json except ImportError: @@ -192,6 +204,10 @@ class DeleteView(RedirectView, SingleObjectMixin): class PDFView(PermissionMixin, View): filename = 'No_Name' + top_space = 3 + + def get_top_space(self): + return self.top_space def render_to_response(self, filename): response = HttpResponse(mimetype='application/pdf') @@ -200,7 +216,7 @@ class PDFView(PermissionMixin, View): buffer = StringIO() pdf_document = SimpleDocTemplate(buffer) - story = [Spacer(1,3*cm)] + story = [Spacer(1, self.get_top_space()*cm)] self.append_to_pdf(story)