[FIX] Escaping in PDF
[cds-indico.git] / indico / MaKaC / PDFinterface / conference.py
blob267ea8c85ad6b07c851ca4ade6e175dce54987aa
1 # -*- coding: utf-8 -*-
2 ##
3 ##
4 ## This file is part of CDS Indico.
5 ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
6 ##
7 ## CDS Indico is free software; you can redistribute it and/or
8 ## modify it under the terms of the GNU General Public License as
9 ## published by the Free Software Foundation; either version 2 of the
10 ## License, or (at your option) any later version.
12 ## CDS Indico is distributed in the hope that it will be useful, but
13 ## WITHOUT ANY WARRANTY; without even the implied warranty of
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ## General Public License for more details.
17 ## You should have received a copy of the GNU General Public License
18 ## along with CDS Indico; if not, write to the Free Software Foundation, Inc.,
19 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20 from MaKaC.common import logger, utils
21 import string
22 import types
23 from copy import deepcopy
24 from textwrap import wrap, fill
25 try :
26 from PIL import Image
27 except ImportError, e:
28 from MaKaC.PDFinterface.base import Image
29 from MaKaC.PDFinterface.base import escape, Int2Romans
30 from datetime import timedelta,datetime
31 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
32 from reportlab.lib.units import inch, cm
33 from reportlab.lib import colors
34 from reportlab.lib.enums import TA_JUSTIFY, TA_CENTER, TA_LEFT, TA_RIGHT
35 from reportlab.rl_config import defaultPageSize
36 from reportlab.platypus import Table,TableStyle,KeepTogether, XPreformatted
37 from reportlab.pdfgen import canvas
38 #from PIL import Image
39 from MaKaC.common.timezoneUtils import DisplayTZ,nowutc
40 import MaKaC.webinterface.urlHandlers as urlHandlers
41 import MaKaC.review as review
42 import MaKaC.conference as conference
43 import MaKaC.schedule as schedule
44 from MaKaC.badge import BadgeTemplateItem
45 from MaKaC.poster import PosterTemplateItem
46 from MaKaC.registration import Registrant
47 from MaKaC.PDFinterface.base import PDFBase, PDFWithTOC, Paragraph, Spacer, PageBreak, Preformatted, FileDummy, setTTFonts, PDFSizes, modifiedFontSize, SimpleParagraph
48 from MaKaC.webinterface.pages.tracks import AbstractStatusTrackViewFactory, _ASTrackViewPFOT, _ASTrackViewPA, _ASTrackViewDuplicated, _ASTrackViewMerged,_ASTrackViewAccepted
49 from MaKaC.webinterface.common.abstractStatusWrapper import AbstractStatusList
50 import MaKaC.common.filters as filters
51 import MaKaC.webinterface.common.contribFilters as contribFilters
52 from MaKaC.webinterface.common.contribStatusWrapper import ContribStatusList
53 from MaKaC.errors import MaKaCError, NoReportError
54 from MaKaC.webinterface.common.countries import CountryHolder
55 from reportlab.lib.pagesizes import landscape, A4
56 from MaKaC.badgeDesignConf import BadgeDesignConfiguration
57 from MaKaC.posterDesignConf import PosterDesignConfiguration
58 from MaKaC.webinterface.common.tools import strip_ml_tags
59 import re
60 from MaKaC.i18n import _
61 from indico.util.i18n import i18nformat
64 styles = getSampleStyleSheet()
65 charRplace = [
66 [u'\u2019', u"'"],
67 [u'\u0153', u"oe"],
68 [u'\u2026', u"..."],
69 [u'\u2013', u"-"],
70 [u'\u2018', u"'"]
75 class ProgrammeToPDF(PDFBase):
77 def __init__(self, conf, doc=None, story=None, tz=None):
78 self._conf = conf
79 if not tz:
80 self._tz = self._conf.getTimezone()
81 else:
82 self._tz = tz
83 PDFBase.__init__(self, doc, story)
84 self._title = _("Conference Scientific Programme")
86 def firstPage(self, c, doc):
87 c.saveState()
88 self._drawLogo(c, False)
89 height=self._drawWrappedString(c, strip_ml_tags(self._conf.getTitle()))
90 c.setFont('Times-Bold', 15)
91 height-=2*cm
92 c.drawCentredString(self._PAGE_WIDTH/2.0, height, "%s - %s"%(self._conf.getAdjustedStartDate(self._tz).strftime("%A %d %B %Y"), self._conf.getAdjustedEndDate(self._tz).strftime("%A %d %B %Y")))
93 if self._conf.getLocation():
94 height-=1*cm
95 c.drawCentredString(self._PAGE_WIDTH/2.0, height, escape(self._conf.getLocation().getName()))
96 c.setFont('Times-Bold', 30)
97 height-=6*cm
98 c.drawCentredString(self._PAGE_WIDTH/2.0, height, self._title)
99 self._drawWrappedString(c, "%s / %s"%(strip_ml_tags(self._conf.getTitle()),self._title), width=inch, height=0.75*inch, font='Times-Roman', size=9, color=(0.5,0.5,0.5), align="left", maximumWidth=self._PAGE_WIDTH-3.5*inch, measurement=inch, lineSpacing=0.15)
100 c.drawRightString(self._PAGE_WIDTH - inch, 0.75 * inch, nowutc().strftime("%A %d %B %Y"))
101 c.restoreState()
103 def laterPages(self, c, doc):
104 c.saveState()
105 self._drawWrappedString(c, "%s / %s"%(escape(strip_ml_tags(self._conf.getTitle())),self._title), width=inch, height=self._PAGE_HEIGHT-0.75*inch, font='Times-Roman', size=9, color=(0.5,0.5,0.5), align="left", maximumWidth=self._PAGE_WIDTH-3.5*inch, measurement=inch, lineSpacing=0.15)
106 c.drawCentredString(self._PAGE_WIDTH/2.0, 0.75 * inch, "Page %d "%doc.page)
107 c.drawRightString(self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - 0.75 * inch, nowutc().strftime("%A %d %B %Y"))
108 c.restoreState()
110 def getBody(self, story=None):
111 if not story:
112 story = self._story
113 style = styles["Normal"]
114 style.alignment = TA_JUSTIFY
115 for track in self._conf.getTrackList():
117 bogustext = track.getTitle()
118 p = Paragraph(escape(bogustext), styles["Heading1"])
119 self._story.append(p)
120 bogustext = track.getDescription()
121 p = Paragraph(escape(bogustext), style)
122 story.append(p)
123 story.append(Spacer(1, 0.4*inch))
127 class AbstractToPDF(PDFBase):
129 def __init__(self, conf, abstract, doc=None, story=None, tz=None):
130 self._conf = conf
131 if not tz:
132 self._tz = self._conf.getTimezone()
133 else:
134 self._tz = tz
135 self._abstract = abstract
136 if not story:
137 story = [Spacer(inch, 5*cm)]
138 PDFBase.__init__(self, doc, story)
139 self._title = _("Abstract")
140 self._PAGE_HEIGHT = defaultPageSize[1]
141 self._PAGE_WIDTH = defaultPageSize[0]
143 def firstPage(self, c, doc):
144 c.saveState()
145 c.setFont('Times-Bold', 30)
146 if not self._drawLogo(c):
147 self._drawWrappedString(c, escape(self._conf.getTitle()), height=self._PAGE_HEIGHT - 2*inch)
149 c.setFont('Times-Bold', 25)
150 #c.drawCentredString(self._PAGE_WIDTH/2, self._PAGE_HEIGHT - inch - 5*cm, self._abstract.getTitle())
151 c.setLineWidth(3)
152 c.setStrokeGray(0.7)
153 #c.line(inch, self._PAGE_HEIGHT - inch - 6*cm, self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - inch - 6*cm)
154 #c.line(inch, inch , self._PAGE_WIDTH - inch, inch)
155 c.setFont('Times-Roman', 10)
156 #c.drawString(0.5*inch, 0.5*inch, Config.getInstance().getBaseURL())
157 c.restoreState()
159 def _getTrackText(self):
160 text = i18nformat("""_("Track classification") : """)
161 status=self._abstract.getCurrentStatus()
162 if isinstance(status,review.AbstractStatusAccepted):
163 if status.getTrack() is not None:
164 text="%s%s"%(text,escape(status.getTrack().getTitle()))
165 else:
166 listTrack= []
167 for track in self._abstract.getTrackListSorted():
168 listTrack.append( escape(track.getTitle()))
169 text += " ; ".join(listTrack)
170 return text
172 def _getContribTypeText(self):
173 status=self._abstract.getCurrentStatus()
174 if isinstance(status,review.AbstractStatusAccepted):
175 text= i18nformat(""" _("Contribution type") : %s""")%(escape(str(status.getType())))
176 else:
177 text= i18nformat(""" _("Contribution type") : %s""")%escape(str(self._abstract.getContribType()))
178 return text
180 def getBody(self, story=None, indexedFlowable={}, level=1 ):
181 if not story:
182 story = self._story
184 #style = ParagraphStyle({})
185 #style.fontSize = 12
186 text = i18nformat(""" _("Abstract ID") : %s""")%self._abstract.getId()
187 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
188 p = SimpleParagraph(text, 12)
189 story.append(p)
191 story.append(Spacer(inch, 0.5*cm, part=escape(self._abstract.getTitle())))
193 style = ParagraphStyle({})
194 style.alignment = TA_CENTER
195 style.fontSize = 25
196 style.leading = 30
197 text = escape(self._abstract.getTitle())
198 p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
199 story.append(p)
201 flowableText = escape(self._abstract.getTitle())
202 if self._conf.getBOAConfig().getShowIds():
203 flowableText += """ (%s)"""%self._abstract.getId()
204 indexedFlowable[p] = {"text":escape(flowableText), "level":1}
206 style = ParagraphStyle({})
207 style.fontName = "LinuxLibertine"
208 style.fontSize = 9
209 style.alignment = TA_JUSTIFY
210 #XXX:Not optimal, but the only way I've found to do it
211 #l=self._abstract.getField("content").split("\n")
212 #res=[]
213 #for line in l:
214 # res.append(fill(line,85))
215 #res="\n".join(res)
216 #p = Preformatted(escape(res), style, part=escape(self._abstract.getTitle()))
217 #story.append(p)
219 story.append(Spacer(inch, 0.5*cm, part=escape(self._abstract.getTitle())))
221 for field in self._conf.getAbstractMgr().getAbstractFieldsMgr().getActiveFields():
222 id = field.getId()
223 name = field.getName()
224 value = self._abstract.getField(id).strip()
225 if value: #id not in ["content"] and
226 #styleHead = ParagraphStyle({})
227 #styleHead.firstLineIndent = -45
228 #styleHead.leftIndent = 45
229 text = "%s :" % name
230 #p = Paragraph(text, styleHead, part=escape(self._abstract.getTitle()))
231 p = SimpleParagraph(text, spaceAfter = 5)
232 story.append(p)
233 #l=value.split("\n")
234 #res=[]
235 #for line in l:
236 # res.append(fill(line,85))
237 #res="\n".join(res)
238 p = Paragraph(escape(value), style, part=escape(self._abstract.getTitle()))
239 story.append(p)
240 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
242 story.append(Spacer(inch, 0.5*cm, part=escape(self._abstract.getTitle())))
243 style = ParagraphStyle({})
244 style.firstLineIndent = -80
245 style.leftIndent = 80
246 style.alignment = TA_JUSTIFY
247 text = i18nformat("""<b> _("Primary authors")</b> : """)
248 listAuthor = []
249 for author in self._abstract.getPrimaryAuthorsList():
250 listAuthor.append( "%s (%s)"%(escape(author.getFullName()), escape(author.getAffiliation())) )
251 text += " ; ".join(listAuthor)
252 p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
253 story.append(p)
255 story.append(Spacer(inch, 0.2*cm))
257 style = ParagraphStyle({})
258 style.firstLineIndent = -35
259 style.leftIndent = 35
260 style.alignment = TA_JUSTIFY
261 text = i18nformat("""<b> _("Co-authors")</b> : """)
262 listAuthor = []
263 for author in self._abstract.getCoAuthorList():
264 listAuthor.append( "%s (%s)"%(escape(author.getFullName()), escape(author.getAffiliation()) ) )
265 text += " ; ".join(listAuthor)
267 p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
268 story.append(p)
270 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
272 #style = ParagraphStyle({})
273 #style.firstLineIndent = -45
274 #style.leftIndent = 45
275 text = i18nformat("""_("Presenter") : """)
276 listSpeaker= []
277 for speaker in self._abstract.getSpeakerList():
278 listSpeaker.append( "%s (%s)"%(escape(speaker.getFullName()), escape(speaker.getAffiliation()) ) )
279 text += " ; ".join(listSpeaker)
280 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
281 p = SimpleParagraph(text)
282 story.append(p)
284 story.append(Spacer(inch, 0.5*cm, part=escape(self._abstract.getTitle())))
285 style = ParagraphStyle({})
286 style.firstLineIndent = -90
287 style.leftIndent = 90
288 p = Paragraph(self._getTrackText(), style, part=escape(self._abstract.getTitle()))
289 #p = SimpleParagraph(self._getTrackText())
290 story.append(p)
292 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
293 tmp= i18nformat("""--_("not specified")--""")
294 if self._abstract.getContribType() is not None:
295 tmp=self._abstract.getContribType().getName()
296 text = i18nformat("""_("Contribution type") : %s""")%escape(tmp)
297 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
298 p = SimpleParagraph(text)
299 story.append(p)
301 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
303 text = i18nformat("""_("Submitted by") : %s""")%escape(self._abstract.getSubmitter().getFullName())
304 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
305 p = SimpleParagraph(text)
306 story.append(p)
308 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
310 text = i18nformat("""_("Submitted on") %s""")%self._abstract.getSubmissionDate().strftime("%A %d %B %Y")
311 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
312 p = SimpleParagraph(text)
313 story.append(p)
315 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
317 text = i18nformat("""_("Last modified on") : %s""")%self._abstract.getModificationDate().strftime("%A %d %B %Y")
318 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
319 p = SimpleParagraph(text)
320 story.append(p)
322 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
324 text = i18nformat("""_("Comments") : """)
325 p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
326 #p = SimpleParagraph(text)
327 story.append(p)
329 style = ParagraphStyle({})
330 style.leftIndent = 40
331 style.alignment = TA_JUSTIFY
332 text = "%s"%escape(self._abstract.getComments())
333 p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
334 story.append(p)
336 return story
339 class AbstractsToPDF(PDFWithTOC):
341 def __init__(self, conf, abstractList, tz=None):
342 self._conf = conf
343 if not tz:
344 self._tz = self._conf.getTimezone()
345 else:
346 self._tz = tz
347 self._abstracts = abstractList
348 self._title = _("Abstracts book")
349 PDFWithTOC.__init__(self)
351 def firstPage(self, c, doc):
352 c.saveState()
353 showLogo = False
354 c.setFont('Times-Bold', 30)
355 if not self._drawLogo(c):
356 self._drawWrappedString(c, escape(self._conf.getTitle()), height=self._PAGE_HEIGHT - 2*inch)
358 c.setFont('Times-Bold', 35)
359 c.drawCentredString(self._PAGE_WIDTH/2, self._PAGE_HEIGHT/2, self._title)
360 c.setLineWidth(3)
361 c.setStrokeGray(0.7)
362 c.setFont('Times-Roman', 10)
363 c.drawString(0.5*inch, 0.5*inch, str(urlHandlers.UHConferenceDisplay.getURL(self._conf)))
364 c.restoreState()
366 def laterPages(self, c, doc):
368 c.saveState()
369 c.setFont('Times-Roman', 9)
370 c.setFillColorRGB(0.5, 0.5, 0.5)
371 confTitle = escape(self._conf.getTitle())
372 if len(self._conf.getTitle())>30:
373 confTitle = escape(self._conf.getTitle()[:30] + "...")
374 c.drawString(inch, self._PAGE_HEIGHT - 0.75 * inch, "%s / %s"%(confTitle, self._title))
375 title = doc.getCurrentPart()
376 if len(doc.getCurrentPart())>50:
377 title = utils.unicodeSlice(doc.getCurrentPart(), 0, 50) + "..."
378 c.drawRightString(self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - 0.75 * inch, "%s"%title)
379 c.drawRightString(self._PAGE_WIDTH - inch, 0.75 * inch, i18nformat(""" _("Page") %d """)%doc.page)
380 c.drawString(inch, 0.75 * inch, nowutc().strftime("%A %d %B %Y"))
381 c.restoreState()
384 def getBody(self):
385 abMgr = self._conf.getAbstractMgr()
386 for abstract in self._abstracts:
387 temp = AbstractToPDF(self._conf, abMgr.getAbstractById(abstract), tz=self._tz)
388 temp.getBody(self._story, indexedFlowable=self._indexedFlowable, level=1)
389 self._story.append(PageBreak())
392 class ConfManagerAbstractToPDF(AbstractToPDF):
394 def _getTrackText(self):
395 text = i18nformat("""_("Track classification") : """)
396 listTrack= []
397 for track in self._abstract.getTrackListSorted():
398 listTrack.append( escape(track.getTitle()))
399 text += " ; ".join(listTrack)
400 return text
402 def _getContribTypeText(self):
403 status=self._abstract.getCurrentStatus()
404 text= i18nformat("""_("Contribution type") : %s""")%escape(str(self._abstract.getContribType()))
405 return text
407 def getBody(self, story=None, indexedFlowable={}, level=1 ):
408 if not story:
409 story = self._story
410 #get the common abstract content from parent
411 AbstractToPDF.getBody(self, story, indexedFlowable, level )
412 #add info for the conference manager
413 story.append(Spacer(inch, 0.5*cm, part=escape(self._abstract.getTitle())))
414 status = self._abstract.getCurrentStatus()
415 #style = ParagraphStyle({})
416 #style.firstLineIndent = -90
417 #style.leftIndent = 90
418 if status.__class__ == review.AbstractStatusDuplicated:
419 original=status.getOriginal()
420 st = i18nformat(""" _("DUPLICATED") (%s : %s)""")%(original.getId(), original.getTitle())
421 elif status.__class__ == review.AbstractStatusMerged:
422 target=status.getTargetAbstract()
423 st = i18nformat(""" _("MERGED") (%s : %s)""")%(target.getId(), target.getTitle())
424 else:
425 st = AbstractStatusList.getInstance().getCaption( status.__class__ ).upper()
426 text = i18nformat("""_("Status") : %s""")%escape(st)
427 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
428 p = SimpleParagraph(text)
429 story.append(p)
430 story.append(Spacer(inch, 0.5*cm, part=escape(self._abstract.getTitle())))
431 #style = ParagraphStyle({})
432 #style.firstLineIndent = -90
433 #style.leftIndent = 90
434 text = i18nformat("""_("Track judgments") :""")
435 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
436 p = SimpleParagraph(text)
437 story.append(p)
439 for track in self._abstract.getTrackListSorted():
440 status = self._abstract.getTrackJudgement(track)
441 if status.__class__ == review.AbstractAcceptance:
442 contribType = ""
443 if status.getContribType() is not None:
444 contribType = "(%s)"%status.getContribType().getName()
445 st = i18nformat(""" _("Proposed to accept") %s""")%(contribType)
446 modifDate = status.getDate().strftime("%d %B %Y %H:%M")
447 modifier = status.getResponsible().getFullName()
448 comments = escape(status.getComment())
449 elif status.__class__ == review.AbstractRejection:
450 st = _("Proposed to reject")
451 modifDate = status.getDate().strftime("%d %B %Y %H:%M")
452 modifier = status.getResponsible().getFullName()
453 comments = escape(status.getComment())
454 elif status.__class__ == review.AbstractReallocation:
455 l = []
456 for track in status.getProposedTrackList():
457 l.append( track.getTitle() )
458 st = i18nformat(""" _("Proposed for other tracks") (%s)""")%", ".join(l)
459 modifDate = status.getDate().strftime("%d %B %Y %H:%M")
460 modifier = status.getResponsible().getFullName()
461 comments = escape(status.getComment())
462 else:
463 st = ""
464 modifDate = ""
465 modifier = ""
466 comments = ""
468 story.append(Spacer(inch, 0.5*cm, part=escape(self._abstract.getTitle())))
470 status = self._abstract.getCurrentStatus()
471 #style = ParagraphStyle({})
472 #style.firstLineIndent = -90
473 #style.leftIndent = 130
474 text = i18nformat("""_("Track") : %s""")%escape(track.getTitle())
475 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
476 p = SimpleParagraph(text, indent = 40)
477 story.append(p)
479 story.append(Spacer(inch, 0.1*cm, part=escape(self._abstract.getTitle())))
481 status = self._abstract.getCurrentStatus()
482 #style = ParagraphStyle({})
483 #style.firstLineIndent = -90
484 #style.leftIndent = 170
485 text = i18nformat("""_("Judgment") : %s""")%st
486 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
487 p = SimpleParagraph(text, indent = 80)
488 story.append(p)
490 #story.append(Spacer(inch, 0.1*cm, part=self._abstract.getTitle()))
492 status = self._abstract.getCurrentStatus()
493 #style = ParagraphStyle({})
494 #style.firstLineIndent = -90
495 #style.leftIndent = 170
496 text = i18nformat("""_("Judged by") : %s""")%modifier
497 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
498 p = SimpleParagraph(text, indent = 80)
499 story.append(p)
501 #story.append(Spacer(inch, 0.1*cm, part=self._abstract.getTitle()))
503 status = self._abstract.getCurrentStatus()
504 #style = ParagraphStyle({})
505 #style.firstLineIndent = -90
506 #style.leftIndent = 170
507 text = i18nformat("""_("Date") : %s""")%modifDate
508 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
509 p = SimpleParagraph(text, indent = 80)
510 story.append(p)
512 #story.append(Spacer(inch, 0.1*cm, part=self._abstract.getTitle()))
514 status = self._abstract.getCurrentStatus()
515 style = ParagraphStyle({})
516 style.firstLineIndent = -55
517 style.leftIndent = 135
518 style.alignment = TA_JUSTIFY
519 text = i18nformat("""_("Comments") : \"<i>%s</i>\"""")%comments
520 p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
521 #p = SimpleParagraph(text)
522 story.append(p)
525 class ConfManagerAbstractsToPDF(AbstractsToPDF):
527 def getBody(self):
528 abMgr = self._conf.getAbstractMgr()
529 for abstract in self._abstracts:
530 temp = ConfManagerAbstractToPDF(self._conf, abMgr.getAbstractById(abstract),tz=self._tz)
531 temp.getBody(self._story, indexedFlowable=self._indexedFlowable, level=1)
532 self._story.append(PageBreak())
535 class TrackManagerAbstractToPDF(AbstractToPDF):
537 def __init__(self, conf, abstract, track, doc=None, story=None, tz=None):
538 AbstractToPDF.__init__(self, conf, abstract, doc, story, tz=tz)
539 self._track = track
540 # self._tz = tz
542 def _getTrackText(self):
543 text = i18nformat("""<b> _("Track classification")</b> : """)
544 listTrack= []
545 for track in self._abstract.getTrackListSorted():
546 listTrack.append( escape(track.getTitle()))
547 text += " ; ".join(listTrack)
548 return text
550 def _getContribTypeText(self):
551 status=self._abstract.getCurrentStatus()
552 text= i18nformat("""<b> _("Contribution type")</b> : %s""")%escape(str(self._abstract.getContribType()))
553 return text
555 def getBody(self, story=None, indexedFlowable={}, level=1 ):
556 if not story:
557 story = self._story
558 #get the common abstract content from parent
559 AbstractToPDF.getBody(self, story, indexedFlowable, level )
561 #add info for the track manager
562 status=AbstractStatusTrackViewFactory.getStatus(self._track,self._abstract)
563 comments = escape(status.getComment())
564 st = status.getLabel().upper()
565 conflictText, res = "", ""
566 if isinstance(status, _ASTrackViewPFOT):
567 l = []
568 for track in status.getProposedTrackList():
569 l.append( escape(track.getTitle()) )
570 res = "%s"%", ".join(l)
571 elif isinstance(status, _ASTrackViewPA):
572 contribType = ""
573 if status.getContribType() is not None:
574 contribType = "(%s)"%status.getContribType().getName()
575 res = "%s %s"%( status.getLabel().upper(), \
576 contribType )
577 conflicts = status.getConflicts()
578 if conflicts:
579 l = []
580 for jud in conflicts:
581 if jud.getTrack() != self._track:
582 l.append( "%s ( %s )"%( jud.getTrack().getTitle(), \
583 escape(jud.getResponsible().getFullName()) ) )
584 conflictText = ",\n".join(l)
585 elif isinstance(status, _ASTrackViewDuplicated):
586 orig = status.getOriginal()
587 st = "%s (%s : %s)"%(status.getLabel().upper(), orig.getId(), orig.getTitle())
588 elif isinstance(status, _ASTrackViewMerged):
589 target=status.getTarget()
590 st = "%s (%s : %s)"%(status.getLabel().upper(), target.getId(), target.getTitle())
591 elif isinstance(status,_ASTrackViewAccepted):
592 if status.getContribType() is not None and \
593 status.getContribType()!="":
594 contribType = ""
595 if status.getContribType() is not None:
596 contribType = "(%s)"%status.getContribType().getName()
597 st = "%s %s"%(status.getLabel().upper(),contribType)
598 modifier = ""
599 if status.getResponsible():
600 modifier = escape(status.getResponsible().getFullName())
601 modifDate = ""
602 if status.getDate():
603 modifDate = status.getDate().strftime( "%d %B %Y %H:%M" )
604 story.append(Spacer(inch, 0.5*cm, part=escape(self._abstract.getTitle())))
605 status = self._abstract.getCurrentStatus()
606 #style = ParagraphStyle({})
607 #style.firstLineIndent = -90
608 #style.leftIndent = 90
609 if st:
610 text = i18nformat("""_("Status") : %s""")%st
611 if modifier or modifDate:
612 text += " (%s)"%" - ".join( [modifier, modifDate])
614 else:
615 text = i18nformat("""_("Status") : _("SUBMITTED")""")
616 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
617 p = SimpleParagraph(text)
618 story.append(p)
622 #story.append(Spacer(inch, 0.1*cm, part=self._abstract.getTitle()))
624 if res:
625 status = self._abstract.getCurrentStatus()
626 style = ParagraphStyle({})
627 style.leftIndent = 60
628 text = "(<i>%s</i>)"%res
629 p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
630 story.append(p)
633 if comments:
634 status = self._abstract.getCurrentStatus()
635 style = ParagraphStyle({})
636 style.leftIndent = 40
637 text = "\"<i>%s</i>\""%comments
638 p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
639 story.append(p)
641 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
643 if conflictText:
644 style = ParagraphStyle({})
645 style.leftIndent = 40
646 p = Paragraph( i18nformat(""" _("In conflict with"): """), style, part=escape(self._abstract.getTitle()))
647 story.append(p)
649 style = ParagraphStyle({})
650 style.leftIndent = 60
651 p = Preformatted(conflictText, style, part=escape(self._abstract.getTitle()))
652 story.append(p)
655 class TrackManagerAbstractsToPDF(AbstractsToPDF):
657 def __init__(self, conf, track, abstractList, tz=None):
658 AbstractsToPDF.__init__(self, conf, abstractList, tz)
659 self._track = track
661 def getBody(self):
662 abMgr = self._conf.getAbstractMgr()
663 for abstract in self._abstracts:
664 temp = TrackManagerAbstractToPDF(self._conf, abMgr.getAbstractById(abstract), self._track, tz=self._tz)
665 temp.getBody(self._story, indexedFlowable=self._indexedFlowable, level=1)
666 self._story.append(PageBreak())
669 class ContribToPDF(PDFBase):
671 def __init__(self, conf, contrib, doc=None, story=None, tz=None):
672 self._conf = conf
673 if not tz:
674 self._tz = self._conf.getTimezone()
675 else:
676 self._tz = tz
677 self._contrib = contrib
678 if not story:
679 story = [Spacer(inch, 5*cm)]
680 PDFBase.__init__(self, doc, story)
681 self._title = _("Contribution")
682 self._PAGE_HEIGHT = defaultPageSize[1]
683 self._PAGE_WIDTH = defaultPageSize[0]
685 def firstPage(self, c, doc):
686 c.saveState()
687 c.setFont('Times-Bold', 30)
688 if not self._drawLogo(c):
689 self._drawWrappedString(c, escape(self._conf.getTitle()), height=self._PAGE_HEIGHT - 2*inch)
690 c.setFont('Times-Bold', 25)
691 #c.drawCentredString(self._PAGE_WIDTH/2, self._PAGE_HEIGHT - inch - 5*cm, self._abstract.getTitle())
692 c.setLineWidth(3)
693 c.setStrokeGray(0.7)
694 #c.line(inch, self._PAGE_HEIGHT - inch - 6*cm, self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - inch - 6*cm)
695 #c.line(inch, inch , self._PAGE_WIDTH - inch, inch)
696 c.setFont('Times-Roman', 10)
697 #c.drawString(0.5*inch, 0.5*inch, Config.getInstance().getBaseURL())
698 c.restoreState()
700 def getBody(self, story=None, indexedFlowable={}, level=1 ):
701 if not story:
702 story = self._story
704 style = ParagraphStyle({})
705 style.fontSize = 12
706 text = i18nformat(""" _("Contribution ID") : %s""")%self._contrib.getId()
707 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
708 story.append(p)
710 story.append(Spacer(inch, 0.5*cm, part=escape(self._contrib.getTitle())))
712 style = ParagraphStyle({})
713 style.alignment = TA_CENTER
714 style.fontSize = 25
715 style.leading = 30
716 text = escape(self._contrib.getTitle())
717 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
718 story.append(p)
720 if self._contrib.isScheduled():
721 style = ParagraphStyle({})
722 style.alignment = TA_CENTER
723 style.fontSize = 12
724 style.leading = 30
725 text = "%s (%s)" % (escape(self._contrib.getAdjustedStartDate(self._tz).strftime("%A %d %b %Y at %H:%M")),escape((datetime(1900,1,1)+self._contrib.getDuration()).strftime("%Hh%M'")))
726 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
727 story.append(p)
729 indexedFlowable[p] = {"text":escape(self._contrib.getTitle()), "level":1}
731 story.append(Spacer(inch, 1*cm, part=escape(self._contrib.getTitle())))
733 style = ParagraphStyle({})
734 style.fontName = "LinuxLibertine"
735 style.fontSize = 9
736 #p = Paragraph(escape(self._contrib.getDescription()), style, part=escape(self._contrib.getTitle()))
737 #story.append(p)
739 #story.append(Spacer(inch, 0.2*cm, part=escape(self._contrib.getTitle())))
741 for field in self._conf.getAbstractMgr().getAbstractFieldsMgr().getActiveFields():
742 fid = field.getId()
743 name = field.getName()
744 value = self._contrib.getField(fid).strip()
745 if value: #id not in ["content"] and
746 styleHead = ParagraphStyle({})
747 styleHead.firstLineIndent = -55
748 styleHead.leftIndent = 45
749 text = "<b>%s</b> :" % name
750 p = Paragraph(text, styleHead, part=escape(self._contrib.getTitle()))
751 story.append(p)
752 l=value.split("\n")
753 res=[]
754 for line in l:
755 res.append(fill(line,85))
756 res="\n".join(res)
757 p = Paragraph(escape(res), style, part=escape(self._contrib.getTitle()))
758 story.append(p)
759 story.append(Spacer(inch, 0.2*cm, part=escape(self._contrib.getTitle())))
761 story.append(Spacer(inch, 0.5*cm, part=escape(self._contrib.getTitle())))
763 style = ParagraphStyle({})
764 style.firstLineIndent = -80
765 style.leftIndent = 80
766 text = i18nformat("""<b> _("Primary authors")</b> : """)
767 listAuthor = []
768 for author in self._contrib.getPrimaryAuthorsList():
769 listAuthor.append( "%s (%s)"%(escape(author.getFullName()), escape(author.getAffiliation())) )
770 text += " ; ".join(listAuthor)
771 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
772 story.append(p)
774 story.append(Spacer(inch, 0.2*cm))
776 style = ParagraphStyle({})
777 style.firstLineIndent = -35
778 style.leftIndent = 35
779 text = i18nformat("""<b> _("Co-authors")</b> : """)
780 listAuthor = []
781 for author in self._contrib.getCoAuthorList():
782 listAuthor.append( "%s (%s)"%(escape(author.getFullName()), escape(author.getAffiliation()) ) )
783 text += " ; ".join(listAuthor)
785 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
786 story.append(p)
788 story.append(Spacer(inch, 0.2*cm, part=escape(self._contrib.getTitle())))
790 style = ParagraphStyle({})
791 style.firstLineIndent = -45
792 style.leftIndent = 45
793 text = i18nformat("""<b> _("Presenter")</b> : """)
794 listSpeaker= []
795 for speaker in self._contrib.getSpeakerList():
796 listSpeaker.append( "%s (%s)"%(escape(speaker.getFullName()), escape(speaker.getAffiliation()) ) )
797 text += " ; ".join(listSpeaker)
798 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
799 story.append(p)
801 story.append(Spacer(inch, 0.5*cm, part=escape(self._contrib.getTitle())))
802 style = ParagraphStyle({})
803 style.firstLineIndent = -90
804 style.leftIndent = 90
805 session = self._contrib.getSession()
806 if session!=None:
807 sessiontitle = session.getTitle()
808 else:
809 sessiontitle = i18nformat("""--_("not yet classified")--""")
810 text = i18nformat("""<b> _("Session classification") </b> : %s""")%escape(sessiontitle)
811 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
812 story.append(p)
814 story.append(Spacer(inch, 0.5*cm, part=escape(self._contrib.getTitle())))
816 style = ParagraphStyle({})
817 style.firstLineIndent = -90
818 style.leftIndent = 90
819 track = self._contrib.getTrack()
820 if track!=None:
821 tracktitle = track.getTitle()
822 else:
823 tracktitle = i18nformat("""--_("not yet classified")--""")
824 text = i18nformat("""<b> _("Track classification")</b> : %s""")%escape(tracktitle)
825 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
826 story.append(p)
828 story.append(Spacer(inch, 0.2*cm, part=escape(self._contrib.getTitle())))
830 tmp=i18nformat("""--_("not specified")--""")
831 if self._contrib.getType():
832 tmp=self._contrib.getType().getName()
833 text = i18nformat("""<b> _("Type")</b> : %s""")%escape(tmp)
834 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
835 story.append(p)
837 # TB: Do we really need to display the submitssion info of a contribution?
838 #story.append(Spacer(inch, 0.2*cm, part=escape(self._contrib.getTitle())))
840 #text = "<b>Submitted by</b> : %s"%escape(self._contrib.getSubmitter().getFullName())
841 #p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
842 #story.append(p)
844 return story
846 class ConfManagerContribToPDF(ContribToPDF):
848 def getBody(self, story=None, indexedFlowable={}, level=1 ):
849 if not story:
850 story = self._story
852 #get the common contribution content from parent
853 ContribToPDF.getBody(self, story, indexedFlowable, level )
855 #add info for the conference manager
858 class ContributionBook(PDFBase):
860 def __init__(self,conf,contribList,aw,tz=None, sortedBy=""):
861 self._conf=conf
862 if not tz:
863 self._tz = self._conf.getTimezone()
864 else:
865 self._tz = tz
866 self._contribList = contribList
867 self._aw=aw
868 PDFBase.__init__(self)
869 self._title=_("Book of abstracts")
870 self._sortedBy = sortedBy
871 if self._sortedBy == "boardNo":
872 try:
873 self._contribList = sorted(self._contribList, key=lambda x:int(x.getBoardNumber()))
874 except ValueError,e:
875 raise MaKaCError(_("In order to generate this PDF, all the contributions must contain a board number and it must only contain digits. There is a least one contribution with a wrong board number."))
876 self._doc.leftMargin=1*cm
877 self._doc.rightMargin=1*cm
878 self._doc.topMargin=1.5*cm
879 self._doc.bottomMargin=1*cm
881 def firstPage(self,c,doc):
882 c.saveState()
883 self._drawLogo(c, False)
884 height=self._drawWrappedString(c, self._conf.getTitle())
885 c.setFont('Times-Bold',15)
886 height-=2*cm
887 c.drawCentredString(self._PAGE_WIDTH/2.0,height,
888 "%s - %s"%(self._conf.getAdjustedStartDate(self._tz).strftime("%A %d %B %Y"),
889 self._conf.getAdjustedEndDate(self._tz).strftime("%A %d %B %Y")))
890 if self._conf.getLocation():
891 height-=1*cm
892 c.drawCentredString(self._PAGE_WIDTH/2.0,height,
893 escape(self._conf.getLocation().getName()))
894 c.setFont('Times-Bold', 30)
895 height-=6*cm
896 c.drawCentredString(self._PAGE_WIDTH/2.0,height,\
897 self._title)
898 self._drawWrappedString(c, "%s / %s"%(self._conf.getTitle(),self._title), width=inch, height=0.75*inch, font='Times-Roman', size=9, color=(0.5,0.5,0.5), align="left", maximumWidth=self._PAGE_WIDTH-3.5*inch, measurement=inch, lineSpacing=0.15)
899 c.drawRightString(self._PAGE_WIDTH-inch,0.75*inch,
900 nowutc().strftime("%A %d %B %Y"))
901 c.restoreState()
903 def laterPages(self,c,doc):
904 c.saveState()
905 c.setFont('Times-Roman',9)
906 c.setFillColorRGB(0.5,0.5,0.5)
907 c.drawString(1*cm,self._PAGE_HEIGHT-1*cm,
908 "%s / %s"%(escape(self._conf.getTitle()),self._title))
909 c.drawCentredString(self._PAGE_WIDTH/2.0,0.5*cm,"Page %d "%doc.page)
910 c.restoreState()
912 def _defineStyles(self):
913 self._styles={}
914 titleStyle=getSampleStyleSheet()["Heading1"]
915 titleStyle.fontSize=13.0
916 titleStyle.spaceBefore=0
917 titleStyle.spaceAfter=4
918 titleStyle.leading=14
919 self._styles["title"]=titleStyle
920 spkStyle=getSampleStyleSheet()["Heading2"]
921 spkStyle.fontSize=10.0
922 spkStyle.spaceBefore=0
923 spkStyle.spaceAfter=0
924 spkStyle.leading=14
925 self._styles["speakers"]=spkStyle
926 abstractStyle=getSampleStyleSheet()["Normal"]
927 abstractStyle.fontSize=10.0
928 abstractStyle.spaceBefore=0
929 abstractStyle.spaceAfter=0
930 abstractStyle.alignment=TA_LEFT
931 self._styles["abstract"]=abstractStyle
932 ttInfoStyle=getSampleStyleSheet()["Normal"]
933 ttInfoStyle.fontSize=10.0
934 ttInfoStyle.spaceBefore=0
935 ttInfoStyle.spaceAfter=0
936 self._styles["tt_info"]=ttInfoStyle
937 normalStyle=getSampleStyleSheet()["Normal"]
938 normalStyle.fontSize=10.0
939 normalStyle.spaceBefore=5
940 normalStyle.spaceAfter=5
941 normalStyle.alignment=TA_LEFT
942 self._styles["normal"]=normalStyle
944 def getBody(self,story=None):
945 self._defineStyles()
946 if not story:
947 story=self._story
948 story.append(PageBreak())
949 if self._conf.getBOAConfig().getText() != "":
950 text=self._conf.getBOAConfig().getText().replace("<BR>","<br>")
951 text=text.replace("<Br>","<br>")
952 text=text.replace("<bR>","<br>")
953 for par in text.split("<br>"):
954 p=Paragraph(par,self._styles["normal"])
955 story.append(p)
956 story.append(PageBreak())
957 for contrib in self._contribList:
958 if not contrib.canAccess(self._aw):
959 continue
960 if self._sortedBy == "boardNo":
961 caption="%s"%(contrib.getTitle())
962 else:
963 caption="%s - %s"%(contrib.getId(),contrib.getTitle())
964 p1=Paragraph(escape(caption),self._styles["title"])
965 lspk=[]
966 for spk in contrib.getSpeakerList():
967 fullName=spk.getFullName()
968 instit=spk.getAffiliation().strip()
969 if instit!="":
970 fullName="%s (%s)"%(fullName, instit)
971 lspk.append("%s"%escape(fullName))
972 speakers= i18nformat("""<b>_("Presenter"): %s</b>""")%"; ".join(lspk)
973 p2=Paragraph(speakers,self._styles["speakers"])
974 abstract=contrib.getDescription()
975 p3=Paragraph(escape(abstract),self._styles["abstract"])
976 ses=""
977 if contrib.getSession() is not None:
978 ses=contrib.getSession().getTitle()
979 if contrib.getBoardNumber():
980 if ses != "":
981 ses = "%s - "%ses
982 ses="%sBoard: %s"%(ses, contrib.getBoardNumber())
983 if contrib.isScheduled():
984 if ses != "":
985 ses = "%s - "%ses
986 text="%s%s"%(ses,contrib.getAdjustedStartDate(self._tz).strftime("%A %d %B %Y %H:%M"))
987 else:
988 text = ses
989 p4=Paragraph(escape(text),self._styles["tt_info"])
990 abs=KeepTogether([p1,p4,p2,p3])
991 story.append(abs)
992 story.append(Spacer(1,0.4*inch))
995 class ContribsToPDF(PDFWithTOC):
997 def __init__(self, conf, contribList, tz=None):
998 self._conf = conf
999 if not tz:
1000 self._tz = self._conf.getTimezone()
1001 else:
1002 self._tz = tz
1003 self._contribs = contribList
1004 self._title = _("Contributions book")
1005 PDFWithTOC.__init__(self)
1007 def firstPage(self, c, doc):
1008 c.saveState()
1009 showLogo = False
1010 c.setFont('Times-Bold', 30)
1011 if not self._drawLogo(c):
1012 self._drawWrappedString(c, escape(self._conf.getTitle()), height=self._PAGE_HEIGHT - 2*inch)
1013 c.setFont('Times-Bold', 35)
1014 c.drawCentredString(self._PAGE_WIDTH/2, self._PAGE_HEIGHT/2, self._title)
1015 c.setLineWidth(3)
1016 c.setStrokeGray(0.7)
1017 #c.line(inch, self._PAGE_HEIGHT - inch - 6*cm, self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - inch - 6*cm)
1018 #c.line(inch, inch , self._PAGE_WIDTH - inch, inch)
1019 c.setFont('Times-Roman', 10)
1020 c.drawString(0.5*inch, 0.5*inch, str(urlHandlers.UHConferenceDisplay.getURL(self._conf)))
1021 c.restoreState()
1023 def laterPages(self, c, doc):
1025 c.saveState()
1026 c.setFont('Times-Roman', 9)
1027 c.setFillColorRGB(0.5, 0.5, 0.5)
1028 confTitle = escape(self._conf.getTitle())
1029 if len(self._conf.getTitle())>30:
1030 confTitle = escape(self._conf.getTitle()[:30] + "...")
1031 c.drawString(inch, self._PAGE_HEIGHT - 0.75 * inch, "%s / %s"%(confTitle, self._title))
1032 title = doc.getCurrentPart()
1033 if len(doc.getCurrentPart())>50:
1034 title = utils.unicodeSlice(doc.getCurrentPart(), 0, 50) + "..."
1035 c.drawRightString(self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - 0.75 * inch, "%s"%title)
1036 c.drawRightString(self._PAGE_WIDTH - inch, 0.75 * inch, i18nformat(""" _("Page") %d """)%doc.page)
1037 c.drawString(inch, 0.75 * inch, nowutc().strftime("%A %d %B %Y"))
1038 c.restoreState()
1041 def getBody(self):
1042 for contrib in self._contribs:
1043 temp = ContribToPDF(self._conf, contrib, tz=self._tz)
1044 temp.getBody(self._story, indexedFlowable=self._indexedFlowable, level=1)
1045 self._story.append(PageBreak())
1047 class ConfManagerContribsToPDF(ContribsToPDF):
1049 def getBody(self):
1050 for contrib in self._contribs:
1051 temp = ConfManagerContribToPDF(self._conf, contrib,tz=self._tz)
1052 temp.getBody(self._story, indexedFlowable=self._indexedFlowable, level=1)
1053 self._story.append(PageBreak())
1055 class TimetablePDFFormat:
1057 def __init__(self, params=None):
1058 if params is None:
1059 self.contribId = True
1060 self.speakerTitle = True
1061 self.contribAbstract = False
1062 self.newPagePerSession = False
1063 self.useSessionColorCodes = False
1064 self.showSessionTOC = False
1065 self.logo = False
1066 self.lengthContribs = False
1067 self.contribsAtConfLevel=False
1068 self.breaksAtConfLevel=False
1069 self.dateCloseToSessions=False
1070 self.coverPage=True
1071 self.tableContents=True
1072 else:
1073 self.setValues(params)
1075 def setValues(self, params):
1076 self.contribId = True
1077 if not params.has_key("showContribId"):
1078 self.contribId = False
1080 self.speakerTitle = True
1081 if not params.has_key("showSpeakerTitle"):
1082 self.speakerTitle = False
1084 self.contribAbstract = False
1085 if params.has_key("showAbstract"):
1086 self.contribAbstract = True
1088 self.contribPosterAbstract = True
1089 if params.has_key("dontShowPosterAbstract"):
1090 self.contribPosterAbstract = False
1092 self.newPagePerSession = False
1093 if params.has_key("newPagePerSession"):
1094 self.newPagePerSession = True
1096 self.useSessionColorCodes = False
1097 if params.has_key("useSessionColorCodes"):
1098 self.useSessionColorCodes = True
1100 self.showSessionTOC = False
1101 if params.has_key("showSessionTOC"):
1102 self.showSessionTOC = True
1104 self.lengthContribs = False
1105 if params.has_key("showLengthContribs"):
1106 self.lengthContribs = True
1108 self.contribsAtConfLevel = False
1109 if params.has_key("showContribsAtConfLevel"):
1110 self.contribsAtConfLevel = True
1112 self.breaksAtConfLevel = False
1113 if params.has_key("showBreaksAtConfLevel"):
1114 self.breaksAtConfLevel = True
1116 self.dateCloseToSessions = False
1117 if params.has_key("printDateCloseToSessions"):
1118 self.dateCloseToSessions = True
1120 self.coverPage=True
1121 if not params.has_key("showCoverPage"):
1122 self.coverPage = False
1124 self.tableContents=True
1125 if not params.has_key("showTableContents"):
1126 self.tableContents = False
1128 self.logo = False
1130 def showContribId(self):
1131 return self.contribId
1133 def showSpeakerTitle(self):
1134 return self.speakerTitle
1136 def showContribAbstract(self):
1137 return self.contribAbstract
1139 def showContribPosterAbstract(self):
1140 return self.contribPosterAbstract
1142 def showLogo(self):
1143 return self.logo
1145 def showNewPagePerSession(self):
1146 return self.newPagePerSession
1148 def showUseSessionColorCodes(self):
1149 return self.useSessionColorCodes
1151 def showTitleSessionTOC(self):
1152 return self.showSessionTOC
1154 def showLengthContribs(self):
1155 return self.lengthContribs
1157 def showContribsAtConfLevel(self):
1158 return self.contribsAtConfLevel
1160 def showBreaksAtConfLevel(self):
1161 return self.breaksAtConfLevel
1163 def showDateCloseToSessions(self):
1164 return self.dateCloseToSessions
1166 def showCoverPage(self):
1167 return self.coverPage
1169 def showTableContents(self):
1170 return self.tableContents
1173 def sortEntries(x,y):
1174 if cmp(x.getStartDate(),y.getStartDate()):
1175 return cmp(x.getStartDate(),y.getStartDate())
1176 else:
1177 try:
1178 return cmp(x.getOwner().getSession().getTitle(),y.getOwner().getSession().getTitle())
1179 except:
1180 return cmp(x.getTitle(),y.getTitle())
1182 class TimeTablePlain(PDFWithTOC):
1184 def __init__(self,conf,aw,showSessions=[],showDays=[],sortingCrit=None, ttPDFFormat=None,
1185 pagesize='A4', fontsize = 'normal', firstPageNumber = '1', showSpeakerAffiliation=False, tz=None):
1186 self._conf=conf
1187 if not tz:
1188 self._tz = self._conf.getTimezone()
1189 else:
1190 self._tz = tz
1191 self._aw=aw
1192 self._tz = DisplayTZ(self._aw,self._conf).getDisplayTZ()
1193 self._showSessions=showSessions
1194 self._showDays=showDays
1195 self._ttPDFFormat = ttPDFFormat or TimetablePDFFormat()
1196 story=[]
1197 if self._ttPDFFormat.showCoverPage():
1198 story=None
1199 PDFWithTOC.__init__(self, story=story, pagesize = pagesize, fontsize=fontsize, firstPageNumber = firstPageNumber)
1200 self._title= _("Programme")
1201 self._doc.leftMargin=1*cm
1202 self._doc.rightMargin=1*cm
1203 self._doc.topMargin=1.5*cm
1204 self._doc.bottomMargin=1*cm
1205 self._sortingCrit=sortingCrit
1206 self._firstPageNumber = firstPageNumber
1207 self._showSpeakerAffiliation = showSpeakerAffiliation
1209 def _processTOCPage(self):
1210 if self._ttPDFFormat.showTableContents():
1211 style1 = ParagraphStyle({})
1212 style1.fontName = "Times-Bold"
1213 style1.fontSize = modifiedFontSize(18, self._fontsize)
1214 style1.leading = modifiedFontSize(22, self._fontsize)
1215 style1.alignment = TA_CENTER
1216 self._story.append(Spacer(inch, 1*cm))
1217 p = Paragraph( _("Table of contents"), style1)
1218 self._story.append(p)
1219 self._story.append(Spacer(inch, 1*cm))
1220 if len(self._showSessions)>0:
1221 style2=ParagraphStyle({})
1222 style2.fontSize=modifiedFontSize(14, self._fontsize)
1223 style2.leading=modifiedFontSize(10, self._fontsize)
1224 style2.alignment=TA_CENTER
1225 caption=[]
1226 for sessionId in self._showSessions:
1227 session=self._conf.getSessionById(sessionId)
1228 if session is not None:
1229 caption.append(session.getTitle())
1230 p=Paragraph("%s"%"\n".join(caption),style2)
1231 self._story.append(p)
1232 self._story.append(Spacer(inch, 2*cm))
1233 self._story.append(self._toc)
1234 self._story.append(PageBreak())
1236 def firstPage(self,c,doc):
1237 if self._ttPDFFormat.showCoverPage():
1238 c.saveState()
1239 if self._ttPDFFormat.showLogo():
1240 self._drawLogo(c, False)
1241 height = self._drawWrappedString(c, self._conf.getTitle())
1242 c.setFont('Times-Bold',modifiedFontSize(15, self._fontsize))
1243 height-=2*cm
1244 c.drawCentredString(self._PAGE_WIDTH/2.0,height,
1245 "%s - %s"%(self._conf.getAdjustedStartDate(self._tz).strftime("%A %d %B %Y"),
1246 self._conf.getAdjustedEndDate(self._tz).strftime("%A %d %B %Y")))
1247 if self._conf.getLocation():
1248 height-=2*cm
1249 c.drawCentredString(self._PAGE_WIDTH/2.0,height,escape(self._conf.getLocation().getName()))
1250 c.setFont('Times-Bold', modifiedFontSize(30, self._fontsize))
1251 height-=1*cm
1252 c.drawCentredString(self._PAGE_WIDTH/2.0,height,\
1253 self._title)
1254 self._drawWrappedString(c, "%s / %s"%(self._conf.getTitle(),self._title), width=inch, height=0.75*inch, font='Times-Roman', size=modifiedFontSize(9, self._fontsize), color=(0.5,0.5,0.5), align="left", maximumWidth=self._PAGE_WIDTH-3.5*inch, measurement=inch, lineSpacing=0.15)
1255 c.drawRightString(self._PAGE_WIDTH-inch,0.75*inch,
1256 nowutc().strftime("%A %d %B %Y"))
1257 c.restoreState()
1259 def laterPages(self,c,doc):
1261 c.saveState()
1262 maxi=self._PAGE_WIDTH-2*cm
1263 if doc.getCurrentPart().strip() != "":
1264 maxi=self._PAGE_WIDTH-6*cm
1265 self._drawWrappedString(c, "%s / %s"%(self._conf.getTitle(),self._title), width=1*cm, height=self._PAGE_HEIGHT-1*cm, font='Times-Roman', size=modifiedFontSize(9, self._fontsize), color=(0.5,0.5,0.5), align="left", lineSpacing=0.3, maximumWidth=maxi)
1266 c.drawCentredString(self._PAGE_WIDTH/2.0,0.5*cm,i18nformat(""" _("Page") %d """)%(doc.page + self._firstPageNumber - 1))
1267 c.drawRightString(self._PAGE_WIDTH-1*cm,self._PAGE_HEIGHT-1*cm,doc.getCurrentPart())
1268 c.restoreState()
1270 def _defineStyles(self):
1271 self._styles={}
1273 dayStyle=getSampleStyleSheet()["Heading1"]
1274 dayStyle.fontSize = modifiedFontSize(dayStyle.fontSize, self._fontsize)
1275 self._styles["day"]=dayStyle
1277 sessionTitleStyle=getSampleStyleSheet()["Heading2"]
1278 sessionTitleStyle.fontSize = modifiedFontSize(12.0, self._fontsize)
1279 self._styles["session_title"]=sessionTitleStyle
1281 sessionDescriptionStyle=getSampleStyleSheet()["Heading2"]
1282 sessionDescriptionStyle.fontSize = modifiedFontSize(10.0, self._fontsize)
1283 self._styles["session_description"] = sessionDescriptionStyle
1285 self._styles["table_body"]=getSampleStyleSheet()["Normal"]
1287 convenersStyle=getSampleStyleSheet()["Normal"]
1288 convenersStyle.fontSize = modifiedFontSize(10.0, self._fontsize)
1289 convenersStyle.leftIndent=10
1290 self._styles["conveners"]=convenersStyle
1292 subContStyle=getSampleStyleSheet()["Normal"]
1293 subContStyle.fontSize=modifiedFontSize(10.0, self._fontsize)
1294 subContStyle.leftIndent=15
1295 self._styles["subContrib"]=subContStyle
1297 def _HTMLColorToRGB(self, colorstring):
1298 """ convert #RRGGBB to an (R, G, B) tuple """
1299 colorstring = colorstring.strip()
1300 if colorstring[0] == '#': colorstring = colorstring[1:]
1301 if len(colorstring) != 6:
1302 raise ValueError, "input #%s is not in #RRGGBB format" % colorstring
1303 r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:]
1304 r, g, b = [float(int(n, 16))/256 for n in (r, g, b)]
1305 #raise MaKaCError(str((r,g,b)))
1306 return (r, g, b)
1308 def _getSessionColor(self,ses):
1309 HTMLcolor = ses.getSession().getColor()
1310 color = self._HTMLColorToRGB(HTMLcolor)
1311 return color
1313 def _processContribution(self,contrib,l):
1314 if not contrib.canAccess(self._aw):
1315 return
1316 date = "%s"%escape(contrib.getAdjustedStartDate(self._tz).strftime("%H:%M"))
1317 #date="<font size=\"" + str(modifiedFontSize(10, self._fontsize)) + "\">%s</font>"%date
1318 #date=self._fontify(date,10)
1319 #date.style=self._styles["table_body"]
1320 date=Paragraph(date,self._styles["table_body"])
1321 lt=[]
1322 captionText="[%s] %s"%(escape(contrib.getId()),escape(contrib.getTitle()))
1323 if not self._ttPDFFormat.showContribId():
1324 captionText="%s"%(escape(contrib.getTitle()))
1325 if self._ttPDFFormat.showLengthContribs():
1326 captionText="%s (%s)"%(captionText, escape((datetime(1900,1,1)+contrib.getDuration()).strftime("%Hh%M'")))
1327 if self._ttPDFFormat.showContribAbstract():
1328 captionText="<font name=\"Times-Bold\"><b>%s</b></font>"%captionText
1329 captionText="<font size=\"" + str(modifiedFontSize(10, self._fontsize)) + "\">%s</font>"%captionText
1330 lt.append([self._fontify(captionText,10)])
1331 colorCell = ""
1332 if self._useColors():
1333 colorCell = " "
1334 if self._ttPDFFormat.showContribAbstract():
1335 spkList=[]
1336 for spk in contrib.getSpeakerList():
1337 spkName = spk.getFullName()
1338 if not self._ttPDFFormat.showSpeakerTitle():
1339 spkName = self._getNameWithoutTitle(spk)
1340 if self._showSpeakerAffiliation and spk.getAffiliation().strip() != "":
1341 spkName += " (" + spk.getAffiliation() + ")"
1342 spkList.append(spkName)
1343 if len(spkList) > 0:
1344 if len(spkList) == 1:
1345 speakerWord = i18nformat(""" _("Presenter"): """)
1346 else:
1347 speakerWord = i18nformat(""" _("Presenters"): """)
1348 speakerText = speakerWord + ", ".join(spkList)
1349 speakerText = "<font name=\"Times-Italic\"><i>%s</i></font>"%speakerText
1350 lt.append([self._fontify(speakerText,9)])
1351 captionText=escape(contrib.getDescription())
1352 lt.append([self._fontify(captionText,9)])
1353 captionAndSpeakers = Table(lt,colWidths=(None),style=self._tsSpk)
1354 if colorCell != "":
1355 l.append([colorCell,date,captionAndSpeakers])
1356 else:
1357 l.append([date,captionAndSpeakers])
1358 else:
1359 caption = Table(lt,colWidths=(None),style=self._tsSpk)
1360 spkList=[]
1361 for spk in contrib.getSpeakerList():
1362 spkName = spk.getFullName()
1363 if not self._ttPDFFormat.showSpeakerTitle():
1364 spkName = self._getNameWithoutTitle(spk)
1365 if self._showSpeakerAffiliation and spk.getAffiliation().strip() != "":
1366 spkName += " (" + spk.getAffiliation() + ")"
1367 p=Paragraph(escape(spkName),self._styles["table_body"])
1368 spkList.append([p])
1369 if len(spkList)==0:
1370 spkList=[[""]]
1371 speakers=Table(spkList,style=self._tsSpk)
1372 if colorCell != "":
1373 l.append([colorCell,date,caption,speakers])
1374 else:
1375 l.append([date,caption,speakers])
1376 for subc in contrib.getSubContributionList():
1377 if not subc.canAccess(self._aw):
1378 return
1379 lt=[]
1380 captionText="- [%s] %s"%(escape(subc.getId()),escape(subc.getTitle()))
1381 if not self._ttPDFFormat.showContribId():
1382 captionText="- %s"%(escape(subc.getTitle()))
1383 if self._ttPDFFormat.showLengthContribs():
1384 captionText="%s (%s)"%(captionText, escape((datetime(1900,1,1)+subc.getDuration()).strftime("%Hh%M'")))
1385 captionText="<font size=\"" + str(modifiedFontSize(10, self._fontsize)) + "\">%s</font>"%captionText
1386 lt.append([Paragraph(captionText,self._styles["subContrib"])])
1387 if self._ttPDFFormat.showContribAbstract():
1388 captionText="<font size=\"" + str(modifiedFontSize(9, self._fontsize)) + "\">%s</font>"%(escape(subc.getDescription()))
1389 lt.append([Paragraph(captionText,self._styles["subContrib"])])
1390 spkList=[]
1391 for spk in subc.getSpeakerList():
1392 spkName = spk.getFullName()
1393 if not self._ttPDFFormat.showSpeakerTitle():
1394 spkName = self._getNameWithoutTitle(spk)
1395 p=Paragraph(escape(spkName),self._styles["table_body"])
1396 spkList.append([p])
1397 if len(spkList)==0:
1398 spkList=[[""]]
1399 if self._ttPDFFormat.showContribAbstract():
1400 lt = spkList+lt
1401 captionAndSpeakers = Table(lt,colWidths=(None),style=self._tsSpk)
1402 if colorCell != "":
1403 l.append([colorCell,"",captionAndSpeakers])
1404 else:
1405 l.append(["",captionAndSpeakers])
1406 else:
1407 caption = Table(lt,colWidths=(None),style=self._tsSpk)
1408 speakers=Table(spkList,style=self._tsSpk)
1409 if colorCell != "":
1410 l.append([colorCell,"",caption,speakers])
1411 else:
1412 l.append(["",caption,speakers])
1415 def _processPosterContribution(self,contrib,l):
1416 if not contrib.canAccess(self._aw):
1417 return
1418 lt=[]
1419 captionText="[%s] %s"%(escape(contrib.getId()),escape(contrib.getTitle()))
1420 if not self._ttPDFFormat.showContribId():
1421 captionText="%s"%(escape(contrib.getTitle()))
1422 if self._ttPDFFormat.showLengthContribs():
1423 captionText="%s (%s)"%(captionText, escape((datetime(1900,1,1)+contrib.getDuration()).strftime("%Hh%M'")))
1424 captionText="<font name=\"Times-Bold\">%s</font>"%captionText
1425 lt.append([self._fontify(captionText,10)])
1426 boardNumber="%s"%escape(contrib.getBoardNumber())
1427 if self._ttPDFFormat.showContribAbstract() and self._ttPDFFormat.showContribPosterAbstract():
1428 spkList=[]
1429 for spk in contrib.getSpeakerList():
1430 spkName = spk.getFullName()
1431 if not self._ttPDFFormat.showSpeakerTitle():
1432 spkName = self._getNameWithoutTitle(spk)
1433 if self._showSpeakerAffiliation and spk.getAffiliation().strip() != "":
1434 spkName += " (" + spk.getAffiliation() + ")"
1435 spkList.append(spkName)
1436 if len(spkList) > 0:
1437 if len(spkList) == 1:
1438 speakerWord = i18nformat(""" _("Presenter"): """)
1439 else:
1440 speakerWord = i18nformat(""" _("Presenters"): """)
1441 speakerText = speakerWord + ", ".join(spkList)
1442 speakerText = "<font name=\"Times-Italic\"><i>%s</i></font>"%speakerText
1443 lt.append([self._fontify(speakerText, 10)])
1444 captionText=escape(contrib.getDescription())
1445 lt.append([self._fontify(captionText,9)])
1446 captionAndSpeakers = Table(lt,colWidths=(None),style=self._tsSpk)
1447 if self._useColors():
1448 l.append([" ",captionAndSpeakers,boardNumber])
1449 else:
1450 l.append([captionAndSpeakers,boardNumber])
1451 else:
1452 caption = Table(lt,colWidths=(None),style=self._tsSpk)
1453 spkList=[]
1454 for spk in contrib.getSpeakerList():
1455 spkName = spk.getFullName()
1456 if not self._ttPDFFormat.showSpeakerTitle():
1457 spkName = self._getNameWithoutTitle(spk)
1458 p=Paragraph(escape(spkName),self._styles["table_body"])
1459 spkList.append([p])
1460 if len(spkList)==0:
1461 spkList=[[""]]
1462 speakers=Table(spkList,style=self._tsSpk)
1463 if self._useColors():
1464 l.append([" ",caption,speakers, boardNumber])
1465 else:
1466 l.append([caption,speakers, boardNumber])
1467 for subc in contrib.getSubContributionList():
1468 if not subc.canAccess(self._aw):
1469 return
1470 lt=[]
1471 captionText="- [%s] %s"%(escape(subc.getId()),escape(subc.getTitle()))
1472 if not self._ttPDFFormat.showContribId():
1473 captionText="- %s"%(escape(subc.getTitle()))
1474 if self._ttPDFFormat.showLengthContribs():
1475 captionText="%s (%s)"%(captionText, escape((datetime(1900,1,1)+subc.getDuration()).strftime("%Hh%M'")))
1476 lt.append([Paragraph(captionText,self._styles["subContrib"])])
1477 if self._ttPDFFormat.showContribAbstract():
1478 captionText="<font size=\"" + str(modifiedFontSize(9, self._fontsize)) + "\">%s</font>"%(escape(subc.getDescription()))
1479 lt.append([Paragraph(captionText,self._styles["subContrib"])])
1480 caption = Table(lt,colWidths=(None),style=self._tsSpk)
1481 spkList=[]
1482 for spk in subc.getSpeakerList():
1483 spkName = spk.getFullName()
1484 if not self._ttPDFFormat.showSpeakerTitle():
1485 spkName = self._getNameWithoutTitle(spk)
1486 p=Paragraph(escape(spkName),self._styles["table_body"])
1487 spkList.append([p])
1488 if len(spkList)==0:
1489 spkList=[[""]]
1490 speakers=Table(spkList,style=self._tsSpk)
1491 l.append(["",caption,speakers])
1493 def _getNameWithoutTitle(self, av):
1494 res = av.getFamilyName().upper()
1495 if av.getFirstName() != "":
1496 res = "%s, %s"%( res, av.getFirstName() )
1497 return res
1499 def _useColors(self):
1500 return self._ttPDFFormat.showUseSessionColorCodes()
1502 def _fontify(self, text, fSize=10, fName=""):
1503 style = getSampleStyleSheet()["Normal"]
1504 style.fontSize=modifiedFontSize(fSize, self._fontsize)
1505 style.leading=modifiedFontSize(fSize+3, self._fontsize)
1506 return Paragraph(text,style)
1508 def _fontifyRow(self, row, fSize=10, fName=""):
1509 newrow = []
1510 for text in row:
1511 newrow.append(self._fontify(text,fSize,fName))
1512 return newrow
1514 def _processDayEntries(self,day,story):
1515 res=[]
1516 originalts=TableStyle([('VALIGN',(0,0),(-1,-1),"TOP"),
1517 ('LEFTPADDING',(0,0),(-1,-1),1),
1518 ('RIGHTPADDING',(0,0),(-1,-1),1),
1519 ('GRID',(0,1),(-1,-1),1,colors.lightgrey)])
1520 self._tsSpk=TableStyle([("LEFTPADDING",(0,0),(0,-1),0),
1521 ("RIGHTPADDING",(0,0),(0,-1),0),
1522 ("TOPPADDING",(0,0),(0,-1),1),
1523 ("BOTTOMPADDING",(0,0),(0,-1),0)])
1524 colorts=TableStyle([("LEFTPADDING",(0,0),(-1,-1),3),
1525 ("RIGHTPADDING",(0,0),(-1,-1),0),
1526 ("TOPPADDING",(0,0),(-1,-1),0),
1527 ("BOTTOMPADDING",(0,0),(-1,-1),0),
1528 ('GRID',(0,0),(0,-1),1,colors.lightgrey)])
1529 entriesOnDay=self._conf.getSchedule().getEntriesOnDay(day)
1530 entriesOnDay.sort(sortEntries)
1531 for entry in entriesOnDay:
1532 #Session slot
1533 if isinstance(entry,schedule.LinkedTimeSchEntry) and \
1534 isinstance(entry.getOwner(),conference.SessionSlot):
1535 sessionSlot=entry.getOwner()
1536 if len(self._showSessions)>0 and \
1537 sessionSlot.getSession().getId() not in self._showSessions:
1538 continue
1539 if not sessionSlot.canView(self._aw):
1540 continue
1541 room=""
1542 if sessionSlot.getRoom() is not None:
1543 room=" - %s"%escape(sessionSlot.getRoom().getName())
1544 sesCaption="%s"%sessionSlot.getSession().getTitle()
1545 if sessionSlot.getTitle()!="":
1546 sesCaption="%s: %s"%(sesCaption,sessionSlot.getTitle())
1547 conv=[]
1548 for c in sessionSlot.getConvenerList():
1549 if self._showSpeakerAffiliation and c.getAffiliation().strip() != "":
1550 conv.append("%s (%s)"%(escape(c.getFullName()), escape(c.getAffiliation())))
1551 else:
1552 conv.append(escape(c.getFullName()))
1553 conv="; ".join(conv)
1554 if conv!="":
1555 conv=i18nformat("""<font name=\"Times-Bold\"><b>- _("Conveners"): %s</b></font>""")%conv
1556 res.append(Paragraph("",self._styles["session_title"]))
1557 startDateStr = escape(sessionSlot.getAdjustedStartDate(self._tz).strftime("%H:%M"))
1558 if self._ttPDFFormat.showDateCloseToSessions():
1559 startDateStr = escape(sessionSlot.getAdjustedStartDate(self._tz).strftime("%d %B %H:%M"))
1560 text="""<u>%s</u>%s (%s-%s)"""%(
1561 escape(sesCaption),room,
1562 #escape(sessionSlot.getStartDate().strftime("%d %B %H:%M")),
1563 #escape(sessionSlot.getEndDate().strftime("%H:%M")))
1564 startDateStr,
1565 escape(sessionSlot.getAdjustedEndDate(self._tz).strftime("%H:%M")))
1566 p1=Paragraph(text,self._styles["session_title"])
1567 if self._useColors():
1568 l = [["",p1]]
1569 widths=[0.2*cm,None]
1570 ts = deepcopy(colorts)
1571 ts.add('BACKGROUND', (0, 0), (0,-1), self._getSessionColor(sessionSlot))
1572 p1 = Table(l,colWidths=widths,style=ts)
1573 res.append(p1)
1574 if self._ttPDFFormat.showTitleSessionTOC():
1575 self._indexedFlowable[p1]={"text":escape(sessionSlot.getSession().getTitle()), "level":2}
1576 ## if self._useColors():
1577 ## l = [["",p1]]
1578 ## widths=[0.2*cm,None]
1579 ## ts = deepcopy(colorts)
1580 ## ts.add('BACKGROUND', (0, 0), (0,-1), self._getSessionColor(sessionSlot))
1581 ## res.append(Table(l,colWidths=widths,style=ts))
1582 ## else:
1583 ## res.append(p1)
1584 #add session description
1585 if sessionSlot.getSession().getDescription():
1586 text = "<i>%s</i>"%escape(sessionSlot.getSession().getDescription())
1587 p = Paragraph(text,self._styles["session_description"])
1588 res.append(p)
1589 p2=Paragraph(conv,self._styles["conveners"])
1590 res.append(p2)
1591 l=[]
1592 ts = deepcopy(originalts)
1593 if sessionSlot.getSession().getScheduleType()=="poster":
1594 if self._sortingCrit is not None:
1595 cl=[]
1596 for sEntry in sessionSlot.getSchedule().getEntries():
1597 if isinstance(sEntry,schedule.LinkedTimeSchEntry) and isinstance(sEntry.getOwner(),conference.Contribution):
1598 cl.append(sEntry.getOwner())
1599 f=filters.SimpleFilter(None,self._sortingCrit)
1600 for contrib in f.apply(cl):
1601 self._processPosterContribution(contrib,l)
1602 else:
1603 for sEntry in sessionSlot.getSchedule().getEntries():
1604 if isinstance(sEntry,schedule.LinkedTimeSchEntry) and isinstance(sEntry.getOwner(),conference.Contribution):
1605 contrib=sEntry.getOwner()
1606 self._processPosterContribution(contrib,l)
1607 if len(l)>0:
1608 title = "[id] title"
1609 if not self._ttPDFFormat.showContribId():
1610 title = "title"
1611 if self._ttPDFFormat.showContribAbstract() and self._ttPDFFormat.showContribPosterAbstract():
1612 #presenter integrated in 1st column -> 2 columns only
1613 row = [title,"board"]
1614 widths=[None,1*cm]
1615 else:
1616 row = [title,"presenter","board"]
1617 widths=[None,5*cm,1*cm]
1618 row = self._fontifyRow(row,11)
1619 if self._useColors():
1620 row.insert(0,"")
1621 widths.insert(0,0.2*cm)
1622 l.insert(0,row)
1623 if self._useColors():
1624 ts.add('BACKGROUND', (0, 1), (0,-1), self._getSessionColor(sessionSlot))
1625 t=Table(l,colWidths=widths,style=ts)
1626 else: #it's not a poster
1627 for sEntry in sessionSlot.getSchedule().getEntries():
1628 if isinstance(sEntry,schedule.LinkedTimeSchEntry) and isinstance(sEntry.getOwner(),conference.Contribution):
1629 contrib=sEntry.getOwner()
1630 self._processContribution(contrib,l)
1631 elif isinstance(sEntry,schedule.BreakTimeSchEntry):
1632 ## date="%s"%escape(sEntry.getStartDate().strftime("%H:%M"))
1633 ## date=self._fontify(date,10)
1634 date="%s"%escape(sEntry.getAdjustedStartDate(self._tz).strftime("%H:%M"))
1635 date=self._fontify(date,10)
1637 lt=[]
1638 captionText="%s"%escape(sEntry.getTitle())
1639 if self._ttPDFFormat.showLengthContribs():
1640 captionText="%s (%s)"%(captionText, escape((datetime(1900,1,1)+sEntry.getDuration()).strftime("%Hh%M'")))
1641 lt.append([self._fontify(captionText,10)])
1642 caption = Table(lt,colWidths=(None),style=self._tsSpk)
1643 if self._ttPDFFormat.showContribAbstract():
1644 row = [date,caption]
1645 else:
1646 row = [date,caption,""]
1647 if self._useColors():
1648 row.insert(0,"")
1649 l.append(row)
1650 if len(l)>0:
1651 title = "[id] title"
1652 if not self._ttPDFFormat.showContribId():
1653 title = "title"
1654 if self._ttPDFFormat.showContribAbstract():
1655 #presenter integrated in 1st column -> 2 columns only
1656 row = ["time",title]
1657 widths = [1*cm,None]
1658 else:
1659 row = ["time",title,"presenter"]
1660 widths = [1*cm,None,5*cm]
1661 row = self._fontifyRow(row,11)
1662 if self._useColors():
1663 row.insert(0,"")
1664 widths.insert(0,0.2*cm)
1665 l.insert(0,row)
1666 if self._useColors():
1667 ts.add('BACKGROUND', (0, 1), (0,-1), self._getSessionColor(sessionSlot))
1668 t=Table(l,colWidths=widths,style=ts)
1669 if len(l)>0:
1670 res.append(t)
1671 if self._ttPDFFormat.showNewPagePerSession():
1672 res.append(PageBreak())
1673 elif entry == entriesOnDay[-1]: # if it is the last one, we do the page break and remove the previous one.
1674 i=len(res)-1
1675 while i>=0:
1676 if isinstance(res[i], PageBreak):
1677 del res[i]
1678 break
1679 i-=1
1680 if self._ttPDFFormat.showNewPagePerSession():
1681 res.append(PageBreak())
1682 #contribution
1683 elif self._ttPDFFormat.showContribsAtConfLevel() and \
1684 isinstance(entry,schedule.LinkedTimeSchEntry) and \
1685 isinstance(entry.getOwner(),conference.Contribution):
1686 contrib=entry.getOwner()
1687 if not contrib.canView(self._aw):
1688 continue
1689 room=""
1690 if contrib.getRoom() is not None:
1691 room=" - %s"%escape(contrib.getRoom().getName())
1692 caption="%s"%contrib.getTitle()
1693 spks=[]
1694 for c in contrib.getSpeakerList():
1695 if self._showSpeakerAffiliation and c.getAffiliation().strip() != "":
1696 spks.append("%s (%s)"%(escape(c.getFullName()), escape(c.getAffiliation())))
1697 else:
1698 spks.append(escape(c.getFullName()))
1699 spks="; ".join(spks)
1700 if spks.strip()!="":
1701 spks=i18nformat("""<font name=\"Times-Bold\"><b>- _("Presenters"): %s</b></font>""")%spks
1702 text="""<u>%s</u>%s (%s-%s)"""%(
1703 escape(caption),room,
1704 escape(contrib.getAdjustedStartDate(self._tz).strftime("%H:%M")),
1705 escape(contrib.getAdjustedEndDate(self._tz).strftime("%H:%M")))
1706 p1=Paragraph(text,self._styles["session_title"])
1707 res.append(p1)
1708 if self._ttPDFFormat.showTitleSessionTOC():
1709 self._indexedFlowable[p1]={"text":escape(contrib.getTitle()), "level":2}
1710 p2=Paragraph(spks,self._styles["conveners"])
1711 res.append(p2)
1712 if entry == entriesOnDay[-1]: # if it is the last one, we do the page break and remove the previous one.
1713 i=len(res)-1
1714 while i>=0:
1715 if isinstance(res[i], PageBreak):
1716 del res[i]
1717 break
1718 i-=1
1719 if self._ttPDFFormat.showNewPagePerSession():
1720 res.append(PageBreak())
1721 #break
1722 elif self._ttPDFFormat.showBreaksAtConfLevel() and \
1723 isinstance(entry,schedule.BreakTimeSchEntry):
1724 breakE=entry
1725 room=""
1726 if breakE.getRoom() is not None:
1727 room=" - %s"%escape(breakE.getRoom().getName())
1728 caption="%s"%breakE.getTitle()
1729 text="""<u>%s</u>%s (%s-%s)"""%(
1730 escape(caption),room,
1731 escape(breakE.getAdjustedStartDate(self._tz).strftime("%H:%M")),
1732 escape(breakE.getAdjustedEndDate(self._tz).strftime("%H:%M")))
1733 p1=Paragraph(text,self._styles["session_title"])
1734 res.append(p1)
1735 if self._ttPDFFormat.showTitleSessionTOC():
1736 self._indexedFlowable[p1]={"text":escape(breakE.getTitle()), "level":2}
1737 if entry == entriesOnDay[-1]: # if it is the last one, we do the page break and remove the previous one.
1738 i=len(res)-1
1739 while i>=0:
1740 if isinstance(res[i], PageBreak):
1741 del res[i]
1742 break
1743 i-=1
1744 if self._ttPDFFormat.showNewPagePerSession():
1745 res.append(PageBreak())
1747 return res
1750 def getBody(self,story=None):
1751 self._defineStyles()
1752 if not story:
1753 story=self._story
1754 if not self._ttPDFFormat.showCoverPage():
1755 s = ParagraphStyle({})
1756 s.fontName = "Times-Bold"
1757 s.fontSize = 18
1758 s.leading = 22
1759 s.alignment = TA_CENTER
1760 p=Paragraph(escape(self._conf.getTitle()),s)
1761 story.append(p)
1762 story.append(Spacer(1,0.4*inch))
1764 currentDay=self._conf.getSchedule().getAdjustedStartDate(self._tz)
1765 while currentDay.strftime("%Y-%m-%d")<=self._conf.getSchedule().getAdjustedEndDate(self._tz).strftime("%Y-%m-%d"):
1766 if len(self._showDays)>0 and \
1767 currentDay.strftime("%d-%B-%Y") not in self._showDays:
1768 currentDay+=timedelta(days=1)
1769 continue
1770 dayEntries=self._processDayEntries(currentDay,story)
1771 if len(dayEntries)==0:
1772 currentDay+=timedelta(days=1)
1773 continue
1774 text=escape(currentDay.strftime("%A %d %B %Y"))
1775 p=Paragraph(text,self._styles["day"],part=currentDay.strftime("%A %d %B %Y"))
1776 story.append(p)
1777 self._indexedFlowable[p]={"text":currentDay.strftime("%A %d %B %Y"), "level":1}
1778 for entry in dayEntries:
1779 story.append(entry)
1780 if not self._ttPDFFormat.showNewPagePerSession():
1781 story.append(PageBreak())
1782 currentDay+=timedelta(days=1)
1784 class SimplifiedTimeTablePlain(PDFBase):
1786 def __init__(self,conf,aw,showSessions=[],showDays=[],sortingCrit=None, ttPDFFormat=None, pagesize = 'A4', fontsize = 'normal', tz=None):
1787 self._conf=conf
1788 if not tz:
1789 self._tz = self._conf.getTimezone()
1790 else:
1791 self._tz = tz
1792 self._aw=aw
1793 self._showSessions=showSessions
1794 self._showDays=showDays
1795 PDFBase.__init__(self, story=[], pagesize = pagesize)
1796 self._title= _("Simplified Programme")
1797 self._doc.leftMargin=1*cm
1798 self._doc.rightMargin=1*cm
1799 self._doc.topMargin=1*cm
1800 self._doc.bottomMargin=1*cm
1801 self._sortingCrit=sortingCrit
1802 self._ttPDFFormat = ttPDFFormat or TimetablePDFFormat()
1803 self._fontsize = fontsize
1805 def _defineStyles(self):
1806 self._styles={}
1807 normalStl=getSampleStyleSheet()["Normal"]
1808 normalStl.fontName="Courier"
1809 normalStl.fontSize = modifiedFontSize(10, self._fontsize)
1810 normalStl.spaceBefore=0
1811 normalStl.spaceAfter=0
1812 normalStl.alignment=TA_LEFT
1813 self._styles["normal"]=normalStl
1814 titleStl=getSampleStyleSheet()["Normal"]
1815 titleStl.fontName="Courier-Bold"
1816 titleStl.fontSize = modifiedFontSize(12, self._fontsize)
1817 titleStl.spaceBefore=0
1818 titleStl.spaceAfter=0
1819 titleStl.alignment=TA_LEFT
1820 self._styles["title"]=titleStl
1821 dayStl=getSampleStyleSheet()["Normal"]
1822 dayStl.fontName="Courier-Bold"
1823 dayStl.fontSize = modifiedFontSize(10, self._fontsize)
1824 dayStl.spaceBefore=0
1825 dayStl.spaceAfter=0
1826 dayStl.alignment=TA_LEFT
1827 self._styles["day"]=dayStl
1829 def _haveSessionSlotsTitles(self, session):
1830 """Checks if the session has slots with titles or not"""
1831 for ss in session.getSlotList():
1832 if ss.getTitle().strip() != "":
1833 return True
1834 return False
1836 def _processDayEntries(self,day,story):
1837 lastSessions=[] # this is to avoid checking if the slots have titles for all the slots
1838 res=[]
1839 for entry in self._conf.getSchedule().getEntriesOnDay(day):
1840 if isinstance(entry,schedule.LinkedTimeSchEntry) and \
1841 isinstance(entry.getOwner(),conference.SessionSlot):
1842 sessionSlot=entry.getOwner()
1843 session = sessionSlot.getSession()
1844 if len(self._showSessions)>0 and \
1845 session.getId() not in self._showSessions:
1846 continue
1847 if not sessionSlot.canView(self._aw):
1848 continue
1849 if session in lastSessions:
1850 continue
1851 if self._haveSessionSlotsTitles(session):
1852 e=sessionSlot
1853 else:
1854 lastSessions.append(session)
1855 e=session
1856 title=e.getTitle()
1857 if title.strip()=="":
1858 title=e.getOwner().getTitle()
1859 res.append(Paragraph( i18nformat("""<font name=\"Times-Bold\"><b> _("Session"):</b></font> %s""")%escape(title),self._styles["normal"]))
1860 roomTime=""
1861 if e.getRoom() is not None:
1862 roomTime="%s "%(escape(e.getRoom().getName()))
1863 roomTime= i18nformat("""<font name=\"Times-Bold\"><b> _("Time and Place"):</b></font> %s(%s-%s)""")%(roomTime, e.getAdjustedStartDate(self._tz).strftime("%H:%M"), \
1864 e.getAdjustedEndDate(self._tz).strftime("%H:%M"))
1865 res.append(Paragraph(roomTime,self._styles["normal"]))
1866 chairs=[]
1867 for c in e.getConvenerList():
1868 chairs.append("%s"%c.getFullName())
1869 if chairs != []:
1870 res.append(Paragraph( i18nformat("""<font name=\"Times-Bold\"><b> _("Chair/s"):</b></font> %s""")%("; ".join(chairs)),self._styles["normal"]))
1871 res.append(Spacer(1,0.2*inch))
1872 elif self._ttPDFFormat.showContribsAtConfLevel() and isinstance(entry,schedule.LinkedTimeSchEntry) and \
1873 isinstance(entry.getOwner(),conference.Contribution):
1874 contrib=entry.getOwner()
1875 if not contrib.canView(self._aw):
1876 continue
1877 title=contrib.getTitle()
1878 if title.strip()=="":
1879 title=e.getOwner().getTitle()
1880 res.append(Paragraph( i18nformat("""<font name=\"Times-Bold\"><b> _("Contribution"):</b></font> %s""")%escape(title),self._styles["normal"]))
1881 roomTime=""
1882 if contrib.getRoom() is not None:
1883 roomTime="%s "%(escape(contrib.getRoom().getName()))
1884 roomTime= i18nformat("""<font name=\"Times-Bold\"><b> _("Time and Place"):</b></font> %s(%s-%s)""")%(roomTime, contrib.getAdjustedStartDate(self._tz).strftime("%H:%M"), \
1885 contrib.getAdjustedEndDate(self._tz).strftime("%H:%M"))
1886 res.append(Paragraph(roomTime,self._styles["normal"]))
1887 spks=[]
1888 for c in contrib.getSpeakerList():
1889 spks.append("%s"%c.getFullName())
1890 if spks != []:
1891 res.append(Paragraph( i18nformat("""<font name=\"Times-Bold\"><b> _("Presenter/s"):</b></font> %s""")%("; ".join(spks)),self._styles["normal"]))
1892 res.append(Spacer(1,0.2*inch))
1893 elif self._ttPDFFormat.showBreaksAtConfLevel() and isinstance(entry,schedule.BreakTimeSchEntry):
1894 title=entry.getTitle()
1895 if title.strip()=="":
1896 title=e.getOwner().getTitle()
1897 res.append(Paragraph( i18nformat("""<font name=\"Times-Bold\"><b> _("Break"):</b></font> %s""")%escape(title),self._styles["normal"]))
1898 roomTime=""
1899 if entry.getRoom() is not None:
1900 roomTime="%s "%(escape(entry.getRoom().getName()))
1901 roomTime= i18nformat("""<font name=\"Times-Bold\"><b> _("Time and Place"):</b></font> %s(%s-%s)""")%(roomTime, entry.getAdjustedStartDate(self._tz).strftime("%H:%M"), \
1902 entry.getAdjustedEndDate(self._tz).strftime("%H:%M"))
1903 res.append(Paragraph(roomTime,self._styles["normal"]))
1904 res.append(Spacer(1,0.2*inch))
1905 res.append(PageBreak())
1906 return res
1908 def getBody(self,story=None):
1909 self._defineStyles()
1910 if not story:
1911 story=self._story
1912 currentDay=self._conf.getSchedule().getAdjustedStartDate(self._tz)
1913 while currentDay.strftime("%Y-%m-%d")<=self._conf.getSchedule().getAdjustedEndDate(self._tz).strftime("%Y-%m-%d"):
1914 if len(self._showDays)>0 and \
1915 currentDay.strftime("%d-%B-%Y") not in self._showDays:
1916 currentDay+=timedelta(days=1)
1917 continue
1918 dayEntries=self._processDayEntries(currentDay,story)
1919 if len(dayEntries)==0:
1920 currentDay+=timedelta(days=1)
1921 continue
1922 if self._conf.getAdjustedEndDate(self._tz).month != self._conf.getAdjustedEndDate(self._tz).month:
1923 text="%s - %s-%s"%(escape(self._conf.getTitle()), escape(self._conf.getAdjustedStartDate(self._tz).strftime("%d %B %Y")), \
1924 escape(self._conf.getAdjustedEndDate(self._tz).strftime("%d %B %Y")) )
1925 else:
1926 text="%s - %s-%s"%(escape(self._conf.getTitle()), escape(self._conf.getAdjustedStartDate(self._tz).strftime("%d")), \
1927 escape(self._conf.getAdjustedEndDate(self._tz).strftime("%d %B %Y")) )
1928 if self._conf.getLocation() is not None:
1929 text="%s, %s."%(text, self._conf.getLocation().getName())
1930 text="%s"%text
1931 p=Paragraph(text, self._styles["title"])
1932 story.append(p)
1933 text2= i18nformat(""" _("Daily Programme"): %s""")%escape(currentDay.strftime("%A %d %B %Y"))
1934 p2=Paragraph(text2,self._styles["day"])
1935 story.append(p2)
1936 story.append(Spacer(1,0.4*inch))
1937 for entry in dayEntries:
1938 story.append(entry)
1939 currentDay+=timedelta(days=1)
1941 class AbstractBook(PDFWithTOC):
1943 def __init__(self,conf,aw,tz=None):
1944 self._conf=conf
1945 if not tz:
1946 self._tz = self._conf.getTimezone()
1947 else:
1948 self._tz = tz
1949 self._aw=aw
1950 self._sortBy=self._conf.getBOAConfig().getSortBy()
1951 if self._sortBy.strip()=="" or\
1952 self._sortBy not in ["number", "name", "sessionTitle", "speaker", "schedule"]:
1953 self._sortBy="number"
1954 self._title= _("Book of abstracts")
1955 PDFWithTOC.__init__(self)
1957 def firstPage(self,c,doc):
1958 c.saveState()
1959 self._drawLogo(c, False)
1960 height=self._drawWrappedString(c,self._conf.getTitle())
1961 c.setFont('Times-Bold',15)
1962 height-=2*cm
1963 c.drawCentredString(self._PAGE_WIDTH/2.0,height,
1964 "%s - %s"%(self._conf.getAdjustedStartDate(self._tz).strftime("%A %d %B %Y"),
1965 self._conf.getAdjustedEndDate(self._tz).strftime("%A %d %B %Y")))
1966 if self._conf.getLocation():
1967 height-=1*cm
1968 c.drawCentredString(self._PAGE_WIDTH/2.0,height,
1969 escape(self._conf.getLocation().getName()))
1970 c.setFont('Times-Bold', 30)
1971 height-=6*cm
1972 c.drawCentredString(self._PAGE_WIDTH/2.0,height,\
1973 self._title)
1974 self._drawWrappedString(c, "%s / %s"%(self._conf.getTitle(),self._title), width=inch, height=0.75*inch, font='Times-Roman', size=9, color=(0.5,0.5,0.5), align="left", maximumWidth=self._PAGE_WIDTH-3.5*inch, measurement=inch, lineSpacing=0.15)
1975 c.drawRightString(self._PAGE_WIDTH-inch,0.75*inch,
1976 nowutc().strftime("%A %d %B %Y"))
1977 c.restoreState()
1979 def laterPages(self,c,doc):
1980 c.saveState()
1981 c.setFont('Times-Roman',9)
1982 c.setFillColorRGB(0.5,0.5,0.5)
1983 c.drawString(1*cm,self._PAGE_HEIGHT-1*cm,
1984 "%s / %s"%(escape(self._conf.getTitle()),self._title))
1985 c.drawCentredString(self._PAGE_WIDTH/2.0,0.5*cm,"%d "%doc.page)
1986 c.restoreState()
1988 def _defineStyles(self):
1989 self._styles={}
1990 titleStyle=getSampleStyleSheet()["Heading1"]
1991 titleStyle.fontName="LinuxLibertine-Bold"
1992 titleStyle.fontSize=14.0
1993 titleStyle.spaceBefore=0
1994 titleStyle.spaceAfter=10
1995 titleStyle.leading=14
1996 self._styles["title"]=titleStyle
1997 subtitleStyle=getSampleStyleSheet()["Heading1"]
1998 subtitleStyle.fontName="LinuxLibertine-Bold"
1999 subtitleStyle.fontSize=11.0
2000 subtitleStyle.spaceBefore=0
2001 subtitleStyle.spaceAfter=4
2002 subtitleStyle.leading=14
2003 self._styles["subtitle"]=subtitleStyle
2004 authStyle=getSampleStyleSheet()["Heading3"]
2005 authStyle.fontName="LinuxLibertine"
2006 authStyle.fontSize=8.0
2007 authStyle.spaceBefore=0
2008 authStyle.spaceAfter=0
2009 authStyle.leading=14
2010 self._styles["authors"]=authStyle
2011 abstractStyle=getSampleStyleSheet()["Normal"]
2012 abstractStyle.fontName="LinuxLibertine"
2013 abstractStyle.fontSize=10.0
2014 abstractStyle.spaceBefore=0
2015 abstractStyle.spaceAfter=0
2016 abstractStyle.alignment=TA_JUSTIFY
2017 self._styles["abstract"]=abstractStyle
2018 ttInfoStyle=getSampleStyleSheet()["Normal"]
2019 ttInfoStyle.fontName="LinuxLibertine"
2020 ttInfoStyle.fontSize=10.0
2021 ttInfoStyle.spaceBefore=0
2022 ttInfoStyle.spaceAfter=0
2023 ttInfoStyle.alignment=TA_JUSTIFY
2024 self._styles["tt_info"]=ttInfoStyle
2025 normalStyle=getSampleStyleSheet()["Normal"]
2026 normalStyle.fontName="LinuxLibertine"
2027 normalStyle.fontSize=10.0
2028 normalStyle.spaceBefore=5
2029 normalStyle.spaceAfter=5
2030 normalStyle.alignment=TA_JUSTIFY
2031 self._styles["normal"]=normalStyle
2033 def _addContribution(self, contrib, story):
2034 if not contrib.canAccess(self._aw):
2035 return
2036 paragraphs=[]
2037 ses=""
2038 if contrib.getSession() is not None:
2039 ses=contrib.getSession().getTitle()
2040 if contrib.getBoardNumber():
2041 if ses != "":
2042 ses = "%s - "%ses
2043 ses="%sBoard %s"%(ses, contrib.getBoardNumber())
2044 if ses!="":
2045 ses = "%s / "%ses
2047 caption = "%s%s"%(ses,contrib.getId())
2048 paragraphs.append(Paragraph(escape(caption),self._styles["subtitle"]))
2049 caption="%s"%(contrib.getTitle())
2050 p = Paragraph(escape(caption),self._styles["title"])
2051 paragraphs.append(p)
2052 flowableText = escape(contrib.getTitle())
2053 if self._conf.getBOAConfig().getShowIds():
2054 flowableText += """ (%s)"""%contrib.getId()
2055 self._indexedFlowable[p] = {"text":escape(flowableText), "level":1}
2057 lauth=[]
2058 institutions=[]
2059 for auth in contrib.getAuthorList():
2060 fullName=auth.getFullName()
2061 instit=auth.getAffiliation().strip()
2062 if instit!="":
2063 try:
2064 indexInsti = institutions.index(instit) + 1
2065 except:
2066 institutions.append(instit)
2067 indexInsti = len(institutions)
2068 fullName="%s <sup>%s</sup>"%(fullName,indexInsti)
2069 lauth.append("%s"%escape(fullName))
2070 authors= "; ".join(lauth)
2071 paragraphs.append(Paragraph(authors,self._styles["authors"]))
2072 if institutions:
2073 linst=[]
2074 for instit in institutions:
2075 linst.append("<sup>%s</sup> <i>%s</i>"%(institutions.index(instit)+1, instit))
2076 institutionsText="<br/>".join(linst)
2077 paragraphs.append(Paragraph(institutionsText,self._styles["authors"]))
2079 submitterEmail=""
2080 if isinstance(contrib, conference.AcceptedContribution):
2081 submitterEmail=contrib.getAbstract().getSubmitter().getEmail()
2082 elif contrib.getSubmitterList():
2083 submitterEmail=contrib.getSubmitterList()[0].getEmail()
2085 if submitterEmail!="":
2086 submitter = i18nformat("""<b>_("Corresponding Author"):</b> %s""")%submitterEmail
2087 paragraphs.append(Paragraph(escape(submitter),self._styles["normal"]))
2089 abstract=contrib.getDescription()
2090 paragraphs.append(Paragraph(escape(abstract),self._styles["abstract"]))
2092 abs=KeepTogether(paragraphs)
2093 story.append(abs)
2094 story.append(Spacer(1,0.4*inch))
2096 def getBody(self,story=None):
2097 self._defineStyles()
2098 if not story:
2099 story=self._story
2100 if self._conf.getBOAConfig().getText():
2101 text=self._conf.getBOAConfig().getText().replace("<BR>","<br>")
2102 text=text.replace("<Br>","<br>")
2103 text=text.replace("<bR>","<br>")
2104 for par in text.split("<br>"):
2105 p=Paragraph(par,self._styles["normal"])
2106 story.append(p)
2107 story.append(PageBreak())
2108 if self._sortBy == "schedule":
2109 for entry in self._conf.getSchedule().getEntries():
2110 if isinstance(entry,schedule.LinkedTimeSchEntry) and isinstance(entry.getOwner(),conference.SessionSlot):
2111 if entry.getOwner().canAccess(self._aw):
2112 for slotentry in entry.getOwner().getSchedule().getEntries():
2113 if isinstance(slotentry.getOwner(), conference.Contribution):
2114 self._addContribution(slotentry.getOwner(), story)
2115 elif isinstance(entry,schedule.LinkedTimeSchEntry) and isinstance(entry.getOwner(),conference.Contribution):
2116 self._addContribution(entry.getOwner(), story)
2117 else:
2118 fc=FilterCriteria(self._conf,{"status":[ContribStatusList.getId(conference.ContribStatusSch),ContribStatusList.getId(conference.ContribStatusNotSch)]})
2119 sc=contribFilters.SortingCriteria((self._sortBy,))
2120 f=filters.SimpleFilter(fc,sc)
2121 for contrib in f.apply(self._conf.getContributionList()):
2122 self._addContribution(contrib, story)
2125 class FilterCriteria(filters.FilterCriteria):
2126 _availableFields = {
2127 contribFilters.StatusFilterField.getId():contribFilters.StatusFilterField
2130 class ProceedingsTOC(PDFBase):
2132 def __init__(self, conf, trackDict=None, trackOrder=None, contribList=None, npages=None, doc=None, story=None, tz=None):
2133 self._conf = conf
2134 if not tz:
2135 self._tz = self._conf.getTimezone()
2136 else:
2137 self._tz = tz
2138 self._trackDict = trackDict
2139 self._trackOrder = trackOrder
2140 self._contribDictNPages = npages
2141 self._contribList=contribList
2142 if not story:
2143 story = [Spacer(inch, 5*cm)]
2144 PDFBase.__init__(self, doc, story)
2145 self._title = _("Proceedings")
2146 self._PAGE_HEIGHT = defaultPageSize[1]
2147 self._PAGE_WIDTH = defaultPageSize[0]
2149 def firstPage(self,c,doc):
2150 c.saveState()
2151 self._drawLogo(c, False)
2152 height=self._drawWrappedString(c, self._conf.getTitle())
2153 c.setFont('Times-Bold',15)
2154 height-=2*cm
2155 c.drawCentredString(self._PAGE_WIDTH/2.0,height,
2156 "%s - %s"%(self._conf.getAdjustedStartDate(self._tz).strftime("%A %d %B %Y"),
2157 self._conf.getAdjustedEndDate(self._tz).strftime("%A %d %B %Y")))
2158 if self._conf.getLocation():
2159 height-=1*cm
2160 c.drawCentredString(self._PAGE_WIDTH/2.0,height,escape(self._conf.getLocation().getName()))
2161 c.setFont('Times-Bold', 30)
2162 height-=6*cm
2163 c.drawCentredString(self._PAGE_WIDTH/2.0,height,self._title)
2164 c.setFont('Times-Roman',9)
2165 c.setFillColorRGB(0.5,0.5,0.5)
2166 c.restoreState()
2168 def laterPages(self,c,doc):
2169 c.saveState()
2170 location = ""
2171 if self._conf.getLocation() is not None and self._conf.getLocation().getName().strip() != "":
2172 location = " - %s"%(escape(self._conf.getLocation().getName()))
2173 self._drawWrappedString(c, "%s%s"%(escape(self._conf.getTitle()), location), width=0.5*inch, height=self._PAGE_HEIGHT-0.75*inch, font='Times-Roman', size=9, color=(0.5,0.5,0.5), align="left", maximumWidth=self._PAGE_WIDTH-inch, measurement=inch, lineSpacing=0.15)
2174 c.drawCentredString(self._PAGE_WIDTH/2.0,0.5*cm,"%s "%Int2Romans.int_to_roman(doc.page-1))
2175 c.restoreState()
2177 def getBody(self, story=None, indexedFlowable={}, level=1 ):
2178 if not story:
2179 story = self._story
2180 self._story.append(PageBreak())
2181 style = ParagraphStyle({})
2182 style.fontName = "Times-Bold"
2183 style.fontSize = 20
2184 style.spaceBefore=0
2185 style.spaceAfter=8
2186 style.leading=14
2187 style.alignment=TA_LEFT
2188 text = _("Table of Contents")
2189 p = Paragraph(text, style)
2190 story.append(p)
2192 story.append(Spacer(inch, 0.5*cm))
2194 styleAuthor = ParagraphStyle({})
2195 styleAuthor.leading = 10
2196 styleAuthor.fontName = "Times-Roman"
2197 styleAuthor.fontSize = 8
2198 styleAuthor.spaceBefore=0
2199 styleAuthor.spaceAfter=0
2200 styleAuthor.alignment=TA_LEFT
2201 styleAuthor.leftIndent=10
2202 styleAuthor.firstLineIndent=0
2204 styleContrib = ParagraphStyle({})
2205 styleContrib.leading = 12
2206 styleContrib.fontName = "Times-Roman"
2207 styleContrib.fontSize = 10
2208 styleContrib.spaceBefore=0
2209 styleContrib.spaceAfter=0
2210 styleContrib.alignment=TA_LEFT
2211 styleContrib.leftIndent=0
2212 styleContrib.firstLineIndent=0
2213 styleContrib.leftIndent=0
2215 styleTrack = ParagraphStyle({})
2216 styleTrack.fontName = "Times-Bold"
2217 styleTrack.fontSize = 12
2218 styleTrack.spaceBefore=40
2219 styleTrack.spaceAfter=30
2220 styleTrack.alignment=TA_LEFT
2222 tsContribs=TableStyle([('VALIGN',(0,0),(-1,0),"BOTTOM"),
2223 ('VALIGN',(0,0),(-1,-1),"BOTTOM"),
2224 ('ALIGN',(0,1),(-1,1),"RIGHT"),
2225 ('BOTTOMPADDING',(0,0),(-1,-1),0),
2226 ('TOPPADDING',(0,0),(-1,-1),0)])
2227 i = 1
2228 if self._trackOrder is not None and self._trackOrder!=[]:
2229 for track in self._trackOrder:
2230 l=[]
2231 p=Paragraph("",styleTrack)
2232 p2=Paragraph("",styleTrack)
2233 l.append([p, p2])
2234 p=Paragraph(escape(track.getTitle()),styleTrack)
2235 p2=Paragraph("<b>%s</b>"%escape("%s"%i),styleTrack)
2236 i += 2
2237 l.append([p, p2])
2238 p=Paragraph("",styleTrack)
2239 p2=Paragraph("",styleTrack)
2240 l.append([p, p2])
2241 l.append(["", ""])
2242 for contrib in self._trackDict[track.getId()]:
2243 i=self._addContrib(contrib, l, i, styleContrib, styleAuthor )
2244 l.append(["", ""])
2245 t=Table(l,colWidths=(None,1.2*cm),style=tsContribs)
2246 self._story.append(t)
2247 else:
2248 l=[]
2249 for contrib in self._contribList:
2250 i=self._addContrib(contrib, l, i, styleContrib, styleAuthor)
2251 if l!=[]:
2252 t=Table(l,colWidths=(None,1.2*cm),style=tsContribs)
2253 self._story.append(t)
2254 self._story.append(Spacer(inch, 2*cm))
2256 return story
2258 def _addContrib(self, contrib, l, i, styleContrib, styleAuthor):
2259 authorList = []
2260 for author in contrib.getPrimaryAuthorList():
2261 authorList.append(self._getAbrName(author))
2262 for author in contrib.getCoAuthorList():
2263 authorList.append(self._getAbrName(author))
2264 if authorList == []:
2265 for author in contrib.getSpeakerList():
2266 authorList.append(self._getAbrName(author))
2267 p=Paragraph(escape(contrib.getTitle()), styleContrib)
2268 p2=Paragraph("""<i>%s</i>"""%(escape(", ".join(authorList))), styleAuthor)
2269 p3=Paragraph("""<font size="10">%s</font>"""%escape("%s"%i),styleAuthor)
2270 i += self._contribDictNPages[contrib.getId()]
2271 l.append([p, ""])
2272 l.append([p2, p3])
2273 l.append(["", ""])
2274 return i
2276 def _getAbrName(self, author):
2277 res = author.getFamilyName()
2278 if res.strip() != "" and len(res)>1:
2279 res = "%s%s"%(res[0].upper(), res[1:].lower())
2280 if author.getFirstName() != "":
2281 if res == "":
2282 res = author.getFirstName()
2283 else:
2284 res = "%s. %s"%(author.getFirstName()[0].upper(), res)
2285 return res
2287 class ProceedingsChapterSeparator(PDFBase):
2289 def __init__(self, track, doc=None, story=None):
2290 self._track = track
2291 self._conf = track.getConference()
2292 if not story:
2293 story = [Spacer(inch, 5*cm)]
2294 PDFBase.__init__(self, doc, story)
2295 self._title = _("Proceedings")
2296 self._PAGE_HEIGHT = defaultPageSize[1]
2297 self._PAGE_WIDTH = defaultPageSize[0]
2299 def firstPage(self,c,doc):
2300 c.saveState()
2301 c.setFont('Times-Roman',9)
2302 c.setFillColorRGB(0.5,0.5,0.5)
2303 #c.drawString(1*cm,self._PAGE_HEIGHT-1*cm,
2304 # "%s / %s"%(escape(self._conf.getTitle()),self._title))
2305 #c.drawCentredString(self._PAGE_WIDTH/2.0,0.5*cm,"Page %d "%doc.page)
2306 self._drawWrappedString(c, self._track.getTitle())
2307 c.setFont('Times-Roman',9)
2308 c.setFillColorRGB(0.5,0.5,0.5)
2309 c.restoreState()
2311 def laterPages(self,c,doc):
2312 c.saveState()
2313 c.setFont('Times-Roman',9)
2314 c.setFillColorRGB(0.5,0.5,0.5)
2315 #c.drawString(1*cm,self._PAGE_HEIGHT-1*cm,
2316 # "%s / %s"%(escape(self._conf.getTitle()),self._title))
2317 #c.drawCentredString(self._PAGE_WIDTH/2.0,0.5*cm,"Page %d "%doc.page)
2318 c.restoreState()
2320 def getBody(self, story=None, indexedFlowable={}, level=1 ):
2321 if not story:
2322 story = self._story
2323 self._story.append(PageBreak())
2324 self._story.append(PageBreak())
2325 return story
2327 class RegistrantToPDF(PDFBase):
2329 def __init__(self, conf, reg, display, doc=None, story=None):
2330 self._reg = reg
2331 self._conf = conf
2332 self._display = display
2333 if not story:
2334 story = [Spacer(inch, 5*cm)]
2335 PDFBase.__init__(self, doc, story)
2336 self._title = _("Registrant")
2337 self._PAGE_HEIGHT = defaultPageSize[1]
2338 self._PAGE_WIDTH = defaultPageSize[0]
2340 def firstPage(self, c, doc):
2341 c.saveState()
2342 c.setFont('Times-Bold', 30)
2343 if not self._drawLogo(c):
2344 self._drawWrappedString(c, escape(self._conf.getTitle()), height=self._PAGE_HEIGHT - 2*inch)
2345 c.setFont('Times-Bold', 25)
2346 #c.drawCentredString(self._PAGE_WIDTH/2, self._PAGE_HEIGHT - inch - 5*cm, self._abstract.getTitle())
2347 c.setLineWidth(3)
2348 c.setStrokeGray(0.7)
2349 #c.line(inch, self._PAGE_HEIGHT - inch - 6*cm, self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - inch - 6*cm)
2350 #c.line(inch, inch , self._PAGE_WIDTH - inch, inch)
2351 c.setFont('Times-Roman', 10)
2352 #c.drawString(0.5*inch, 0.5*inch, Config.getInstance().getBaseURL())
2353 c.restoreState()
2355 def getBody(self, story=None, indexedFlowable={}, level=1 ):
2356 if not story:
2357 story = self._story
2359 style = ParagraphStyle({})
2360 style.fontSize = 12
2361 text = i18nformat(""" _("Registrant ID") : %s""")%self._reg.getId()
2362 p = Paragraph(text, style, part=escape(self._reg.getFullName()))
2363 story.append(p)
2365 story.append(Spacer(inch, 0.5*cm, part=escape(self._reg.getFullName())))
2367 style = ParagraphStyle({})
2368 style.alignment = TA_CENTER
2369 style.fontSize = 25
2370 style.leading = 30
2371 text = escape(self._reg.getFullName())
2372 p = Paragraph(text, style, part=escape(self._reg.getFullName()))
2373 story.append(p)
2375 indexedFlowable[p] = {"text":escape(self._reg.getFullName()), "level":1}
2376 story.append(Spacer(inch, 1*cm, part=escape(self._reg.getFullName())))
2377 style = ParagraphStyle({})
2378 style.alignment = TA_JUSTIFY
2379 for key in self._display:
2380 text = ""
2381 if key == "Email" and self._reg.getEmail() <> "":
2382 text = i18nformat("""<b> _("Email") </b> : %s""")%escape(self._reg.getEmail())
2383 elif key == "Position" and self._reg.getPosition() <> "":
2384 text = i18nformat("""<b> _("Position") </b> : %s""")%escape(self._reg.getPosition())
2385 elif key == "LastName" and self._reg.getFamilyName() <> "":
2386 text = i18nformat("""<b> _("Surname") </b> : %s""")%escape(self._reg.getFamilyName())
2387 elif key == "FirstName" and self._reg.getFirstName() <> "":
2388 text = i18nformat("""<b> _("First Name") </b> : %s""")%escape(self._reg.getFirstName())
2389 elif key == "Institution" and self._reg.getInstitution() <> "":
2390 text = i18nformat("""<b> _("Institution") </b> : %s""")%escape(self._reg.getInstitution())
2391 elif key == "Address" and self._reg.getAddress() <> "":
2392 text = i18nformat("""<b> _("Address") </b> : %s""")%escape(self._reg.getAddress())
2393 elif key == "City" and self._reg.getCity() <> "":
2394 text = i18nformat("""<b> _("City") </b> : %s""")%escape(self._reg.getCity())
2395 elif key == "Country" and self._reg.getCountry() <> "":
2396 text = i18nformat("""<b> _("Country") </b> : %s""")%escape(CountryHolder().getCountryById(self._reg.getCountry()))
2397 elif key == "Phone" and self._reg.getPhone() <> "":
2398 text = i18nformat("""<b> _("Phone") </b> : %s""")%escape(self._reg.getPhone())
2399 elif key == "isPayed" and self._reg.isPayedText() <> "":
2400 text = i18nformat("""<b> _("Paid") </b> : %s""")%escape(self._reg.isPayedText())
2401 elif key == "idpayment" and self._reg.getIdPay() <> "":
2402 text = i18nformat("""<b> _("idpayment") </b> : %s""")%escape(self._reg.getIdPay())
2403 elif key == "amountToPay":
2404 text = i18nformat("""<b> _("Amount") </b> : %.2f %s""")%(self._reg.getTotal(), escape(self._reg.getConference().getRegistrationForm().getCurrency()))
2405 elif key == "Sessions":
2406 listSession = []
2407 for ses in self._reg.getSessionList():
2408 if ses is not None:
2409 listSession.append("%s"%escape(ses.getTitle()))
2410 if len(listSession) > 0:
2411 text = i18nformat("""<b> _("Sessions")</b> : """)
2412 text += " ; ".join(listSession)
2413 elif key == "SocialEvents":
2414 listSocialEvents = []
2415 for se in self._reg.getSocialEvents():
2416 if se is not None:
2417 listSocialEvents.append("%s"%escape(se.getCaption()))
2418 if len(listSocialEvents) > 0:
2419 text = i18nformat("""<b> _("Social Events")</b> : """)
2420 text += " ; ".join(listSocialEvents)
2421 elif key == "Accommodation" and self._reg.getAccommodation() is not None and \
2422 self._reg.getAccommodation().getAccommodationType() is not None:
2423 text = i18nformat("""<b> _("Acommodation")</b> : %s""")%escape(self._reg.getAccommodation().getAccommodationType().getCaption())
2424 elif key == "ArrivalDate" and self._reg.getAccommodation() is not None and \
2425 self._reg.getAccommodation().getArrivalDate() is not None:
2426 text = i18nformat("""<b> _("Arrival Date")</b> : %s""")%escape(self._reg.getAccommodation().getArrivalDate().strftime("%d-%B-%Y"))
2427 elif key == "DepartureDate" and self._reg.getAccommodation() is not None and \
2428 self._reg.getAccommodation().getDepartureDate() is not None:
2429 text = i18nformat("""<b> _("Departure Date")</b> : %s""")%escape(self._reg.getAccommodation().getDepartureDate().strftime("%d-%B-%Y"))
2430 elif key == "ReasonParticipation" and self._reg.getReasonParticipation() is not None and \
2431 self._reg.getReasonParticipation() is not None and self._reg.getReasonParticipation() != "":
2432 text = i18nformat("""<b> _("Reason Participation") </b> : %s""")%escape(self._reg.getReasonParticipation())
2433 elif key == "RegistrationDate" and self._reg.getRegistrationDate() is not None:
2434 text = i18nformat("""<b> _("Registration date") </b> : %s""")%escape(self._reg.getAdjustedRegistrationDate().strftime("%d-%B-%Y-%H:%M"))
2436 elif key.startswith("s-"):
2437 ids = key.split("-")
2438 if len(ids) == 2:
2439 status = self._reg.getStatusById(ids[1])
2440 if status.getStatusValue() is not None:
2441 text = _("""<b> %s </b> : %s""")%(escape(status.getCaption()),escape(status.getStatusValue().getCaption()))
2442 else:
2443 ids = key.split("-")
2444 if len(ids) == 2:
2445 group = self._reg.getMiscellaneousGroupById(ids[0])
2446 if group is not None:
2447 field = self._conf.getRegistrationForm().getSectionById(ids[0]).getFieldById(ids[1])
2448 response = group.getResponseItemById(ids[1])
2449 if response is not None and response.getValue() != "":
2450 text = _("""<b> %s </b> : %s""")%(escape(field.getCaption()),escape(str(response.getValue())))
2451 if text != "":
2452 p = Paragraph(text, style, part=escape(self._reg.getFullName()))
2453 story.append(p)
2454 story.append(Spacer(inch, 0.2*cm, part=escape(self._reg.getFullName())))
2455 return story
2457 class RegistrantsListToBookPDF(PDFWithTOC):
2458 def __init__(self, conf,doc=None, story=[],list=None, display=["Institution", "Phone", "City", "Country"]):
2459 self._conf = conf
2460 self._regForm = conf.getRegistrationForm()
2461 self._regList = list
2462 self._display = display
2463 self._title = _("Registrants Book")
2464 PDFWithTOC.__init__(self)
2466 def firstPage(self, c, doc):
2467 c.saveState()
2468 showLogo = False
2469 c.setFont('Times-Bold', 30)
2470 if not self._drawLogo(c):
2471 self._drawWrappedString(c, escape(self._conf.getTitle()), height=self._PAGE_HEIGHT - 2*inch)
2472 c.setFont('Times-Bold', 35)
2473 c.drawCentredString(self._PAGE_WIDTH/2, self._PAGE_HEIGHT/2, self._title)
2474 c.setLineWidth(3)
2475 c.setStrokeGray(0.7)
2476 #c.line(inch, self._PAGE_HEIGHT - inch - 6*cm, self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - inch - 6*cm)
2477 #c.line(inch, inch , self._PAGE_WIDTH - inch, inch)
2478 c.setFont('Times-Roman', 10)
2479 c.drawString(0.5*inch, 0.5*inch, str(urlHandlers.UHConferenceDisplay.getURL(self._conf)))
2480 c.restoreState()
2482 def laterPages(self, c, doc):
2484 c.saveState()
2485 c.setFont('Times-Roman', 9)
2486 c.setFillColorRGB(0.5, 0.5, 0.5)
2487 confTitle = escape(self._conf.getTitle())
2488 if len(self._conf.getTitle())>30:
2489 confTitle = escape(self._conf.getTitle()[:30] + "...")
2490 c.drawString(inch, self._PAGE_HEIGHT - 0.75 * inch, "%s / %s"%(confTitle, self._title))
2491 title = doc.getCurrentPart()
2492 if len(doc.getCurrentPart())>50:
2493 title = utils.unicodeSlice(doc.getCurrentPart(), 0, 50) + "..."
2494 c.drawRightString(self._PAGE_WIDTH - inch, self._PAGE_HEIGHT - 0.75 * inch, "%s"%title)
2495 c.drawRightString(self._PAGE_WIDTH - inch, 0.75 * inch, i18nformat(""" _("Page") %d """)%doc.page)
2496 c.drawString(inch, 0.75 * inch, nowutc().strftime("%A %d %B %Y"))
2497 c.restoreState()
2500 def getBody(self):
2501 for reg in self._regList:
2502 temp = RegistrantToPDF(self._conf, reg, self._display)
2503 temp.getBody(self._story, indexedFlowable=self._indexedFlowable, level=1)
2504 self._story.append(PageBreak())
2507 class RegistrantsListToPDF(PDFBase):
2509 def __init__(self, conf,doc=None, story=[],list=None, display=["Institution", "Phone", "City", "Country"]):
2510 self._conf = conf
2511 self._regForm = conf.getRegistrationForm()
2512 self._regList = list
2513 self._display = display
2514 PDFBase.__init__(self, doc, story, printLandscape=True)
2515 self._title = _("Registrants List")
2516 self._PAGE_HEIGHT = landscape(A4)[1]
2517 self._PAGE_WIDTH = landscape(A4)[0]
2519 def firstPage(self, c, doc):
2520 c.saveState()
2521 showLogo = False
2522 c.setFont('Times-Bold', 30)
2523 if not showLogo:
2524 self._drawWrappedString(c, escape(self._conf.getTitle()), height=self._PAGE_HEIGHT-0.75*inch)
2525 c.setFont('Times-Bold', 25)
2526 c.setLineWidth(3)
2527 c.setStrokeGray(0.7)
2528 c.setFont('Times-Roman', 10)
2529 c.drawRightString(self._PAGE_WIDTH - inch,self._PAGE_HEIGHT-1*cm, "%s"%(nowutc().strftime("%d %B %Y, %H:%M")))
2530 c.restoreState()
2532 def getBody(self, story=None, indexedFlowable={}, level=1 ):
2533 if not story:
2534 story = self._story
2536 style = ParagraphStyle({})
2537 style.fontSize = 12
2538 style.alignment = TA_CENTER
2539 text = i18nformat("""<b>_("List of registrants")</b>""")
2540 p = Paragraph(text, style, part=escape(self._conf.getTitle()))
2541 p.spaceAfter = 30
2542 story.append(p)
2544 styleRegistrant = ParagraphStyle({})
2545 styleRegistrant.leading = 10
2546 styleRegistrant.fontName = "Times-Roman"
2547 styleRegistrant.fontSize = 8
2548 styleRegistrant.spaceBefore=0
2549 styleRegistrant.spaceAfter=0
2550 styleRegistrant.alignment=TA_LEFT
2551 styleRegistrant.leftIndent=10
2552 styleRegistrant.firstLineIndent=0
2554 tsRegs=TableStyle([('VALIGN',(0,0),(-1,-1),"MIDDLE"),
2555 ('LINEBELOW',(0,0),(-1,0), 1, colors.black),
2556 ('ALIGN',(0,0),(-1,0),"CENTER"),
2557 ('ALIGN',(0,1),(-1,-1),"LEFT") ] )
2558 l = []
2559 lp = []
2560 lp.append(Paragraph( i18nformat("""<b> _("Name")</b>"""), styleRegistrant))
2562 for key in self._display:
2563 if key in ["Email", "Position", "LastName", "FirstName", "Institution", "Phone", "City", "Country", "Address", "RegistrationDate"]:
2564 p=Paragraph("""<b>%s</b>"""%key, styleRegistrant)
2565 elif key=="Accommodation":
2566 p=Paragraph("""<b>%s</b>"""%escape(self._regForm.getAccommodationForm().getTitle()), styleRegistrant)
2567 elif key == "SocialEvents":
2568 p=Paragraph("""<b>%s</b>"""%escape(self._regForm.getSocialEventForm().getTitle()), styleRegistrant)
2569 elif key == "Sessions":
2570 p=Paragraph("""<b>%s</b>"""%escape(self._regForm.getSessionsForm().getTitle()), styleRegistrant)
2571 elif key=="ArrivalDate":
2572 p=Paragraph( i18nformat("""<b> _("Arrival Date")</b>"""), styleRegistrant)
2573 elif key=="DepartureDate":
2574 p=Paragraph( i18nformat("""<b> _("Departure Date")</b>"""), styleRegistrant)
2575 elif key == "ReasonParticipation":
2576 p=Paragraph("""<b>%s</b>"""%escape(self._regForm.getReasonParticipationForm().getTitle()), styleRegistrant)
2577 elif key == "isPayed":
2578 p=Paragraph("""<b>Paid</b>""", styleRegistrant)
2579 elif key == "idpayment":
2580 p=Paragraph("""<b>Payment ID</b>""", styleRegistrant)
2581 elif key == "amountToPay":
2582 p=Paragraph("""<b>Amount</b>""", styleRegistrant)
2583 elif key.startswith("s-"):
2584 ids=key.split("-")
2585 if len(ids)==2:
2586 status=self._regForm.getStatusById(ids[1])
2587 p=Paragraph("""<b>%s</b>"""%escape(status.getCaption()), styleRegistrant)
2588 else:
2589 p=Paragraph("", styleRegistrant)
2590 else:
2591 ids=key.split("-")
2592 if len(ids)==2:
2593 group=self._regForm.getSectionById(ids[0])
2594 if group is not None:
2595 i=group.getFieldById(ids[1])
2596 if i is not None:
2597 p=Paragraph("""<b>%s</b>"""%escape(i.getCaption()), styleRegistrant)
2598 lp.append(p)
2599 l.append(lp)
2601 if self._regList == None:
2602 self._regList = self._conf.getRegistrantsList(True)
2603 for reg in self._regList:
2604 lp = []
2605 lp.append(Paragraph("""%s"""%escape(reg.getFullName()), styleRegistrant))
2606 for key in self._display:
2607 if key == "Email":
2608 lp.append(Paragraph("""%s"""%escape(reg.getEmail()), styleRegistrant))
2609 elif key == "Position":
2610 lp.append(Paragraph("""%s"""%escape(reg.getPosition()), styleRegistrant))
2611 elif key == "LastName":
2612 lp.append(Paragraph("""%s"""%escape(reg.getFamilyName()), styleRegistrant))
2613 elif key == "FirstName":
2614 lp.append(Paragraph("""%s"""%escape(reg.getFirstName()), styleRegistrant))
2615 elif key == "Institution":
2616 lp.append(Paragraph("""%s"""%escape(reg.getInstitution()), styleRegistrant))
2617 elif key == "Address":
2618 lp.append(Paragraph("""%s"""%escape(reg.getAddress()), styleRegistrant))
2619 elif key == "City":
2620 lp.append(Paragraph("""%s"""%escape(reg.getCity()), styleRegistrant))
2621 elif key == "Country":
2622 lp.append(Paragraph("""%s"""%CountryHolder().getCountryById(reg.getCountry()), styleRegistrant))
2623 elif key == "Phone":
2624 lp.append(Paragraph("""%s"""%escape(reg.getPhone()), styleRegistrant))
2625 elif key == "isPayed":
2626 lp.append(Paragraph("""%s"""%escape(reg.isPayedText()), styleRegistrant))
2627 elif key == "idpayment":
2628 lp.append(Paragraph("""%s"""%escape(reg.getIdPay()), styleRegistrant))
2629 elif key == "amountToPay":
2630 lp.append(Paragraph("%.2f %s"%(reg.getTotal(), reg.getConference().getRegistrationForm().getCurrency()), styleRegistrant))
2631 elif key == "Sessions":
2632 p7 = []
2633 for ses in reg.getSessionList():
2634 if ses is not None:
2635 p7.append(Paragraph("""%s"""%escape(ses.getTitle()), styleRegistrant))
2636 if p7 == []:
2637 p7 = Paragraph("", styleRegistrant)
2638 lp.append(p7)
2639 elif key == "SocialEvents":
2640 p8 = []
2641 for se in reg.getSocialEvents():
2642 if se is not None:
2643 p8.append(Paragraph("""%s"""%escape(se.getCaption()), styleRegistrant))
2644 if p8 == []:
2645 p8 = Paragraph("", styleRegistrant)
2646 lp.append(p8)
2647 elif key == "Accommodation":
2648 if reg.getAccommodation() is not None and reg.getAccommodation().getAccommodationType() is not None:
2649 lp.append(Paragraph("%s"%escape(reg.getAccommodation().getAccommodationType().getCaption()), styleRegistrant))
2650 else:
2651 lp.append(Paragraph("", styleRegistrant))
2652 elif key == "ArrivalDate":
2653 if reg.getAccommodation() is not None and reg.getAccommodation().getArrivalDate() is not None:
2654 lp.append(Paragraph("%s"%escape(reg.getAccommodation().getArrivalDate().strftime("%d-%B-%Y")), styleRegistrant))
2655 else:
2656 lp.append(Paragraph("", styleRegistrant))
2657 elif key == "DepartureDate":
2658 if reg.getAccommodation() is not None and reg.getAccommodation().getDepartureDate() is not None:
2659 lp.append(Paragraph("%s"%escape(reg.getAccommodation().getDepartureDate().strftime("%d-%B-%Y")), styleRegistrant))
2660 else:
2661 lp.append(Paragraph("", styleRegistrant))
2662 elif key == "ReasonParticipation":
2663 lp.append(Paragraph("""%s"""%escape(reg.getReasonParticipation() or ""), styleRegistrant))
2664 elif key == "RegistrationDate":
2665 if reg.getRegistrationDate() is not None:
2666 lp.append(Paragraph("""%s"""%escape(reg.getAdjustedRegistrationDate().strftime("%d-%B-%Y-%H:%M")), styleRegistrant))
2667 else:
2668 lp.append(Paragraph("", styleRegistrant))
2669 elif key.startswith("s-"):
2670 ids=key.split("-")
2671 if len(ids)==2:
2672 status=reg.getStatusById(ids[1])
2673 cap=""
2674 if status.getStatusValue() is not None:
2675 cap=status.getStatusValue().getCaption()
2676 lp.append(Paragraph("""%s"""%escape(cap), styleRegistrant))
2677 else:
2678 ids=key.split("-")
2679 if len(ids)==2:
2680 group=reg.getMiscellaneousGroupById(ids[0])
2681 if group is not None:
2682 i=group.getResponseItemById(ids[1])
2683 if i is not None:
2684 lp.append(Paragraph("""%s"""%escape(str(i.getValue())), styleRegistrant))
2685 continue
2686 lp.append(Paragraph("", styleRegistrant))
2687 l.append(lp)
2688 noneList = ()
2689 for i in range(0, len(self._display)+1):
2690 noneList += (None,)
2691 t=Table(l,colWidths=noneList,style=tsRegs)
2692 self._story.append(t)
2693 return story
2696 class RegistrantsListToBadgesPDF:
2698 Class used to print the Badges for the registrants
2702 The following dictionary maps the names of the fonts, as returned by the javascript in WConfModifBadgeDesign.tpl,
2703 to actual TTF font names.
2704 Each font name is mapped to 4 TTF fonts: Normal one, Bold one, Italic one, Bold & Italic one.
2706 __fonts = {'Times New Roman':['Times-Roman','Times-Bold','Times-Italic','Times-Bold-Italic'],
2707 'Courier':['Courier', 'Courier-Bold', 'Courier-Italic', 'Courier-Bold-Italic'],
2708 'Sans':['Sans', 'Sans-Bold', 'Sans-Italic', 'Sans-Bold-Italic'],
2709 'LinuxLibertine':['LinuxLibertine','LinuxLibertine-Bold','LinuxLibertine-Italic','LinuxLibertine-Bold-Italic'],
2710 'Kochi-Mincho':['Kochi-Mincho','Kochi-Mincho','Kochi-Mincho','Kochi-Mincho'],
2711 'Kochi-Gothic':['Kochi-Gothic','Kochi-Gothic','Kochi-Gothic','Kochi-Gothic'],
2712 'Uming-CN':['Uming-CN','Uming-CN','Uming-CN','Uming-CN']
2713 #,'Bitstream Cyberbit':['Bitstream-Cyberbit', 'Bitstream-Cyberbit', 'Bitstream-Cyberbit', 'Bitstream-Cyberbit']
2716 """ The following dictionary maps the sizes of the items, as returned by the javascript in WConfModifBadgeDesign.tpl,
2717 to actual font sizes in points, as ReportLab needs.
2719 __fontSizes = {'xx-small':9,
2720 'x-small':10,
2721 'small':11,
2722 'medium':12,
2723 'large':14,
2724 'x-large':16,
2725 'xx-large':24
2728 """ The following dictionary maps the possible text alignments, as returned by the javascript in WConfModifBadgeDesign.tpl,
2729 to ReportLab constants.
2731 __alignments = {'Left':TA_LEFT,
2732 'Right':TA_RIGHT,
2733 'Center':TA_CENTER,
2734 'Justified':TA_JUSTIFY
2737 """ The following dictionary maps the possible text colors, as returned by the javascript in WConfModifBadgeDesign.tpl,
2738 to ReportLab color constants.
2740 __colors = {'black': colors.black,
2741 'red': colors.red,
2742 'blue': colors.blue,
2743 'green': colors.green,
2744 'yellow': colors.yellow,
2745 'brown': colors.brown,
2746 'cyan': colors.cyan,
2747 'gold': colors.gold,
2748 'pink': colors.pink,
2749 'gray': colors.gray,
2750 'white': colors.white
2754 def __init__(self, conf, badgeTemplate, marginTop, marginBottom, marginLeft, marginRight, marginColumns, marginRows, pagesize, drawDashedRectangles, registrantList):
2755 """ Constructor
2756 conf: the conference for which the badges are printed, as a Conference object.
2757 badgeTemplate: the template used, as a BadgeTemplate object.
2758 marginTop: a float indicating the top margin, in cm, int or float
2759 marginBottom: a float indicating the minimum bottom margin, in cm, int or float
2760 marginLeft: a float indicating the left margin, in cm, int or float
2761 marginRight: a float indicating the minimum right margin, in cm, int or float
2762 marginColumns: a float indicating the margin between columns of badges, in cm, int or float
2763 marginRows: a float indicating the margin between rows of badges, in cm, int or float
2764 pagesize: a string with the pagesize to used, e.g. 'A4', 'A3', 'Letter'
2765 registrantList: either a string whose value should be "all", either a list of registrant id's
2766 The badges will be drawn aligned to the left.
2769 self.__conf = conf
2770 self.__badgeTemplate = badgeTemplate
2771 self.__marginTop = marginTop
2772 self.__marginBottom = marginBottom
2773 self.__marginLeft = marginLeft
2774 self.__marginRight = marginRight
2775 self.__marginColumns = marginColumns
2776 self.__marginRows = marginRows
2778 if registrantList == 'all':
2779 self.__registrantList = self.__conf.getRegistrantsList(sort = True)
2780 else:
2781 self.__registrantList = [self.__conf.getRegistrantById(id) for id in registrantList]
2783 self.__size = PDFSizes().PDFpagesizes[pagesize]
2784 self.__width, self.__height = self.__size
2786 self.__drawDashedRectangles = drawDashedRectangles
2788 setTTFonts()
2791 def getPDFBin(self):
2792 """ Returns the data of the PDF file to be printed
2795 self.__fileDummy = FileDummy()
2796 self.__canvas = canvas.Canvas(self.__fileDummy, pagesize = self.__size)
2798 nBadgesHorizontal = int((self.__width - self.__marginLeft * cm - self.__marginRight * cm + self.__marginColumns * cm + 0.01*cm) /
2799 ((self.__badgeTemplate.getWidthInCm() + self.__marginColumns) * cm))
2802 nBadgesVertical = int((self.__height - self.__marginTop * cm - self.__marginBottom * cm + self.__marginRows * cm + 0.01*cm) /
2803 ((self.__badgeTemplate.getHeightInCm() + self.__marginRows) * cm))
2805 # We get an instance of the position generator
2806 p = RegistrantsListToBadgesPDF.__position_generator(
2807 nBadgesHorizontal, nBadgesVertical,
2808 self.__badgeTemplate.getWidthInCm() * cm, self.__badgeTemplate.getHeightInCm() * cm,
2809 self.__marginLeft * cm, self.__marginTop * cm, self.__marginColumns * cm, self.__marginRows * cm)
2811 if nBadgesHorizontal == 0 or nBadgesVertical == 0:
2812 raise NoReportError( _("The template dimensions are too large for the page size you selected"))
2814 # We print a badge for each registrant
2815 for registrant in self.__registrantList:
2816 try:
2817 posx, posy = p.next()
2818 self.__draw_badge(registrant, posx, posy)
2819 except StopIteration:
2820 # We have printed all the badges that fitted in 1 page, we have to restart the position generator.
2821 self.__canvas.showPage()
2822 p = RegistrantsListToBadgesPDF.__position_generator(
2823 nBadgesHorizontal, nBadgesVertical,
2824 self.__badgeTemplate.getWidthInCm() * cm, self.__badgeTemplate.getHeightInCm() * cm,
2825 self.__marginLeft * cm, self.__marginTop * cm, self.__marginColumns * cm, self.__marginRows * cm)
2826 posx, posy = p.next()
2827 self.__draw_badge(registrant, posx, posy)
2829 self.__canvas.save()
2830 return self.__fileDummy.getData()
2832 def __position_generator(cls,
2833 nBadgesHorizontal, nBadgesVertical,
2834 badgeWidth, badgeHeight,
2835 marginLeft, marginTop,
2836 interColumnMargin, interRowMargin):
2837 """ Generates the a new position for drawing a badge each time it is called.
2838 The position of a badge is the position of the top left corner.
2839 When there are no more positions available in a page, it throws a StopIteration exception.
2842 nx = 0
2843 ny = 0
2844 while ny < nBadgesVertical:
2845 while nx < nBadgesHorizontal:
2846 x = marginLeft + nx * (badgeWidth + interColumnMargin)
2847 y = marginTop + ny * (badgeHeight + interRowMargin)
2848 nx = nx + 1
2849 yield x,y
2850 nx = 0
2851 ny = ny + 1
2852 return
2853 __position_generator = classmethod(__position_generator)
2856 def __draw_badge(self, registrant, posx, posy):
2857 """ Draws a badge, for a given registrant, at the position (posx, posy).
2858 (posx, posy) is the position of the top left corner of a badge.
2861 # We draw a dashed rectangle around the badge
2862 if self.__drawDashedRectangles:
2863 self.__canvas.saveState()
2864 self.__canvas.setDash(1,5)
2865 self.__canvas.rect(posx, self.__height - posy - self.__badgeTemplate.getHeightInCm() * cm,
2866 self.__badgeTemplate.getWidthInCm() * cm, self.__badgeTemplate.getHeightInCm() * cm)
2867 self.__canvas.restoreState()
2869 # We draw the background if we find it.
2870 usedBackgroundId = self.__badgeTemplate.getUsedBackgroundId()
2871 if usedBackgroundId != -1 and self.__badgeTemplate.getBackground(usedBackgroundId)[1] is not None:
2872 self.__canvas.drawImage(self.__badgeTemplate.getBackground(usedBackgroundId)[1].getFilePath(),
2873 posx, self.__height - posy - self.__badgeTemplate.getHeightInCm() * cm,
2874 self.__badgeTemplate.getWidthInCm() * cm, self.__badgeTemplate.getHeightInCm() * cm)
2877 # We draw the items of the badge
2878 for item in self.__badgeTemplate.getItems():
2879 # First we determine the actual text that has to be drawed.
2880 action = BadgeDesignConfiguration().items_actions[item.getKey()][1]
2881 if isinstance(action, str):
2882 # If for this kind of item we have to draw always the same string, let's draw it.
2883 text = action
2884 elif isinstance(action, types.MethodType):
2885 # If the action is a method, depending on which class owns the method, we pass a
2886 # different object to the method.
2887 if action.im_class == Registrant:
2888 text = action.__call__(registrant)
2889 elif action.im_class == conference.Conference:
2890 text = action.__call__(self.__conf)
2891 elif action.im_class == BadgeTemplateItem:
2892 text = action.__call__(item)
2893 else:
2894 text= _("Error")
2895 elif isinstance(action, types.ClassType):
2896 # If the action is a class, it must be a class who complies to the following interface:
2897 # -it must have a getArgumentType() method, which returns either Conference, Registrant or BadgeTemplateItem.
2898 # Depending on what is returned, we will pass a different object to the getValue() method.
2899 # -it must have a getValue(object) method, to which a Conference instance, a Registrant instance or a
2900 # BadgeTemplateItem instance must be passed, depending on the result of the getArgumentType() method.
2901 argumentType = action.getArgumentType()
2902 if argumentType == Registrant:
2903 text = action.getValue(registrant)
2904 elif argumentType == conference.Conference:
2905 text = action.getValue(self.__conf)
2906 elif argumentType == BadgeTemplateItem:
2907 text = action.getValue(item)
2908 else:
2909 text = _("Error")
2910 else:
2911 text = _("Error")
2913 if not isinstance(text, basestring):
2914 text = str(text)
2915 text = escape(text)
2917 #style definition for the Paragraph used to draw the text.
2918 style = ParagraphStyle({})
2919 style.alignment = RegistrantsListToBadgesPDF.__alignments[item.getTextAlign()]
2920 style.textColor = RegistrantsListToBadgesPDF.__colors[item.getColor()]
2921 style.fontSize = RegistrantsListToBadgesPDF.__fontSizes.get(item.getFontSize(), 25)
2922 style.leading = style.fontSize
2924 if item.isBold() and item.isItalic():
2925 style.fontName = style.fontName = RegistrantsListToBadgesPDF.__fonts[item.getFont()][3]
2926 elif item.isItalic():
2927 style.fontName = style.fontName = RegistrantsListToBadgesPDF.__fonts[item.getFont()][2]
2928 elif item.isBold():
2929 style.fontName = style.fontName = RegistrantsListToBadgesPDF.__fonts[item.getFont()][1]
2930 else:
2931 style.fontName = style.fontName = RegistrantsListToBadgesPDF.__fonts[item.getFont()][0]
2933 p = Paragraph(text, style)
2935 itemx = self.__badgeTemplate.pixelsToCm(item.getX()) * cm
2936 itemy = self.__badgeTemplate.pixelsToCm(item.getY()) * cm
2938 availableWidth = self.__badgeTemplate.pixelsToCm(item.getWidth()) * cm
2939 availableHeight = (self.__badgeTemplate.getHeightInCm()
2940 - self.__badgeTemplate.pixelsToCm(item.getY()) \
2941 ) * cm
2943 w,h = p.wrap(availableWidth, availableHeight)
2945 if w > availableWidth or h > availableHeight:
2946 ## TODO: give warnings
2947 pass
2949 p.drawOn(self.__canvas, posx + itemx, self.__height - posy - itemy - h)
2952 class LectureToPosterPDF:
2954 Class used to print a lecture's poster
2957 """ The following dictionary maps the names of the fonts, as returned by the javascript in WConfModifPosterDesign.tpl,
2958 to actual TTF font names.
2959 Each font name is mapped to 4 TTF fonts: Normal one, Bold one, Italic one, Bold & Italic one.
2961 __fonts = {'Times New Roman':['Times-Roman','Times-Bold','Times-Italic','Times-Bold-Italic'],
2962 'Courier':['Courier', 'Courier-Bold', 'Courier-Italic', 'Courier-Bold-Italic'],
2963 'Sans':['Sans', 'Sans-Bold', 'Sans-Italic', 'Sans-Bold-Italic'],
2964 'LinuxLibertine':['LinuxLibertine','LinuxLibertine-Bold','LinuxLibertine-Italic','LinuxLibertine-Bold-Italic'],
2965 'Kochi-Mincho':['Kochi-Mincho','Kochi-Mincho','Kochi-Mincho','Kochi-Mincho'],
2966 'Kochi-Gothic':['Kochi-Gothic','Kochi-Gothic','Kochi-Gothic','Kochi-Gothic'],
2967 'Uming-CN':['Uming-CN','Uming-CN','Uming-CN','Uming-CN']
2968 #,'Bitstream Cyberbit':['Bitstream-Cyberbit', 'Bitstream-Cyberbit', 'Bitstream-Cyberbit', 'Bitstream-Cyberbit']
2972 """ The following dictionary maps the possible text alignments, as returned by the javascript in WConfModifPosterDesign.tpl,
2973 to ReportLab constants.
2975 __alignments = {'Left':TA_LEFT,
2976 'Right':TA_RIGHT,
2977 'Center':TA_CENTER,
2978 'Justified':TA_JUSTIFY
2981 """ The following dictionary maps the possible text colors, as returned by the javascript in WConfModifPosterDesign.tpl,
2982 to ReportLab color constants.
2984 __colors = {'black': colors.black,
2985 'red': colors.red,
2986 'blue': colors.blue,
2987 'green': colors.green,
2988 'yellow': colors.yellow,
2989 'brown': colors.brown,
2990 'cyan': colors.cyan,
2991 'gold': colors.gold,
2992 'pink': colors.pink,
2993 'gray': colors.gray,
2994 'white': colors.white
2998 def __init__(self, conf, posterTemplate, marginH, marginV, pagesize, tz=None):
2999 """ Constructor
3000 conf: the conference for which the posters are printed, as a Conference object.
3001 posterTemplate: the template used, as a PosterTemplate object.
3002 marginH: a number indicating the minimal horizontal margin
3003 marginV: a number indicating the minimal vertical margin
3004 pagesize: a string with the pagesize to used, e.g. 'A4', 'A3', 'Letter'
3005 registrantList: either a string whose value should be "all",
3006 either a list of registrant id's
3009 self.__conf = conf
3010 if not tz:
3011 self._tz = self.__conf.getTimezone()
3012 else:
3013 self._tz = tz
3014 self.__posterTemplate = posterTemplate
3015 self.__marginH = marginH
3016 self.__marginV = marginV
3018 self.__size = PDFSizes().PDFpagesizes[pagesize]
3019 self.__width, self.__height = self.__size
3021 setTTFonts()
3023 """ The following function maps the sizes of the items, as returned by the javascript in WConfModifPosterDesign.tpl,
3024 to actual font sizes in points, as ReportLab needs.
3026 def __extract_size(cls, sizePt):
3028 m = re.match(r"(\d+)(pt)",sizePt)
3030 if m:
3031 return int(m.group(1))
3032 return None
3033 __extract_size = classmethod (__extract_size)
3036 def getPDFBin(self):
3037 """ Returns the data of the PDF file to be printed
3040 self.__fileDummy = FileDummy()
3041 self.__canvas = canvas.Canvas(self.__fileDummy, pagesize = self.__size)
3043 self.__draw_poster(self.__marginH * cm, self.__marginV * cm)
3045 self.__canvas.save()
3046 return self.__fileDummy.getData()
3048 def __draw_background(self, file, position, posx, posy):
3050 img = Image.open(file)
3052 imgWidth, imgHeight = img.size
3054 posx = self.__posterTemplate.pixelsToCm(posx);
3055 posy = self.__posterTemplate.pixelsToCm(posy);
3057 if position == "Stretch":
3058 x_1 = posx
3059 y_1 = posy
3060 width = self.__posterTemplate.getWidthInCm()
3061 height = self.__posterTemplate.getHeightInCm()
3063 elif position == "Center":
3064 height = self.__posterTemplate.pixelsToCm(imgHeight)
3065 width = self.__posterTemplate.pixelsToCm(imgWidth)
3067 posterWidth = self.__posterTemplate.getWidthInCm()
3068 posterHeight = self.__posterTemplate.getHeightInCm()
3070 if width > posterWidth or height > posterHeight:
3072 if width > posterWidth:
3073 ratio = float(posterWidth)/width;
3074 width = posterWidth;
3075 height = height*ratio
3077 x_1 = posx;
3078 y_1 = posy + (posterHeight - height)/2.0;
3081 if height > posterHeight:
3082 ratio = float(posterHeight)/height;
3083 height = posterHeight;
3084 width = width*ratio
3085 x_1 = posx + (posterWidth - width)/2.0;
3086 y_1 = posy;
3087 else:
3088 x_1 = posx + (posterWidth - self.__posterTemplate.pixelsToCm(imgWidth))/2.0
3089 y_1 = posy + (posterHeight - self.__posterTemplate.pixelsToCm(imgHeight))/2.0
3091 self.__canvas.drawImage(file,
3092 x_1 * cm, y_1 * cm,
3093 width * cm, height * cm)
3096 def __draw_poster(self, posx, posy):
3097 """ Draws a poster, for a given registrant, at the position (posx, posy).
3098 (posx, posy) is the position of the top left corner of a poster.
3101 # We draw the background if we find it.
3102 usedBackgroundId = self.__posterTemplate.getUsedBackgroundId()
3104 if usedBackgroundId != -1 and self.__posterTemplate.getBackground(usedBackgroundId)[1] is not None:
3106 self.__draw_background(self.__posterTemplate.getBackground(usedBackgroundId)[1].getFilePath(),
3107 self.__posterTemplate.getBackgroundPosition(usedBackgroundId),posx,posy)
3109 # We draw the items of the poster
3110 for item in self.__posterTemplate.getItems():
3112 # First we determine the actual text that has to be drawed.
3113 action = PosterDesignConfiguration().items_actions[item.getKey()][1]
3115 if isinstance(action, str):
3116 # If for this kind of item we have to draw always the same string, let's draw it.
3117 # text is passed in lists, because some fields need several lines
3118 text = [action]
3119 elif isinstance(action, types.MethodType):
3120 # If the action is a method, depending on which class owns the method, we pass a
3121 # different object to the method.
3122 if action.im_class == conference.Conference:
3123 text = action.__call__(self.__conf).replace("\r\n","\n").split("\n")
3124 elif action.im_class == PosterTemplateItem:
3125 text = [action.__call__(item)]
3126 else:
3127 text= [_("Error")]
3128 elif isinstance(action, types.ClassType):
3129 # If the action is a class, it must be a class who complies to the following interface:
3130 # -it must have a getArgumentType() method, which returns either Conference or PosterTemplateItem.
3131 # Depending on what is returned, we will pass a different object to the getValue() method.
3132 # -it must have a getValue(object) method, to which a Conference instance or a
3133 # PosterTemplateItem instance must be passed, depending on the result of the getArgumentType() method.
3134 argumentType = action.getArgumentType()
3135 if action.__name__ == "ConferenceChairperson":
3136 #this specific case may need more than one line
3137 chairList = action.getValue(self.__conf)
3139 # 'text' is a list of lines
3140 text = []
3141 # let's fill it with the chairpersons' names
3142 for chair in chairList:
3143 if chair.getAffiliation() != "":
3144 text.append("%s (%s)" % (chair.getDirectFullName(),chair.getAffiliation()))
3145 else:
3146 text.append(chair.getDirectFullName())
3148 elif argumentType == conference.Conference:
3149 text = [action.getValue(self.__conf)]
3150 elif argumentType == PosterTemplateItem:
3151 text = [action.getValue(item)]
3152 else:
3153 text = [_("Error")]
3154 else:
3155 text = [_("Error")]
3157 text = map(escape,text)
3159 #style definition for the Paragraph used to draw the text.
3160 style = ParagraphStyle({})
3161 style.alignment = LectureToPosterPDF.__alignments[item.getTextAlign()]
3162 style.textColor = LectureToPosterPDF.__colors[item.getColor()]
3163 style.fontSize = LectureToPosterPDF.__extract_size(item.getFontSize())
3164 style.leading = style.fontSize
3166 if item.isBold() and item.isItalic():
3167 style.fontName = style.fontName = LectureToPosterPDF.__fonts[item.getFont()][3]
3168 elif item.isItalic():
3169 style.fontName = style.fontName = LectureToPosterPDF.__fonts[item.getFont()][2]
3170 elif item.isBold():
3171 style.fontName = style.fontName = LectureToPosterPDF.__fonts[item.getFont()][1]
3172 else:
3173 style.fontName = style.fontName = LectureToPosterPDF.__fonts[item.getFont()][0]
3175 availableWidth = self.__posterTemplate.pixelsToCm(item.getWidth()) * cm
3176 availableHeight = (self.__posterTemplate.getHeightInCm()
3177 - self.__posterTemplate.pixelsToCm(item.getY()) \
3178 ) * cm
3180 w,h = 0,0
3181 itemx = self.__posterTemplate.pixelsToCm(item.getX()) * cm
3182 itemy = self.__posterTemplate.pixelsToCm(item.getY()) * cm
3184 # now, we iterate over the line set
3185 for line in text:
3186 if line == "":
3187 itemy += style.fontSize
3188 else:
3189 p = Paragraph(line, style)
3191 itemy += h
3193 w,h = p.wrap(availableWidth, availableHeight)
3195 if w > availableWidth or h > availableHeight:
3196 ## TODO: warnings
3197 pass
3199 # finally, draw
3200 p.drawOn(self.__canvas, posx + itemx, self.__height - posy - itemy - h)