## $Id: pdf.py 7835 2012-03-11 15:57:55Z henrik $
##
## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
"""
Generate PDF docs for applicants.
"""
import grok
from datetime import datetime
from zope.component import getUtility
from zope.i18n import translate
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import Frame, Paragraph, Image, Table, Spacer
from reportlab.platypus.tables import TableStyle
from zope.component import getUtility
from zope.formlib.form import setUpEditWidgets
from zope.publisher.browser import TestRequest
from waeup.kofa.applicants.interfaces import IApplicant
from waeup.kofa.browser import DEFAULT_PASSPORT_IMAGE_PATH
from waeup.kofa.interfaces import IExtFileStore, IPDF, IKofaUtils
from waeup.kofa.interfaces import MessageFactory as _
SLIP_STYLE = TableStyle(
[('VALIGN',(0,0),(-1,-1),'TOP')]
)
class PDFApplicationSlip(grok.Adapter):
grok.context(IApplicant)
grok.implements(IPDF)
grok.name('application_slip')
form_fields = grok.AutoFields(IApplicant).omit(
'locked', 'course_admitted')
@property
def title(self):
container_title = self.context.__parent__.title
portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
ar_translation = translate(_('Application Record'),
'waeup.kofa', target_language=portal_language)
return '%s - %s %s' % (container_title,
ar_translation, self.context.application_number)
def _setUpWidgets(self):
"""Setup simple display widgets.
Returns the list of widgets.
"""
request = TestRequest()
return setUpEditWidgets(
self.form_fields, 'form', self.context, request, {},
for_display=True, ignore_request=True
)
def _getCourseAdmittedLink(self, view):
"""Return link, title and code in html format to the certificate
admitted.
"""
course_admitted = self.context.course_admitted
if view is not None and getattr(course_admitted, '__parent__',None):
url = view.url(course_admitted)
title = course_admitted.title
code = course_admitted.code
return '%s - %s' %(url,code,title)
return ''
def _addPassportImage(self, data):
"""Add passport image to data stream.
If no image exists yet the default image is added.
"""
img = getUtility(IExtFileStore).getFileByContext(self.context)
if img is None:
img = open(DEFAULT_PASSPORT_IMAGE_PATH, 'rb')
doc_img = Image(img.name, width=4*cm, height=3*cm, kind='bound')
data.append([doc_img])
data.append([Spacer(1, 18)])
return data
def _addDeptAndFaculty(self, data):
"""If we have a valid course admitted, add dept. and faculty to data
stream.
"""
style = getSampleStyleSheet()
course_admitted = self.context.course_admitted
dept = getattr(
getattr(course_admitted, '__parent__', None),
'__parent__', None)
if dept is None:
return data
portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
dp_translation = translate(_('Department:'),
'waeup.kofa', target_language=portal_language)
f_label = '%s' % dp_translation
f_text = '%s' % dept.longtitle()
f_label = Paragraph(f_label, style["Normal"])
f_text = Paragraph(f_text, style["Normal"])
data.append([f_label,f_text])
faculty = getattr(dept, '__parent__', None)
if faculty is None:
return data
fc_translation = translate(_('Faculty:'),
'waeup.kofa', target_language=portal_language)
f_label = '%s' % fc_translation
f_text = '%s' % faculty.longtitle()
f_label = Paragraph(f_label, style["Normal"])
f_text = Paragraph(f_text, style["Normal"])
data.append([f_label,f_text])
return data
def __call__(self, view=None):
"""Return a PDF representation of the context applicant.
If no `view` is given, the course admitted field will be an
empty string and author will be set as ``'unknown'``.
If a `view` is given, author will be set as the calling
principal.
"""
pdf = canvas.Canvas('application_slip.pdf',pagesize=A4)
pdf.setTitle(self.title)
pdf.setSubject('Application')
if view is None:
pdf.setAuthor('unknown')
if view is not None:
pdf.setAuthor('%s (%s)' % (view.request.principal.title,
view.request.principal.id))
pdf.setCreator('Kofa')
width, height = A4
style = getSampleStyleSheet()
pdf.line(1*cm,height-(1.8*cm),width-(1*cm),height-(1.8*cm))
story = []
frame_header = Frame(1*cm,1*cm,width-(1.7*cm),height-(1.7*cm))
header_title = getattr(grok.getSite(), 'name', u'Sample University')
story.append(Paragraph(header_title, style["Heading1"]))
frame_header.addFromList(story,pdf)
story = []
frame_body = Frame(1*cm,1*cm,width-(2*cm),height-(3.5*cm))
story.append(Paragraph(self.title, style["Heading2"]))
story.append(Spacer(1, 18))
for msg in self.context.history.messages:
f_msg = '%s' % msg
story.append(Paragraph(f_msg, style["Normal"]))
story.append(Spacer(1, 24))
# Setup table data
data = []
# Insert passport photograph
data = self._addPassportImage(data)
# Render widget fields
widgets = self._setUpWidgets()
portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
for widget in widgets: # self.widgets:
f_label = '%s:' % translate(
widget.label.strip(), 'waeup.kofa',
target_language=portal_language)
f_label = Paragraph(f_label, style["Normal"])
f_text = '%s' % widget()
# Add br tag if widgets contain div tags
# which are not supported by reportlab
f_text = f_text.replace('', '
')
f_text = f_text.replace('\n', '')
f_text = Paragraph(f_text, style["Normal"])
data.append([f_label,f_text])
adm_translation = translate(_('Admitted Course of Study:'),
'waeup.kofa', target_language=portal_language)
f_label = '%s' % adm_translation
f_text = '%s' % (
self._getCourseAdmittedLink(view),)
f_label = Paragraph(f_label, style["Normal"])
f_text = Paragraph(f_text, style["Normal"])
data.append([f_label,f_text])
# Add dept. and faculty if applicable
data = self._addDeptAndFaculty(data)
# Create table
table = Table(data,style=SLIP_STYLE)
story.append(table)
# Add some comments
if self.context.state == 'created':
comment1 = _(
'Proceed to the login page of the portal' +
' and enter your new credentials:' +
' user name= ${a}, password = ${b}.', mapping = {
'a':self.context.student_id, 'b':self.context.application_number}
)
comment2 = _(
'Change your password when you have ' +
' logged in.'
)
comment1 = Paragraph(comment1, style["Normal"])
comment2 = Paragraph(comment2, style["Normal"])
story.append(Spacer(1, 18))
story.append(comment1)
story.append(comment2)
frame_body.addFromList(story,pdf)
story = []
frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
f_text = '%s' % timestamp
story.append(Paragraph(f_text, style["Normal"]))
frame_footer.addFromList(story,pdf)
return pdf.getpdfdata()