source: main/waeup.sirp/branches/henrik-bootstrap/src/waeup/sirp/applicants/pdf.py @ 10009

Last change on this file since 10009 was 7438, checked in by Henrik Bettermann, 13 years ago

Put viewlets into their own module.

Remove unneeded imports.

  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1## $Id: pdf.py 7438 2011-12-22 18:24:35Z 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.publisher.browser import TestRequest
32from waeup.sirp.applicants.interfaces import IApplicant
33from waeup.sirp.browser import DEFAULT_PASSPORT_IMAGE_PATH
34from waeup.sirp.interfaces import IExtFileStore, IPDF
35
36SLIP_STYLE = TableStyle(
37    [('VALIGN',(0,0),(-1,-1),'TOP')]
38    )
39
40
41class PDFApplicationSlip(grok.Adapter):
42
43    grok.context(IApplicant)
44    grok.implements(IPDF)
45    grok.name('application_slip')
46
47    form_fields =  grok.AutoFields(IApplicant).omit(
48        'locked', 'course_admitted')
49
50    @property
51    def title(self):
52        container_title = self.context.__parent__.title
53        return '%s Application Record %s' % (
54            container_title, self.context.application_number)
55
56    def _setUpWidgets(self):
57        """Setup simple display widgets.
58
59        Returns the list of widgets.
60        """
61        request = TestRequest()
62        return setUpEditWidgets(
63            self.form_fields, 'form', self.context, request, {},
64            for_display=True, ignore_request=True
65            )
66
67    def _getCourseAdmittedLink(self, view):
68        """Return link, title and code in html format to the certificate
69           admitted.
70        """
71        course_admitted = self.context.course_admitted
72        if view is not None and getattr(course_admitted, '__parent__',None):
73            url = view.url(course_admitted)
74            title = course_admitted.title
75            code = course_admitted.code
76            return '<a href="%s">%s - %s</a>' %(url,code,title)
77        return ''
78
79    def _addPassportImage(self, data):
80        """Add passport image to data stream.
81
82        If no image exists yet the default image is added.
83        """
84        img = getUtility(IExtFileStore).getFileByContext(self.context)
85        if img is None:
86            img = open(DEFAULT_PASSPORT_IMAGE_PATH, 'rb')
87        doc_img = Image(img.name, width=4*cm, height=3*cm, kind='bound')
88        data.append([doc_img])
89        data.append([Spacer(1, 18)])
90        return data
91
92    def _addDeptAndFaculty(self, data):
93        """If we have a valid course admitted, add dept. and faculty to data
94           stream.
95        """
96        style = getSampleStyleSheet()
97        course_admitted = self.context.course_admitted
98        dept = getattr(
99                getattr(course_admitted, '__parent__', None),
100                '__parent__', None)
101        if dept is None:
102            return data
103        f_label = '<font size=12>Department:</font>'
104        f_text = '<font size=12>%s</font>' % dept.longtitle()
105        f_label = Paragraph(f_label, style["Normal"])
106        f_text = Paragraph(f_text, style["Normal"])
107        data.append([f_label,f_text])
108
109        faculty = getattr(dept, '__parent__', None)
110        if faculty is None:
111            return data
112        f_label = '<font size=12>Faculty:</font>'
113        f_text = '<font size=12>%s</font>' % faculty.longtitle()
114        f_label = Paragraph(f_label, style["Normal"])
115        f_text = Paragraph(f_text, style["Normal"])
116        data.append([f_label,f_text])
117        return data
118
119    def __call__(self, view=None):
120        """Return a PDF representation of the context applicant.
121
122        If no `view` is given, the course admitted field will be an
123        empty string and author will be set as ``'unknown'``.
124
125        If a `view` is given, author will be set as the calling
126        principal.
127        """
128        pdf = canvas.Canvas('application_slip.pdf',pagesize=A4)
129        pdf.setTitle(self.title)
130        pdf.setSubject('Application')
131        if view is None:
132            pdf.setAuthor('unknown')
133        if view is not None:
134            pdf.setAuthor('%s (%s)' % (view.request.principal.title,
135                                      view.request.principal.id))
136        pdf.setCreator('SIRP')
137        width, height = A4
138        style = getSampleStyleSheet()
139        pdf.line(1*cm,height-(1.8*cm),width-(1*cm),height-(1.8*cm))
140
141        story = []
142        frame_header = Frame(1*cm,1*cm,width-(1.7*cm),height-(1.7*cm))
143        header_title = getattr(grok.getSite(), 'name', u'Sample University')
144        story.append(Paragraph(header_title, style["Heading1"]))
145        frame_header.addFromList(story,pdf)
146
147        story = []
148        frame_body = Frame(1*cm,1*cm,width-(2*cm),height-(3.5*cm))
149        story.append(Paragraph(self.title, style["Heading2"]))
150        story.append(Spacer(1, 18))
151        for msg in self.context.history.messages:
152            f_msg = '<font face="Courier" size=10>%s</font>' % msg
153            story.append(Paragraph(f_msg, style["Normal"]))
154        story.append(Spacer(1, 24))
155
156        # Setup table data
157        data = []
158        # Insert passport photograph
159        data = self._addPassportImage(data)
160        # Render widget fields
161        widgets = self._setUpWidgets()
162        for widget in widgets: # self.widgets:
163            f_label = '<font size=12>%s</font>:' % widget.label.strip()
164            f_label = Paragraph(f_label, style["Normal"])
165            f_text = '<font size=12>%s</font>' % widget()
166            f_text = Paragraph(f_text, style["Normal"])
167            data.append([f_label,f_text])
168        f_label = '<font size=12>Admitted Course of Study:</font>'
169        f_text = '<font size=12>%s</font>' % (
170            self._getCourseAdmittedLink(view),)
171        f_label = Paragraph(f_label, style["Normal"])
172        f_text = Paragraph(f_text, style["Normal"])
173        data.append([f_label,f_text])
174
175        # Add dept. and faculty if applicable
176        data = self._addDeptAndFaculty(data)
177
178        # Create table
179        table = Table(data,style=SLIP_STYLE)
180        story.append(table)
181
182        # Add some comments
183        if self.context.state == 'created':
184            comment1 = (
185                '<font size=10>Proceed to the login page of the portal' +
186                ' and enter your new credentials:' +
187                ' user name= %s, password = %s.</font>' %
188                (self.context.student_id, self.context.application_number)
189                )
190            comment2 = (
191                '<font size=10>Change your password when you have ' +
192                ' logged in.</font>'
193                )
194            comment1 = Paragraph(comment1, style["Normal"])
195            comment2 = Paragraph(comment2, style["Normal"])
196            story.append(Spacer(1, 18))
197            story.append(comment1)
198            story.append(comment2)
199
200        frame_body.addFromList(story,pdf)
201
202        story = []
203        frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
204        timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
205        f_text = '<font size=10>%s</font>' % timestamp
206        story.append(Paragraph(f_text, style["Normal"]))
207        frame_footer.addFromList(story,pdf)
208        return pdf.getpdfdata()
Note: See TracBrowser for help on using the repository browser.