source: main/waeup.sirp/trunk/src/waeup/sirp/applicants/pdf.py @ 7430

Last change on this file since 7430 was 7415, checked in by Henrik Bettermann, 13 years ago
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1## $Id: pdf.py 7415 2011-12-21 07:15:47Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
19Generate PDF docs for applicants.
20"""
21import grok
22from datetime import datetime
23from reportlab.pdfgen import canvas
24from reportlab.lib.units import cm
25from reportlab.lib.pagesizes import A4
26from reportlab.lib.styles import getSampleStyleSheet
27from reportlab.platypus import Frame, Paragraph, Image, Table, Spacer
28from reportlab.platypus.tables import TableStyle
29from zope.component import getUtility
30from zope.formlib.form import setUpEditWidgets
31from zope.interface import Interface
32from zope.publisher.browser import TestRequest
33from waeup.sirp.applicants.interfaces import IApplicant
34from waeup.sirp.browser import DEFAULT_PASSPORT_IMAGE_PATH
35from waeup.sirp.interfaces import IExtFileStore, IPDF
36
37SLIP_STYLE = TableStyle(
38    [('VALIGN',(0,0),(-1,-1),'TOP')]
39    )
40
41
42class PDFApplicationSlip(grok.Adapter):
43
44    grok.context(IApplicant)
45    grok.implements(IPDF)
46    grok.name('application_slip')
47
48    form_fields =  grok.AutoFields(IApplicant).omit(
49        'locked', 'course_admitted')
50
51    @property
52    def title(self):
53        container_title = self.context.__parent__.title
54        return '%s Application Record %s' % (
55            container_title, self.context.application_number)
56
57    def _setUpWidgets(self):
58        """Setup simple display widgets.
59
60        Returns the list of widgets.
61        """
62        request = TestRequest()
63        return setUpEditWidgets(
64            self.form_fields, 'form', self.context, request, {},
65            for_display=True, ignore_request=True
66            )
67
68    def _getCourseAdmittedLink(self, view):
69        """Return link, title and code in html format to the certificate
70           admitted.
71        """
72        course_admitted = self.context.course_admitted
73        if view is not None and getattr(course_admitted, '__parent__',None):
74            url = view.url(course_admitted)
75            title = course_admitted.title
76            code = course_admitted.code
77            return '<a href="%s">%s - %s</a>' %(url,code,title)
78        return ''
79
80    def _addPassportImage(self, data):
81        """Add passport image to data stream.
82
83        If no image exists yet the default image is added.
84        """
85        img = getUtility(IExtFileStore).getFileByContext(self.context)
86        if img is None:
87            img = open(DEFAULT_PASSPORT_IMAGE_PATH, 'rb')
88        doc_img = Image(img.name, width=4*cm, height=3*cm, kind='bound')
89        data.append([doc_img])
90        data.append([Spacer(1, 18)])
91        return data
92
93    def _addDeptAndFaculty(self, data):
94        """If we have a valid course admitted, add dept. and faculty to data
95           stream.
96        """
97        style = getSampleStyleSheet()
98        course_admitted = self.context.course_admitted
99        dept = getattr(
100                getattr(course_admitted, '__parent__', None),
101                '__parent__', None)
102        if dept is None:
103            return data
104        f_label = '<font size=12>Department:</font>'
105        f_text = '<font size=12>%s</font>' % dept.longtitle()
106        f_label = Paragraph(f_label, style["Normal"])
107        f_text = Paragraph(f_text, style["Normal"])
108        data.append([f_label,f_text])
109
110        faculty = getattr(dept, '__parent__', None)
111        if faculty is None:
112            return data
113        f_label = '<font size=12>Faculty:</font>'
114        f_text = '<font size=12>%s</font>' % faculty.longtitle()
115        f_label = Paragraph(f_label, style["Normal"])
116        f_text = Paragraph(f_text, style["Normal"])
117        data.append([f_label,f_text])
118        return data
119
120    def __call__(self, view=None):
121        """Return a PDF representation of the context applicant.
122
123        If no `view` is given, the course admitted field will be an
124        empty string and author will be set as ``'unknown'``.
125
126        If a `view` is given, author will be set as the calling
127        principal.
128        """
129        pdf = canvas.Canvas('application_slip.pdf',pagesize=A4)
130        pdf.setTitle(self.title)
131        pdf.setSubject('Application')
132        if view is None:
133            pdf.setAuthor('unknown')
134        if view is not None:
135            pdf.setAuthor('%s (%s)' % (view.request.principal.title,
136                                      view.request.principal.id))
137        pdf.setCreator('SIRP')
138        width, height = A4
139        style = getSampleStyleSheet()
140        pdf.line(1*cm,height-(1.8*cm),width-(1*cm),height-(1.8*cm))
141
142        story = []
143        frame_header = Frame(1*cm,1*cm,width-(1.7*cm),height-(1.7*cm))
144        header_title = getattr(grok.getSite(), 'name', u'Sample University')
145        story.append(Paragraph(header_title, style["Heading1"]))
146        frame_header.addFromList(story,pdf)
147
148        story = []
149        frame_body = Frame(1*cm,1*cm,width-(2*cm),height-(3.5*cm))
150        story.append(Paragraph(self.title, style["Heading2"]))
151        story.append(Spacer(1, 18))
152        for msg in self.context.history.messages:
153            f_msg = '<font face="Courier" size=10>%s</font>' % msg
154            story.append(Paragraph(f_msg, style["Normal"]))
155        story.append(Spacer(1, 24))
156
157        # Setup table data
158        data = []
159        # Insert passport photograph
160        data = self._addPassportImage(data)
161        # Render widget fields
162        widgets = self._setUpWidgets()
163        for widget in widgets: # self.widgets:
164            f_label = '<font size=12>%s</font>:' % widget.label.strip()
165            f_label = Paragraph(f_label, style["Normal"])
166            f_text = '<font size=12>%s</font>' % widget()
167            f_text = Paragraph(f_text, style["Normal"])
168            data.append([f_label,f_text])
169        f_label = '<font size=12>Admitted Course of Study:</font>'
170        f_text = '<font size=12>%s</font>' % (
171            self._getCourseAdmittedLink(view),)
172        f_label = Paragraph(f_label, style["Normal"])
173        f_text = Paragraph(f_text, style["Normal"])
174        data.append([f_label,f_text])
175
176        # Add dept. and faculty if applicable
177        data = self._addDeptAndFaculty(data)
178
179        # Create table
180        table = Table(data,style=SLIP_STYLE)
181        story.append(table)
182
183        # Add some comments
184        if self.context.state == 'created':
185            comment1 = (
186                '<font size=10>Proceed to the login page of the portal' +
187                ' and enter your new credentials:' +
188                ' user name= %s, password = %s.</font>' %
189                (self.context.student_id, self.context.application_number)
190                )
191            comment2 = (
192                '<font size=10>Change your password when you have ' +
193                ' logged in.</font>'
194                )
195            comment1 = Paragraph(comment1, style["Normal"])
196            comment2 = Paragraph(comment2, style["Normal"])
197            story.append(Spacer(1, 18))
198            story.append(comment1)
199            story.append(comment2)
200
201        frame_body.addFromList(story,pdf)
202
203        story = []
204        frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
205        timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
206        f_text = '<font size=10>%s</font>' % timestamp
207        story.append(Paragraph(f_text, style["Normal"]))
208        frame_footer.addFromList(story,pdf)
209        return pdf.getpdfdata()
Note: See TracBrowser for help on using the repository browser.