1 # -*- coding: utf-8 -*-
4 ## This file is part of CDS Indico.
5 ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
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
23 from copy
import deepcopy
24 from textwrap
import wrap
, fill
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
60 from MaKaC
.i18n
import _
61 from indico
.util
.i18n
import i18nformat
64 styles
= getSampleStyleSheet()
75 class ProgrammeToPDF(PDFBase
):
77 def __init__(self
, conf
, doc
=None, story
=None, tz
=None):
80 self
._tz
= self
._conf
.getTimezone()
83 PDFBase
.__init
__(self
, doc
, story
)
84 self
._title
= _("Conference Scientific Programme")
86 def firstPage(self
, c
, doc
):
88 self
._drawLogo
(c
, False)
89 height
=self
._drawWrappedString
(c
, strip_ml_tags(self
._conf
.getTitle()))
90 c
.setFont('Times-Bold', 15)
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():
95 c
.drawCentredString(self
._PAGE
_WIDTH
/2.0, height
, escape(self
._conf
.getLocation().getName()))
96 c
.setFont('Times-Bold', 30)
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"))
103 def laterPages(self
, c
, doc
):
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"))
110 def getBody(self
, story
=None):
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
)
123 story
.append(Spacer(1, 0.4*inch
))
127 class AbstractToPDF(PDFBase
):
129 def __init__(self
, conf
, abstract
, doc
=None, story
=None, tz
=None):
132 self
._tz
= self
._conf
.getTimezone()
135 self
._abstract
= abstract
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
):
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())
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())
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()))
167 for track
in self
._abstract
.getTrackListSorted():
168 listTrack
.append( escape(track
.getTitle()))
169 text
+= " ; ".join(listTrack
)
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())))
177 text
= i18nformat(""" _("Contribution type") : %s""")%escape
(str(self
._abstract
.getContribType()))
180 def getBody(self
, story
=None, indexedFlowable
={}, level
=1 ):
184 #style = ParagraphStyle({})
186 text
= i18nformat(""" _("Abstract ID") : %s""")%self
._abstract
.getId()
187 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
188 p
= SimpleParagraph(text
, 12)
191 story
.append(Spacer(inch
, 0.5*cm
, part
=escape(self
._abstract
.getTitle())))
193 style
= ParagraphStyle({})
194 style
.alignment
= TA_CENTER
197 text
= escape(self
._abstract
.getTitle())
198 p
= Paragraph(text
, style
, part
=escape(self
._abstract
.getTitle()))
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"
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")
214 # res.append(fill(line,85))
216 #p = Preformatted(escape(res), style, part=escape(self._abstract.getTitle()))
219 story
.append(Spacer(inch
, 0.5*cm
, part
=escape(self
._abstract
.getTitle())))
221 for field
in self
._conf
.getAbstractMgr().getAbstractFieldsMgr().getActiveFields():
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
230 #p = Paragraph(text, styleHead, part=escape(self._abstract.getTitle()))
231 p
= SimpleParagraph(text
, spaceAfter
= 5)
236 # res.append(fill(line,85))
238 p
= Paragraph(escape(value
), style
, part
=escape(self
._abstract
.getTitle()))
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> : """)
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()))
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> : """)
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()))
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") : """)
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
)
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())
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
)
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
)
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
)
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
)
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)
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()))
339 class AbstractsToPDF(PDFWithTOC
):
341 def __init__(self
, conf
, abstractList
, tz
=None):
344 self
._tz
= self
._conf
.getTimezone()
347 self
._abstracts
= abstractList
348 self
._title
= _("Abstracts book")
349 PDFWithTOC
.__init
__(self
)
351 def firstPage(self
, c
, doc
):
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
)
362 c
.setFont('Times-Roman', 10)
363 c
.drawString(0.5*inch
, 0.5*inch
, str(urlHandlers
.UHConferenceDisplay
.getURL(self
._conf
)))
366 def laterPages(self
, c
, doc
):
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"))
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") : """)
397 for track
in self
._abstract
.getTrackListSorted():
398 listTrack
.append( escape(track
.getTitle()))
399 text
+= " ; ".join(listTrack
)
402 def _getContribTypeText(self
):
403 status
=self
._abstract
.getCurrentStatus()
404 text
= i18nformat("""_("Contribution type") : %s""")%escape
(str(self
._abstract
.getContribType()))
407 def getBody(self
, story
=None, indexedFlowable
={}, level
=1 ):
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())
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
)
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
)
439 for track
in self
._abstract
.getTrackListSorted():
440 status
= self
._abstract
.getTrackJudgement(track
)
441 if status
.__class
__ == review
.AbstractAcceptance
:
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
:
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())
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)
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)
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)
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)
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)
525 class ConfManagerAbstractsToPDF(AbstractsToPDF):
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)
542 def _getTrackText(self):
543 text = i18nformat("""<b
> _("Track classification")</b
> : """)
545 for track in self._abstract.getTrackListSorted():
546 listTrack.append( escape(track.getTitle()))
547 text += " ; ".join(listTrack)
550 def _getContribTypeText(self):
551 status=self._abstract.getCurrentStatus()
552 text= i18nformat("""<b
> _("Contribution type")</b
> : %s""")%escape(str(self._abstract.getContribType()))
555 def getBody(self, story=None, indexedFlowable={}, level=1 ):
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):
568 for track in status.getProposedTrackList():
569 l.append( escape(track.getTitle()) )
570 res = "%s"%", ".join(l)
571 elif isinstance(status, _ASTrackViewPA):
573 if status.getContribType() is not None:
574 contribType = "(%s)"%status.getContribType().getName()
575 res = "%s %s"%( status.getLabel().upper(), \
577 conflicts = status.getConflicts()
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()!="":
595 if status.getContribType() is not None:
596 contribType = "(%s)"%status.getContribType().getName()
597 st = "%s %s"%(status.getLabel().upper(),contribType)
599 if status.getResponsible():
600 modifier = escape(status.getResponsible().getFullName())
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
610 text = i18nformat("""_("Status") : %s""")%st
611 if modifier or modifDate:
612 text += " (%s)"%" - ".join( [modifier, modifDate])
615 text = i18nformat("""_("Status") : _("SUBMITTED")""")
616 #p = Paragraph(text, style, part=escape(self._abstract.getTitle()))
617 p = SimpleParagraph(text)
622 #story.append(Spacer(inch, 0.1*cm, part=self._abstract.getTitle()))
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()))
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()))
641 story.append(Spacer(inch, 0.2*cm, part=escape(self._abstract.getTitle())))
644 style = ParagraphStyle({})
645 style.leftIndent = 40
646 p = Paragraph( i18nformat(""" _("In conflict with"): """), style, part=escape(self._abstract.getTitle()))
649 style = ParagraphStyle({})
650 style.leftIndent = 60
651 p = Preformatted(conflictText, style, part=escape(self._abstract.getTitle()))
655 class TrackManagerAbstractsToPDF(AbstractsToPDF):
657 def __init__(self, conf, track, abstractList, tz=None):
658 AbstractsToPDF.__init__(self, conf, abstractList, tz)
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):
674 self._tz = self._conf.getTimezone()
677 self._contrib = contrib
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):
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())
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())
700 def getBody(self, story=None, indexedFlowable={}, level=1 ):
704 style = ParagraphStyle({})
706 text = i18nformat(""" _("Contribution ID") : %s""")%self._contrib.getId()
707 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
710 story.append(Spacer(inch, 0.5*cm, part=escape(self._contrib.getTitle())))
712 style = ParagraphStyle({})
713 style.alignment = TA_CENTER
716 text = escape(self._contrib.getTitle())
717 p = Paragraph(text, style, part=escape(self._contrib.getTitle()))
720 if self._contrib.isScheduled():
721 style = ParagraphStyle({})
722 style.alignment = TA_CENTER
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()))
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"
736 #p = Paragraph(escape(self._contrib.getDescription()), style, part=escape(self._contrib.getTitle()))
739 #story.append(Spacer(inch, 0.2*cm, part=escape(self._contrib.getTitle())))
741 for field in self._conf.getAbstractMgr().getAbstractFieldsMgr().getActiveFields():
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()))
755 res.append(fill(line,85))
757 p = Paragraph(escape(res), style, part=escape(self._contrib.getTitle()))
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
> : """)
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()))
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
> : """)
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()))
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
> : """)
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()))
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()
807 sessiontitle = session.getTitle()
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()))
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()
821 tracktitle = track.getTitle()
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()))
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()))
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()))
846 class ConfManagerContribToPDF(ContribToPDF):
848 def getBody(self, story=None, indexedFlowable={}, level=1 ):
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=""):
863 self._tz = self._conf.getTimezone()
866 self._contribList = contribList
868 PDFBase.__init__(self)
869 self._title=_("Book of abstracts")
870 self._sortedBy = sortedBy
871 if self._sortedBy == "boardNo":
873 self._contribList = sorted(self._contribList, key=lambda x:int(x.getBoardNumber()))
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):
883 self._drawLogo(c, False)
884 height=self._drawWrappedString(c, self._conf.getTitle())
885 c.setFont('Times-Bold',15)
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():
892 c.drawCentredString(self._PAGE_WIDTH/2.0,height,
893 escape(self._conf.getLocation().getName()))
894 c.setFont('Times-Bold', 30)
896 c.drawCentredString(self._PAGE_WIDTH/2.0,height,\
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"))
903 def laterPages(self,c,doc):
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)
912 def _defineStyles(self):
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
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):
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"])
956 story.append(PageBreak())
957 for contrib in self._contribList:
958 if not contrib.canAccess(self._aw):
960 if self._sortedBy == "boardNo":
961 caption="%s"%(contrib.getTitle())
963 caption="%s - %s"%(contrib.getId(),contrib.getTitle())
964 p1=Paragraph(escape(caption),self._styles["title"])
966 for spk in contrib.getSpeakerList():
967 fullName=spk.getFullName()
968 instit=spk.getAffiliation().strip()
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"])
977 if contrib.getSession() is not None:
978 ses=contrib.getSession().getTitle()
979 if contrib.getBoardNumber():
982 ses="%sBoard: %s"%(ses, contrib.getBoardNumber())
983 if contrib.isScheduled():
986 text="%s%s"%(ses,contrib.getAdjustedStartDate(self._tz).strftime("%A %d %B %Y %H:%M"))
989 p4=Paragraph(escape(text),self._styles["tt_info"])
990 abs=KeepTogether([p1,p4,p2,p3])
992 story.append(Spacer(1,0.4*inch))
995 class ContribsToPDF(PDFWithTOC):
997 def __init__(self, conf, contribList, tz=None):
1000 self._tz = self._conf.getTimezone()
1003 self._contribs = contribList
1004 self._title = _("Contributions book")
1005 PDFWithTOC.__init__(self)
1007 def firstPage(self, c, doc):
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)
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)))
1023 def laterPages(self, c, doc):
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"))
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):
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):
1059 self.contribId = True
1060 self.speakerTitle = True
1061 self.contribAbstract = False
1062 self.newPagePerSession = False
1063 self.useSessionColorCodes = False
1064 self.showSessionTOC = False
1066 self.lengthContribs = False
1067 self.contribsAtConfLevel=False
1068 self.breaksAtConfLevel=False
1069 self.dateCloseToSessions=False
1071 self.tableContents=True
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
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
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
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())
1178 return cmp(x.getOwner().getSession().getTitle(),y.getOwner().getSession().getTitle())
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):
1188 self._tz = self._conf.getTimezone()
1192 self._tz = DisplayTZ(self._aw,self._conf).getDisplayTZ()
1193 self._showSessions=showSessions
1194 self._showDays=showDays
1195 self._ttPDFFormat = ttPDFFormat or TimetablePDFFormat()
1197 if self._ttPDFFormat.showCoverPage():
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
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():
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))
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():
1249 c.drawCentredString(self._PAGE_WIDTH/2.0,height,escape(self._conf.getLocation().getName()))
1250 c.setFont('Times-Bold', modifiedFontSize(30, self._fontsize))
1252 c.drawCentredString(self._PAGE_WIDTH/2.0,height,\
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"))
1259 def laterPages(self,c,doc):
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())
1270 def _defineStyles(self):
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)))
1308 def _getSessionColor(self
,ses
):
1309 HTMLcolor
= ses
.getSession().getColor()
1310 color
= self
._HTMLColorToRGB
(HTMLcolor
)
1313 def _processContribution(self
,contrib
,l
):
1314 if not contrib
.canAccess(self
._aw
):
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"])
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)])
1332 if self
._useColors
():
1334 if self
._ttPDFFormat
.showContribAbstract():
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"): """)
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
)
1355 l
.append([colorCell
,date
,captionAndSpeakers
])
1357 l
.append([date
,captionAndSpeakers
])
1359 caption
= Table(lt
,colWidths
=(None),style
=self
._tsSpk
)
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"])
1371 speakers
=Table(spkList
,style
=self
._tsSpk
)
1373 l
.append([colorCell
,date
,caption
,speakers
])
1375 l
.append([date
,caption
,speakers
])
1376 for subc
in contrib
.getSubContributionList():
1377 if not subc
.canAccess(self
._aw
):
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"])])
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"])
1399 if self
._ttPDFFormat
.showContribAbstract():
1401 captionAndSpeakers
= Table(lt
,colWidths
=(None),style
=self
._tsSpk
)
1403 l
.append([colorCell
,"",captionAndSpeakers
])
1405 l
.append(["",captionAndSpeakers
])
1407 caption
= Table(lt
,colWidths
=(None),style
=self
._tsSpk
)
1408 speakers
=Table(spkList
,style
=self
._tsSpk
)
1410 l
.append([colorCell
,"",caption
,speakers
])
1412 l
.append(["",caption
,speakers
])
1415 def _processPosterContribution(self
,contrib
,l
):
1416 if not contrib
.canAccess(self
._aw
):
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():
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"): """)
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
])
1450 l
.append([captionAndSpeakers
,boardNumber
])
1452 caption
= Table(lt
,colWidths
=(None),style
=self
._tsSpk
)
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"])
1462 speakers
=Table(spkList
,style
=self
._tsSpk
)
1463 if self
._useColors
():
1464 l
.append([" ",caption
,speakers
, boardNumber
])
1466 l
.append([caption
,speakers
, boardNumber
])
1467 for subc
in contrib
.getSubContributionList():
1468 if not subc
.canAccess(self
._aw
):
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
)
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"])
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() )
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
=""):
1511 newrow
.append(self
._fontify
(text
,fSize
,fName
))
1514 def _processDayEntries(self
,day
,story
):
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
:
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
:
1539 if not sessionSlot
.canView(self
._aw
):
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())
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())))
1552 conv
.append(escape(c
.getFullName()))
1553 conv
="; ".join(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")))
1565 escape(sessionSlot
.getAdjustedEndDate(self
._tz
).strftime("%H:%M")))
1566 p1
=Paragraph(text
,self
._styles
["session_title"])
1567 if self
._useColors
():
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
)
1574 if self
._ttPDFFormat
.showTitleSessionTOC():
1575 self
._indexedFlowable
[p1
]={"text":escape(sessionSlot
.getSession().getTitle()), "level":2}
1576 ## if self._useColors():
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))
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"])
1589 p2
=Paragraph(conv
,self
._styles
["conveners"])
1592 ts
= deepcopy(originalts
)
1593 if sessionSlot
.getSession().getScheduleType()=="poster":
1594 if self
._sortingCrit
is not None:
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
)
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
)
1608 title
= "[id] title"
1609 if not self
._ttPDFFormat
.showContribId():
1611 if self
._ttPDFFormat
.showContribAbstract() and self
._ttPDFFormat
.showContribPosterAbstract():
1612 #presenter integrated in 1st column -> 2 columns only
1613 row
= [title
,"board"]
1616 row
= [title
,"presenter","board"]
1617 widths
=[None,5*cm
,1*cm
]
1618 row
= self
._fontifyRow
(row
,11)
1619 if self
._useColors
():
1621 widths
.insert(0,0.2*cm
)
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)
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
]
1646 row
= [date
,caption
,""]
1647 if self
._useColors
():
1651 title
= "[id] title"
1652 if not self
._ttPDFFormat
.showContribId():
1654 if self
._ttPDFFormat
.showContribAbstract():
1655 #presenter integrated in 1st column -> 2 columns only
1656 row
= ["time",title
]
1657 widths
= [1*cm
,None]
1659 row
= ["time",title
,"presenter"]
1660 widths
= [1*cm
,None,5*cm
]
1661 row
= self
._fontifyRow
(row
,11)
1662 if self
._useColors
():
1664 widths
.insert(0,0.2*cm
)
1666 if self
._useColors
():
1667 ts
.add('BACKGROUND', (0, 1), (0,-1), self
._getSessionColor
(sessionSlot
))
1668 t
=Table(l
,colWidths
=widths
,style
=ts
)
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.
1676 if isinstance(res
[i
], PageBreak
):
1680 if self
._ttPDFFormat
.showNewPagePerSession():
1681 res
.append(PageBreak())
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
):
1690 if contrib
.getRoom() is not None:
1691 room
=" - %s"%escape
(contrib
.getRoom().getName())
1692 caption
="%s"%contrib
.getTitle()
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())))
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"])
1708 if self
._ttPDFFormat
.showTitleSessionTOC():
1709 self
._indexedFlowable
[p1
]={"text":escape(contrib
.getTitle()), "level":2}
1710 p2
=Paragraph(spks
,self
._styles
["conveners"])
1712 if entry
== entriesOnDay
[-1]: # if it is the last one, we do the page break and remove the previous one.
1715 if isinstance(res
[i
], PageBreak
):
1719 if self
._ttPDFFormat
.showNewPagePerSession():
1720 res
.append(PageBreak())
1722 elif self
._ttPDFFormat
.showBreaksAtConfLevel() and \
1723 isinstance(entry
,schedule
.BreakTimeSchEntry
):
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"])
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.
1740 if isinstance(res
[i
], PageBreak
):
1744 if self
._ttPDFFormat
.showNewPagePerSession():
1745 res
.append(PageBreak())
1750 def getBody(self
,story
=None):
1751 self
._defineStyles
()
1754 if not self
._ttPDFFormat
.showCoverPage():
1755 s
= ParagraphStyle({})
1756 s
.fontName
= "Times-Bold"
1759 s
.alignment
= TA_CENTER
1760 p
=Paragraph(escape(self
._conf
.getTitle()),s
)
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)
1770 dayEntries
=self
._processDayEntries
(currentDay
,story
)
1771 if len(dayEntries
)==0:
1772 currentDay
+=timedelta(days
=1)
1774 text
=escape(currentDay
.strftime("%A %d %B %Y"))
1775 p
=Paragraph(text
,self
._styles
["day"],part
=currentDay
.strftime("%A %d %B %Y"))
1777 self
._indexedFlowable
[p
]={"text":currentDay
.strftime("%A %d %B %Y"), "level":1}
1778 for entry
in dayEntries
:
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):
1789 self
._tz
= self
._conf
.getTimezone()
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
):
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
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() != "":
1836 def _processDayEntries(self
,day
,story
):
1837 lastSessions
=[] # this is to avoid checking if the slots have titles for all the slots
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
:
1847 if not sessionSlot
.canView(self
._aw
):
1849 if session
in lastSessions
:
1851 if self
._haveSessionSlotsTitles
(session
):
1854 lastSessions
.append(session
)
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"]))
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"]))
1867 for c
in e
.getConvenerList():
1868 chairs
.append("%s"%c.getFullName())
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
):
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"]))
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"]))
1888 for c
in contrib
.getSpeakerList():
1889 spks
.append("%s"%c.getFullName())
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"]))
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())
1908 def getBody(self
,story
=None):
1909 self
._defineStyles
()
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)
1918 dayEntries
=self
._processDayEntries
(currentDay
,story
)
1919 if len(dayEntries
)==0:
1920 currentDay
+=timedelta(days
=1)
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")) )
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())
1931 p
=Paragraph(text
, self
._styles
["title"])
1933 text2
= i18nformat(""" _("Daily Programme"): %s""")%escape
(currentDay
.strftime("%A %d %B %Y"))
1934 p2
=Paragraph(text2
,self
._styles
["day"])
1936 story
.append(Spacer(1,0.4*inch
))
1937 for entry
in dayEntries
:
1939 currentDay
+=timedelta(days
=1)
1941 class AbstractBook(PDFWithTOC
):
1943 def __init__(self
,conf
,aw
,tz
=None):
1946 self
._tz
= self
._conf
.getTimezone()
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
):
1959 self
._drawLogo
(c
, False)
1960 height
=self
._drawWrappedString
(c
,self
._conf
.getTitle())
1961 c
.setFont('Times-Bold',15)
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():
1968 c
.drawCentredString(self
._PAGE
_WIDTH
/2.0,height
,
1969 escape(self
._conf
.getLocation().getName()))
1970 c
.setFont('Times-Bold', 30)
1972 c
.drawCentredString(self
._PAGE
_WIDTH
/2.0,height
,\
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"))
1979 def laterPages(self
,c
,doc
):
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
)
1988 def _defineStyles(self
):
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
):
2038 if contrib
.getSession() is not None:
2039 ses
=contrib
.getSession().getTitle()
2040 if contrib
.getBoardNumber():
2043 ses
="%sBoard %s"%(ses
, contrib
.getBoardNumber())
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}
2059 for auth
in contrib
.getAuthorList():
2060 fullName
=auth
.getFullName()
2061 instit
=auth
.getAffiliation().strip()
2064 indexInsti
= institutions
.index(instit
) + 1
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"]))
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"]))
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
)
2094 story
.append(Spacer(1,0.4*inch
))
2096 def getBody(self
,story
=None):
2097 self
._defineStyles
()
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"])
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
)
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):
2135 self
._tz
= self
._conf
.getTimezone()
2138 self
._trackDict
= trackDict
2139 self
._trackOrder
= trackOrder
2140 self
._contribDictNPages
= npages
2141 self
._contribList
=contribList
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
):
2151 self
._drawLogo
(c
, False)
2152 height
=self
._drawWrappedString
(c
, self
._conf
.getTitle())
2153 c
.setFont('Times-Bold',15)
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():
2160 c
.drawCentredString(self
._PAGE
_WIDTH
/2.0,height
,escape(self
._conf
.getLocation().getName()))
2161 c
.setFont('Times-Bold', 30)
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)
2168 def laterPages(self
,c
,doc
):
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))
2177 def getBody(self
, story
=None, indexedFlowable
={}, level
=1 ):
2180 self
._story
.append(PageBreak())
2181 style
= ParagraphStyle({})
2182 style
.fontName
= "Times-Bold"
2187 style
.alignment
=TA_LEFT
2188 text
= _("Table of Contents")
2189 p
= Paragraph(text
, style
)
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)])
2228 if self
._trackOrder
is not None and self
._trackOrder
!=[]:
2229 for track
in self
._trackOrder
:
2231 p
=Paragraph("",styleTrack
)
2232 p2
=Paragraph("",styleTrack
)
2234 p
=Paragraph(escape(track
.getTitle()),styleTrack
)
2235 p2
=Paragraph("<b>%s</b>"%escape
("%s"%i),styleTrack
)
2238 p
=Paragraph("",styleTrack
)
2239 p2
=Paragraph("",styleTrack
)
2242 for contrib
in self
._trackDict
[track
.getId()]:
2243 i
=self
._addContrib
(contrib
, l
, i
, styleContrib
, styleAuthor
)
2245 t
=Table(l
,colWidths
=(None,1.2*cm
),style
=tsContribs
)
2246 self
._story
.append(t
)
2249 for contrib
in self
._contribList
:
2250 i
=self
._addContrib
(contrib
, l
, i
, styleContrib
, styleAuthor
)
2252 t
=Table(l
,colWidths
=(None,1.2*cm
),style
=tsContribs
)
2253 self
._story
.append(t
)
2254 self
._story
.append(Spacer(inch
, 2*cm
))
2258 def _addContrib(self
, contrib
, l
, i
, styleContrib
, styleAuthor
):
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()]
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() != "":
2282 res
= author
.getFirstName()
2284 res
= "%s. %s"%(author
.getFirstName()[0].upper(), res
)
2287 class ProceedingsChapterSeparator(PDFBase
):
2289 def __init__(self
, track
, doc
=None, story
=None):
2291 self
._conf
= track
.getConference()
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
):
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)
2311 def laterPages(self
,c
,doc
):
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)
2320 def getBody(self
, story
=None, indexedFlowable
={}, level
=1 ):
2323 self
._story
.append(PageBreak())
2324 self
._story
.append(PageBreak())
2327 class RegistrantToPDF(PDFBase
):
2329 def __init__(self
, conf
, reg
, display
, doc
=None, story
=None):
2332 self
._display
= display
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
):
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())
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())
2355 def getBody(self
, story
=None, indexedFlowable
={}, level
=1 ):
2359 style
= ParagraphStyle({})
2361 text
= i18nformat(""" _("Registrant ID") : %s""")%self
._reg
.getId()
2362 p
= Paragraph(text
, style
, part
=escape(self
._reg
.getFullName()))
2365 story
.append(Spacer(inch
, 0.5*cm
, part
=escape(self
._reg
.getFullName())))
2367 style
= ParagraphStyle({})
2368 style
.alignment
= TA_CENTER
2371 text
= escape(self
._reg
.getFullName())
2372 p
= Paragraph(text
, style
, part
=escape(self
._reg
.getFullName()))
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
:
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":
2407 for ses
in self
._reg
.getSessionList():
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():
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("-")
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()))
2443 ids
= key
.split("-")
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())))
2452 p
= Paragraph(text
, style
, part
=escape(self
._reg
.getFullName()))
2454 story
.append(Spacer(inch
, 0.2*cm
, part
=escape(self
._reg
.getFullName())))
2457 class RegistrantsListToBookPDF(PDFWithTOC
):
2458 def __init__(self
, conf
,doc
=None, story
=[],list=None, display
=["Institution", "Phone", "City", "Country"]):
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
):
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
)
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
)))
2482 def laterPages(self
, c
, doc
):
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"))
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"]):
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
):
2522 c
.setFont('Times-Bold', 30)
2524 self
._drawWrappedString
(c
, escape(self
._conf
.getTitle()), height
=self
._PAGE
_HEIGHT
-0.75*inch
)
2525 c
.setFont('Times-Bold', 25)
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")))
2532 def getBody(self
, story
=None, indexedFlowable
={}, level
=1 ):
2536 style
= ParagraphStyle({})
2538 style
.alignment
= TA_CENTER
2539 text
= i18nformat("""<b>_("List of registrants")</b>""")
2540 p
= Paragraph(text
, style
, part
=escape(self
._conf
.getTitle()))
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") ] )
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-"):
2586 status
=self
._regForm
.getStatusById(ids
[1])
2587 p
=Paragraph("""<b>%s</b>"""%escape
(status
.getCaption()), styleRegistrant
)
2589 p
=Paragraph("", styleRegistrant
)
2593 group
=self
._regForm
.getSectionById(ids
[0])
2594 if group
is not None:
2595 i
=group
.getFieldById(ids
[1])
2597 p
=Paragraph("""<b>%s</b>"""%escape
(i
.getCaption()), styleRegistrant
)
2601 if self
._regList
== None:
2602 self
._regList
= self
._conf
.getRegistrantsList(True)
2603 for reg
in self
._regList
:
2605 lp
.append(Paragraph("""%s"""%escape
(reg
.getFullName()), styleRegistrant
))
2606 for key
in self
._display
:
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
))
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":
2633 for ses
in reg
.getSessionList():
2635 p7
.append(Paragraph("""%s"""%escape
(ses
.getTitle()), styleRegistrant
))
2637 p7
= Paragraph("", styleRegistrant
)
2639 elif key
== "SocialEvents":
2641 for se
in reg
.getSocialEvents():
2643 p8
.append(Paragraph("""%s"""%escape
(se
.getCaption()), styleRegistrant
))
2645 p8
= Paragraph("", styleRegistrant
)
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
))
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
))
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
))
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
))
2668 lp
.append(Paragraph("", styleRegistrant
))
2669 elif key
.startswith("s-"):
2672 status
=reg
.getStatusById(ids
[1])
2674 if status
.getStatusValue() is not None:
2675 cap
=status
.getStatusValue().getCaption()
2676 lp
.append(Paragraph("""%s"""%escape
(cap
), styleRegistrant
))
2680 group
=reg
.getMiscellaneousGroupById(ids
[0])
2681 if group
is not None:
2682 i
=group
.getResponseItemById(ids
[1])
2684 lp
.append(Paragraph("""%s"""%escape
(str(i
.getValue())), styleRegistrant
))
2686 lp
.append(Paragraph("", styleRegistrant
))
2689 for i
in range(0, len(self
._display
)+1):
2691 t
=Table(l
,colWidths
=noneList
,style
=tsRegs
)
2692 self
._story
.append(t
)
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,
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
,
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
,
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
):
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.
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)
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
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
:
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.
2844 while ny
< nBadgesVertical
:
2845 while nx
< nBadgesHorizontal
:
2846 x
= marginLeft
+ nx
* (badgeWidth
+ interColumnMargin
)
2847 y
= marginTop
+ ny
* (badgeHeight
+ interRowMargin
)
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.
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
)
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
)
2913 if not isinstance(text
, basestring
):
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]
2929 style
.fontName
= style
.fontName
= RegistrantsListToBadgesPDF
.__fonts
[item
.getFont()][1]
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()) \
2943 w
,h
= p
.wrap(availableWidth
, availableHeight
)
2945 if w
> availableWidth
or h
> availableHeight
:
2946 ## TODO: give warnings
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
,
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
,
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):
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
3011 self
._tz
= self
.__conf
.getTimezone()
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
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
)
3031 return int(m
.group(1))
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":
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
3078 y_1
= posy
+ (posterHeight
- height
)/2.0;
3081 if height
> posterHeight
:
3082 ratio
= float(posterHeight
)/height
;
3083 height
= posterHeight
;
3085 x_1
= posx
+ (posterWidth
- width
)/2.0;
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,
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
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
)]
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
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()))
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
)]
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]
3171 style
.fontName
= style
.fontName
= LectureToPosterPDF
.__fonts
[item
.getFont()][1]
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()) \
3181 itemx
= self
.__posterTemplate
.pixelsToCm(item
.getX()) * cm
3182 itemy
= self
.__posterTemplate
.pixelsToCm(item
.getY()) * cm
3184 # now, we iterate over the line set
3187 itemy
+= style
.fontSize
3189 p
= Paragraph(line
, style
)
3193 w
,h
= p
.wrap(availableWidth
, availableHeight
)
3195 if w
> availableWidth
or h
> availableHeight
:
3200 p
.drawOn(self
.__canvas
, posx
+ itemx
, self
.__height
- posy
- itemy
- h
)