source: indico/indico/MaKaC/webinterface/rh/CFADisplay.py @ 6fb6a4

burotelhello-world-walkthroughipv6v0.97-seriesv0.98-seriesv0.98.2v0.98.3v0.98b1v0.98b2v0.99v1.0v1.1
Last change on this file since 6fb6a4 was 6fb6a4, checked in by Adrian Moennich <jerome.ernst.monnich@…>, 2 years ago

[FIX] Fix issue with invalid html in abstracts

  • do not use html sanitizer for abstract fields
  • always escape html when retrieving abstract fields
  • fixes #647
  • Property mode set to 100644
File size: 36.2 KB
Line 
1# -*- coding: utf-8 -*-
2##
3##
4## This file is part of CDS Indico.
5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
6##
7## CDS Indico is free software; you can redistribute it and/or
8## modify it under the terms of the GNU General Public License as
9## published by the Free Software Foundation; either version 2 of the
10## License, or (at your option) any later version.
11##
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.
16##
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
21import os
22from textwrap import TextWrapper
23
24from BTrees.IOBTree import IOBTree
25from datetime import datetime
26
27import MaKaC.webinterface.urlHandlers as urlHandlers
28import MaKaC.webinterface.mail as mail
29import MaKaC.webinterface.pages.abstracts as abstracts
30import MaKaC.webinterface.materialFactories as materialFactories
31import MaKaC.review as review
32from MaKaC.webinterface.rh.conferenceDisplay import RHConferenceBaseDisplay
33from MaKaC.webinterface.rh.base import RHModificationBaseProtected
34from MaKaC.common import DBMgr,Config
35from MaKaC.review import AbstractStatusSubmitted
36from MaKaC.PDFinterface.conference import AbstractToPDF, AbstractsToPDF
37from MaKaC.webinterface.general import normaliseListParam
38from MaKaC.errors import MaKaCError
39import MaKaC.common.timezoneUtils as timezoneUtils
40import MaKaC.conference as conference
41from MaKaC.common.info import HelperMaKaCInfo
42from MaKaC.i18n import _
43
44
45class RHBaseCFA( RHConferenceBaseDisplay ):
46
47    def _processIfActive( self ):
48        """only override this method if the CFA must be activated for
49            carrying on the handler execution"""
50        return "cfa"
51
52    def _process( self ):
53        #if the CFA is not activated we show up a form informing about that.
54        #   This must be done at RH level because there can be some RH not
55        #   displaying pages.
56        cfaMgr = self._conf.getAbstractMgr()
57        if not cfaMgr.isActive() or not self._conf.hasEnabledSection("cfa"):
58            p = abstracts.WPCFAInactive( self, self._conf )
59            return p.display()
60        else:
61            return self._processIfActive()
62
63
64class RHConferenceCFA( RHBaseCFA ):
65    _uh = urlHandlers.UHConferenceCFA
66
67    def _processIfActive( self ):
68        p = abstracts.WPConferenceCFA( self, self._target )
69        return p.display()
70
71
72class RHAbstractSubmissionBase( RHBaseCFA ):
73
74    def _checkProtection( self ):
75        self._checkSessionUser()
76        RHBaseCFA._checkProtection( self )
77
78    def _processIfOpened( self ):
79        """only override this method if the submission period must be opened
80            for the request handling"""
81        return "cfa opened"
82
83    def _processIfActive( self ):
84        cfaMgr = self._conf.getAbstractMgr()
85        #if the user is in the autorized list, don't check period
86        if self._getUser() in cfaMgr.getAuthorizedSubmitterList():
87            return self._processIfOpened()
88        #if the submission period is not yet opened we show up a form informing
89        #   about that.
90        if timezoneUtils.nowutc() < cfaMgr.getStartSubmissionDate():
91        #if the submission period is already closed we show up a form informing
92        #   about that.
93            p = abstracts.WPCFANotYetOpened( self, self._conf )
94            return p.display()
95        elif timezoneUtils.nowutc() > cfaMgr.getEndSubmissionDate() :
96            p = abstracts.WPCFAClosed( self, self._conf )
97            return p.display()
98        else:
99            return self._processIfOpened()
100
101
102class _AbstractAuthorList:
103
104    def __init__( self, params ):
105        self._mapFromParams( params )
106
107    def _getAuthorFromParams( self, idx, params ):
108        author = {  "auth_id": int( params["auth_id"][idx].strip() ), \
109                "auth_title": params["auth_title"][idx].strip(), \
110                "auth_firstName": params["auth_firstName"][idx].strip(), \
111                "auth_surName": params["auth_surName"][idx].strip(), \
112                "auth_affiliation": params["auth_affiliation"][idx].strip(), \
113                "auth_email": params["auth_email"][idx].strip(), \
114                "auth_phone": params["auth_phone"][idx].strip(), \
115                "auth_address": params["auth_address"][idx].strip(), \
116                "auth_primary": params["auth_primary"][idx], \
117                "auth_speaker": params["auth_speaker"][idx], \
118                "auth_focus": False }
119        return author
120
121    def _normaliseAuthorParams( self, params ):
122        params["auth_id"]  = normaliseListParam( params.get("auth_id", []) )
123        params["auth_title"]  = normaliseListParam( params.get("auth_title", []) )
124        params["auth_firstName"]  = normaliseListParam( params.get("auth_firstName", []) )
125        params["auth_surName"]  = normaliseListParam( params.get("auth_surName", []) )
126        params["auth_affiliation"]       = normaliseListParam( params.get("auth_affiliation", []) )
127        params["auth_email"]  = normaliseListParam( params.get("auth_email", []) )
128        params["auth_phone"]  = normaliseListParam( params.get("auth_phone", []) )
129        params["auth_address"]  = normaliseListParam( params.get("auth_address", []) )
130        primaries  = normaliseListParam( params.get("auth_primary", []) )
131        #params["auth_primary"] = normaliseListParam( params.get("auth_primary", []) )
132        speakers = normaliseListParam( params.get("auth_speaker", []) )
133        params["auth_primary"] = []
134        params["auth_speaker"] = []
135        for id in params["auth_id"]:
136            params["auth_primary"].append( str(id) in primaries )
137            params["auth_speaker"].append( str(id) in speakers)
138
139    def _mapFromParams( self, params ):
140        self._normaliseAuthorParams( params )
141        self._primaryAuthors = IOBTree()
142        self._secondaryAuthors = IOBTree()
143        maxId = -1
144        for idx in range( len( params["auth_id"] ) ):
145            id = int( params["auth_id"][idx] )
146            if id>maxId:
147                maxId = id
148            author = self._getAuthorFromParams( idx, params )
149            if author["auth_primary"]:
150                self._primaryAuthors[ id ] = author
151            else:
152                self._secondaryAuthors[ id ] = author
153        self._nextId = maxId+1
154
155    def getList( self ):
156        res = []
157        for a in self._primaryAuthors.values():
158            res.append( a )
159        for a in self._secondaryAuthors.values():
160            res.append( a )
161        return res
162
163    def getPrimaryList( self ):
164        return self._primaryAuthors.values()
165
166    def getSecondaryList( self ):
167        return self._secondaryAuthors.values()
168
169    def _getNewAuthor( self, **data ):
170        author = { "auth_id": int( self._nextId ), \
171                "auth_title": data.get("title", ""), \
172                "auth_firstName": data.get("firstName", ""), \
173                "auth_surName": data.get("surName", ""), \
174                "auth_affiliation": data.get("affiliation", ""), \
175                "auth_email": data.get("email", ""), \
176                "auth_phone": data.get("phone", ""), \
177                "auth_address": data.get("address", ""), \
178                "auth_primary": data.get("primary", False), \
179                "auth_speaker": data.get("speaker", False), \
180                "auth_focus": data.get("focus", False) }
181        #self._authors[ self._nextId ] = author
182        self._nextId += 1
183        return author
184
185    def addPrimaryAuthor( self, **data ):
186        data["primary"] = True
187        author = self._getNewAuthor( **data )
188        self._primaryAuthors[ author["auth_id"] ] = author
189
190    def addSecondaryAuthor( self, **data ):
191        data["primary"] = False
192        author = self._getNewAuthor( **data )
193        self._secondaryAuthors[ author["auth_id"] ] = author
194
195    def removePrimaryAuthor( self, id ):
196        try:
197            del self._primaryAuthors[ int(id) ]
198        except KeyError:
199            pass
200
201    def removeSecondaryAuthor( self, id ):
202        try:
203            del self._secondaryAuthors[ int(id) ]
204        except KeyError:
205            pass
206
207
208class AbstractData:
209
210    def __init__( self, absMgr, params ):
211        self._absMgr = absMgr
212        self._afm = absMgr.getAbstractFieldsMgr()
213        cparams = params.copy()
214        self._mapFromParams( cparams )
215
216    def _mapFromParams( self, params ):
217        self.title = params.get("title",  "").strip()
218        self._otherFields = {}
219        for f in self._afm.getFields():
220            id = f.getId()
221            self._otherFields[id] = params.get("f_%s"%id,"").strip()
222        self.type = params.get("type", None)
223        self.tracks = normaliseListParam( params.get("tracks", []) )
224        self.authors = _AbstractAuthorList( params )
225        self.comments = params.get("comments","")
226
227    def getFieldNames( self ):
228        return ['f_%s' % id for id in self._otherFields.keys()]
229
230    def getFieldValue( self, id ):
231        return self._otherFields.get(id, "")
232
233    def setFieldValue( self, id, value ):
234        self._otherFields[id] = value
235
236    def check( self ):
237        errors = []
238        if self.title.strip() == "":
239            errors.append( _("Abstract TITLE cannot be empty") )
240        for f in self._afm.getFields():
241            id = f.getId()
242            caption = f.getCaption()
243            ml = f.getMaxLength()
244            if f.isMandatory() and self._otherFields.get(id,"") == "":
245                errors.append(_("The field <b>%s</b> is mandatory") % caption)
246            if ml != 0 and len(self._otherFields.get(id,"")) > ml:
247                errors.append(_("The field <b>%s</b> cannot be more than %s characters") % (caption,ml))
248        if len( self.authors.getPrimaryList() ) == 0:
249            errors.append( _("No PRIMARY AUTHOR has been specified. You must define at least one primary author") )
250        speakerCount = 0
251        idx = 1
252        for author in self.authors.getPrimaryList():
253            if author["auth_firstName"].strip() == "":
254                errors.append( _("FIRST NAME has not been specified for PRIMARY AUTHOR #%s")%idx )
255            if author["auth_surName"].strip() == "":
256                errors.append( _("SURNAME has not been specified for PRIMARY AUTHOR #%s")%idx )
257            if author["auth_affiliation"].strip() == "":
258                errors.append( _("AFFILIATION has not been specified for PRIMARY AUTHOR #%s")%idx )
259            if author["auth_email"].strip() == "":
260                errors.append( _("EMAIL has not been specified for PRIMARY AUTHOR #%s")%idx )
261            if author["auth_speaker"]:
262                speakerCount += 1
263            idx += 1
264        idx = 1
265        for author in self.authors.getSecondaryList():
266            if author["auth_firstName"].strip() == "":
267                errors.append( _("FIRST NAME has not been specified for CO-AUTHOR #%s")%idx )
268            if author["auth_surName"].strip() == "":
269                errors.append( _("SURNAME has not been specified for CO-AUTHOR #%s")%idx )
270            if author["auth_affiliation"].strip() == "":
271                errors.append( _("AFFILIATION has not been specified for CO-AUTHOR #%s")%idx )
272            if author["auth_speaker"]:
273                speakerCount += 1
274            idx += 1
275        if speakerCount == 0:
276            errors.append( _("At least ONE PRESENTER must be specified") )
277        if not self.tracks and self._absMgr.areTracksMandatory():
278            errors.append( _("At least ONE TRACK must be seleted") )
279        return errors
280
281    def toDict( self ):
282        d = { "title": self.title, \
283              "type": self.type, \
284              "tracks": self.tracks, \
285              "authors": self.authors, \
286              "comments": self.comments }
287        for f in self._afm.getFields():
288            id = f.getId()
289            d[id] = self._otherFields.get(id,"")
290        return d
291
292
293class _AbstractSubmissionNotification:
294
295    def __init__( self, abstract ):
296        self._abstract = abstract
297        self._conf = self._abstract.getConference()
298        self._subject=_("Abstract submission confirmation (%s)")%self._conf.getTitle()
299
300    def getSubject( self ):
301        return self._subject
302
303    def setSubject(self,s):
304        self._subject=s
305
306    def getDestination( self ):
307        return self._abstract.getSubmitter()
308
309    def getFromAddr(self):
310        return self._conf.getSupportEmail(returnNoReply=True)
311
312    def getCCList(self):
313        return self._abstract.getOwner().getSubmissionNotification().getCCList()
314
315    def getToList(self):
316        return self._abstract.getOwner().getSubmissionNotification().getToList()
317
318    def getMsg( self ):
319        primary_authors = []
320        for auth in self._abstract.getPrimaryAuthorList():
321            primary_authors.append("""%s (%s) <%s>"""%(auth.getFullName(), auth.getAffiliation(), auth.getEmail())  )
322        co_authors = []
323        for auth in self._abstract.getCoAuthorList():
324            email = ""
325            if auth.getEmail() != "":
326                email = " <%s>"%auth.getEmail()
327            co_authors.append( """%s (%s)%s"""%(auth.getFullName(), auth.getAffiliation(), email) )
328        speakers = []
329        for spk in self._abstract.getSpeakerList():
330            speakers.append( spk.getFullName() )
331        tracks = []
332        for track in self._abstract.getTrackListSorted():
333            tracks.append( """%s"""%track.getTitle() )
334        tw = TextWrapper()
335        msg = [ _("""_("Dear") %s,""")%self._abstract.getSubmitter().getStraightFullName() ]
336        msg.append( "" )
337        msg.append( tw.fill(_("The submission of your abstract has been successfully processed.")) )
338        msg.append( "" )
339        tw.break_long_words = False
340        msg.append( tw.fill( _("""_("Abstract submitted"):\n<%s>.""")%urlHandlers.UHUserAbstracts.getURL( self._conf ) ) )
341        msg.append( "" )
342        msg.append( tw.fill( _("""_("Status of your abstract"):\n<%s>.""")%urlHandlers.UHAbstractDisplay.getURL( self._abstract ) ) )
343        msg.append( "" )
344        tw.subsequent_indent = ""
345        msg.append( tw.fill( _("""_("See below a detailed summary of your submitted abstract"):""") ) )
346        msg.append( "" )
347        tw.subsequent_indent = " "*3
348        msg.append( tw.fill( _("""_("Conference"): %s""")%self._conf.getTitle() ) )
349        msg.append( "" )
350        msg.append( tw.fill( _("""_("Submitted by"): %s""")%self._abstract.getSubmitter().getFullName() ) )
351        msg.append( "" )
352        msg.append( tw.fill( _("""_("Submitted on"): %s""")%self._abstract.getSubmissionDate().strftime( "%d %B %Y %H:%M" ) ) )
353        msg.append( "" )
354        msg.append( tw.fill( _("""_("Title"): %s""")%self._abstract.getTitle() ) )
355        msg.append( "" )
356        for f in self._conf.getAbstractMgr().getAbstractFieldsMgr().getFields():
357            msg.append( tw.fill(f.getCaption()) )
358            msg.append( self._abstract.getField(f.getId()) )
359            msg.append( "" )
360        msg.append( tw.fill( _("""_("Primary Authors"):""") ) )
361        msg += primary_authors
362        msg.append( "" )
363        msg.append( tw.fill( _("""_("Co-authors"):""") ) )
364        msg += co_authors
365        msg.append( "" )
366        msg.append( tw.fill( _("""_("Abstract presenters"):""") ) )
367        msg += speakers
368        msg.append( "" )
369        msg.append( tw.fill( _("""_("Track classification"):""") ) )
370        msg += tracks
371        msg.append( "" )
372        ctype= _("""--_("not specified")--""")
373        if self._abstract.getContribType() is not None:
374            ctype=self._abstract.getContribType().getName()
375        msg.append( tw.fill( _("""_("Presentation type"): %s""")%ctype) )
376        msg.append( "" )
377        msg.append( tw.fill( _("""_("Comments"): %s""")%self._abstract.getComments() ) )
378        msg.append( "" )
379        return "\n".join( msg )
380
381    def getBody(self):
382        msg=self.getMsg()
383        return _("""
384_("The following email has been sent to %s"):
385
386===
387
388%s""")%(self.getDestination().getFullName(), msg)
389
390
391class RHAbstractSubmission( RHAbstractSubmissionBase ):
392    _uh = urlHandlers.UHAbstractSubmission
393
394    def _checkParams( self, params ):
395        RHAbstractSubmissionBase._checkParams( self, params )
396        #if the user is not logged in we return inmediately as this form needs
397        #   the user to be logged in and therefore all the checking below is not
398        #   necessary
399
400        if self._getUser() == None:
401            return
402        self._action = ""
403        if "cancel" in params:
404            self._action = "CANCEL"
405            return
406        id = params.get("type", "")
407        params["type"] = self._conf.getContribTypeById(id)
408        self._abstractData = AbstractData( self._target.getAbstractMgr(), params )
409        self._doNotSanitizeFields = self._abstractData.getFieldNames()
410        if "add_primary_author" in params:
411            #self._action = "NEW_AUTHOR"
412            self._abstractData.authors.addPrimaryAuthor( focus=True )
413        elif "add_secondary_author" in params:
414            #self._action = "NEW_AUTHOR"
415            self._abstractData.authors.addSecondaryAuthor( focus=True )
416        elif "remove_primary_authors" in params:
417            tmp = self._normaliseListParam( params.get("selected_primary_authors", []) )
418            for id in tmp:
419                self._abstractData.authors.removePrimaryAuthor( id )
420        elif "remove_secondary_authors" in params:
421            tmp = self._normaliseListParam( params.get("selected_secondary_authors", []) )
422            for id in tmp:
423                self._abstractData.authors.removeSecondaryAuthor( id )
424        elif "validate" in params:
425            self._action = "VALIDATE"
426        else:
427            #First call
428            av = self._getUser()
429            self._abstractData.authors.addPrimaryAuthor( \
430                                        title = av.getTitle(), \
431                                        firstName = av.getName(), \
432                                        surName = av.getSurName(), \
433                                        affiliation = av.getOrganisation(), \
434                                        email = av.getEmail(), \
435                                        phone = av.getTelephone(), \
436                                        address = av.getAddress(), \
437                                        speaker = True )
438
439    def _doValidate( self ):
440        #First, one must validate that the information is fine
441        errors = self._abstractData.check()
442        if errors:
443            p = abstracts.WPAbstractSubmission( self, self._target )
444            pars = self._abstractData.toDict()
445            pars["errors"] = errors
446            pars["action"] = self._action
447            return p.display( **pars )
448        #Then, we create the abstract object and set its data to the one
449        #   received
450        cfaMgr = self._target.getAbstractMgr()
451        afm = cfaMgr.getAbstractFieldsMgr()
452        a = cfaMgr.newAbstract( self._getUser() )
453        a.setTitle( self._abstractData.title )
454        for f in afm.getFields():
455            id = f.getId()
456            a.setField(id, self._abstractData.getFieldValue(id))
457        for authData in self._abstractData.authors.getPrimaryList():
458            auth=a.newPrimaryAuthor(title = authData["auth_title"], \
459                                firstName = authData["auth_firstName"], \
460                                surName = authData["auth_surName"], \
461                                email = authData["auth_email"], \
462                                affiliation = authData["auth_affiliation"], \
463                                address = authData["auth_address"], \
464                                telephone = authData["auth_phone"] )
465            if authData["auth_speaker"]:
466                a.addSpeaker( auth )
467        for authData in self._abstractData.authors.getSecondaryList():
468            auth=a.newCoAuthor(title = authData["auth_title"], \
469                                firstName = authData["auth_firstName"], \
470                                surName = authData["auth_surName"], \
471                                email = authData["auth_email"], \
472                                affiliation = authData["auth_affiliation"], \
473                                address = authData["auth_address"], \
474                                telephone = authData["auth_phone"] )
475            if authData["auth_speaker"]:
476                a.addSpeaker( auth )
477        a.setContribType( self._abstractData.type )
478        for trackId in self._abstractData.tracks:
479            track = self._conf.getTrackById( trackId )
480            a.addTrack( track )
481        a.setComments(self._abstractData.comments)
482
483
484        #The commit must be forced before sending the confirmation
485        DBMgr.getInstance().commit()
486        #Email confirmation about the submission
487        mail.Mailer.send( _AbstractSubmissionNotification( a ), self._conf.getSupportEmail(returnNoReply=True) )
488        #Email confirmation about the submission to coordinators
489        if cfaMgr.getSubmissionNotification().hasDestination():
490            asn=_AbstractSubmissionNotification( a )
491            asn.setSubject(_("[Indico] New abstract submission: %s")%asn.getDestination().getFullName())
492            mail.GenericMailer.send( asn )
493        #We must perform some actions: email warning to the authors
494        #Finally, we display a confirmation form
495        self._redirect( urlHandlers.UHAbstractSubmissionConfirmation.getURL( a ) )
496
497    def _processIfOpened( self ):
498        if self._action == "CANCEL":
499            self._redirect( urlHandlers.UHConferenceCFA.getURL( self._conf ) )
500        elif self._action == "VALIDATE":
501            return self._doValidate()
502        else:
503            p = abstracts.WPAbstractSubmission( self, self._target )
504            pars = self._abstractData.toDict()
505            return p.display( **pars )
506
507
508
509class RHUserAbstracts( RHAbstractSubmissionBase ):
510    _uh = urlHandlers.UHUserAbstracts
511
512    def _processIfActive( self ):
513        p = abstracts.WPUserAbstracts( self, self._conf )
514        return p.display()
515
516
517class RHAbstractDisplayBase( RHAbstractSubmissionBase ):
518
519    def _checkParams( self, params ):
520        RHAbstractSubmissionBase._checkParams( self, params )
521        cfaMgr = self._conf.getAbstractMgr()
522        if not params.has_key("abstractId") and params.has_key("contribId"):
523            params["abstractId"] = params["contribId"]
524        self._abstract = self._target = cfaMgr.getAbstractById( params["abstractId"] )
525
526
527class RHAbstractSubmissionConfirmation( RHAbstractDisplayBase ):
528    _uh = urlHandlers.UHAbstractSubmissionConfirmation
529
530    def _processIfOpened( self ):
531        p = abstracts.WPAbstractSubmissionConfirmation( self, self._target )
532        return p.display()
533
534
535class RHAbstractDisplay( RHAbstractDisplayBase ):
536    _uh = urlHandlers.UHAbstractDisplay
537
538    def _processIfActive( self ):
539        p = abstracts.WPAbstractDisplay( self, self._target )
540        return p.display()
541
542
543class RHAbstractDisplayPDF( RHAbstractDisplayBase ):
544
545    def _checkProtection( self ):
546        RHConferenceBaseDisplay._checkProtection(self)
547        if not self._conf.getAbstractMgr().isActive() or not self._conf.hasEnabledSection("cfa"):
548            raise MaKaCError( _("The Call For Abstracts was disabled by the conference managers"))
549
550    def _process( self ):
551        tz = timezoneUtils.DisplayTZ(self._aw,self._conf).getDisplayTZ()
552        filename = "%s - Abstract.pdf"%self._target.getTitle()
553        pdf = AbstractToPDF(self._conf, self._target,tz=tz)
554        data = pdf.getPDFBin()
555        #self._req.headers_out["Accept-Ranges"] = "bytes"
556        self._req.headers_out["Content-Length"] = "%s"%len(data)
557        cfg = Config.getInstance()
558        mimetype = cfg.getFileTypeMimeType( "PDF" )
559        self._req.content_type = """%s"""%(mimetype)
560        self._req.headers_out["Content-Disposition"] = """inline; filename="%s\""""%filename
561        return data
562
563
564class RHAbstractsDisplayPDF(RHConferenceBaseDisplay):
565
566    def _checkProtection( self ):
567        RHConferenceBaseDisplay._checkProtection(self)
568        if not self._conf.getAbstractMgr().isActive() or not self._conf.hasEnabledSection("cfa"):
569            raise MaKaCError( _("The Call For Abstracts was disabled by the conference managers"))
570
571    def _checkParams( self, params ):
572        RHConferenceBaseDisplay._checkParams( self, params )
573        self._abstractIds = normaliseListParam( params.get("abstracts", []) )
574
575    def _process( self ):
576        tz = timezoneUtils.DisplayTZ(self._aw,self._conf).getDisplayTZ()
577        filename = "Abstracts.pdf"
578        if not self._abstractIds:
579            return _("No abstract to print")
580        pdf = AbstractsToPDF(self._conf, self._abstractIds,tz=tz)
581        data = pdf.getPDFBin()
582        self._req.set_content_length(len(data))
583        cfg = Config.getInstance()
584        mimetype = cfg.getFileTypeMimeType( "PDF" )
585        self._req.content_type = """%s"""%(mimetype)
586        self._req.headers_out["Content-Disposition"] = """inline; filename="%s\""""%filename
587        return data
588
589
590class RHAbstractModificationBase( RHAbstractDisplayBase, RHModificationBaseProtected ):
591
592    def _checkProtection( self ):
593        RHModificationBaseProtected._checkProtection( self )
594
595
596    def _processIfActive( self ):
597        #We overload this method to alow modification after the CFA is closed if the modification deadline is after the submission deadline
598        cfaMgr = self._conf.getAbstractMgr()
599        modifDeadLine = cfaMgr.getModificationDeadline()
600        if not modifDeadLine:
601            modifDeadLine = cfaMgr.getEndSubmissionDate()
602        #if the user is in the autorized list, don't check period
603        if self._getUser() in cfaMgr.getAuthorizedSubmitterList():
604            return self._processIfOpened()
605        #if the submission period is not yet opened we show up a form informing
606        #   about that.
607        if timezoneUtils.nowutc() < cfaMgr.getStartSubmissionDate():
608        #if the submission period is already closed we show up a form informing
609        #   about that.
610            p = abstracts.WPCFANotYetOpened( self, self._conf )
611            return p.display()
612        #elif timezoneUtils.nowutc() > cfaMgr.getEndSubmissionDate() :
613        elif timezoneUtils.nowutc() > cfaMgr.getEndSubmissionDate() and timezoneUtils.nowutc() > modifDeadLine:
614            p = abstracts.WPCFAClosed( self, self._conf )
615            return p.display()
616        else:
617            return self._processIfOpened()
618
619
620class RHAbstractModify( RHAbstractModificationBase ):
621    _uh = urlHandlers.UHAbstractModify
622
623    def _checkParams( self, params ):
624        RHAbstractModificationBase._checkParams( self, params )
625        #if the user is not logged in we return inmediately as this form needs
626        #   the user to be logged in and therefore all the checking below is not
627        #   necessary
628        if self._getUser() == None:
629            return
630        self._action = ""
631        if "cancel" in params:
632            self._action = "CANCEL"
633            return
634
635        params["type"]=self._conf.getContribTypeById(params.get("type", ""))
636        self._abstractData = AbstractData( self._conf.getAbstractMgr(), params )
637        self._doNotSanitizeFields = self._abstractData.getFieldNames()
638        if "add_primary_author" in params:
639            self._abstractData.authors.addPrimaryAuthor( focus=True )
640        elif "add_secondary_author" in params:
641            self._abstractData.authors.addSecondaryAuthor( focus=True )
642        elif "remove_primary_authors" in params:
643            tmp = self._normaliseListParam( params.get("selected_primary_authors", []) )
644            for id in tmp:
645                self._abstractData.authors.removePrimaryAuthor( id )
646        elif "remove_secondary_authors" in params:
647            tmp = self._normaliseListParam( params.get("selected_secondary_authors", []) )
648            for id in tmp:
649                self._abstractData.authors.removeSecondaryAuthor( id )
650        elif "validate" in params:
651            self._action = "VALIDATE"
652        else:
653            #First call
654            afm = self._conf.getAbstractMgr().getAbstractFieldsMgr()
655            self._abstractData.title = self._abstract.getTitle()
656            for f in afm.getFields():
657                id = f.getId()
658                self._abstractData.setFieldValue(id, self._abstract.getField(id))
659            for author in self._abstract.getPrimaryAuthorList():
660                data = { "title": author.getTitle(), \
661                        "firstName": author.getFirstName(), \
662                        "surName": author.getSurName(), \
663                        "affiliation": author.getAffiliation(), \
664                        "email": author.getEmail(), \
665                        "phone": author.getTelephone(), \
666                        "address": author.getAddress(), \
667                        "primary": self._abstract.isPrimaryAuthor( author ), \
668                        "speaker": self._abstract.isSpeaker( author ) }
669                self._abstractData.authors.addPrimaryAuthor( **data )
670            for author in self._abstract.getCoAuthorList():
671                data = { "title": author.getTitle(), \
672                        "firstName": author.getFirstName(), \
673                        "surName": author.getSurName(), \
674                        "affiliation": author.getAffiliation(), \
675                        "email": author.getEmail(), \
676                        "phone": author.getTelephone(), \
677                        "address": author.getAddress(), \
678                        "primary": self._abstract.isPrimaryAuthor( author ), \
679                        "speaker": self._abstract.isSpeaker( author ) }
680                self._abstractData.authors.addSecondaryAuthor( **data )
681            self._abstractData.type=self._abstract.getContribType()
682            trackIds = []
683            for track in self._abstract.getTrackListSorted():
684                trackIds.append( track.getId() )
685            self._abstractData.tracks = trackIds
686            self._abstractData.comments = self._abstract.getComments()
687
688    def _doValidate( self ):
689        #First, one must validate that the information is fine
690        errors = self._abstractData.check()
691        if errors:
692            p = abstracts.WPAbstractModify( self, self._target )
693            pars = self._abstractData.toDict()
694            pars["errors"] = errors
695            pars["action"] = self._action
696            return p.display( **pars )
697        #Then, we create the abstract object and set its data to the one
698        #   received
699        self._abstract.setTitle( self._abstractData.title )
700        afm = self._conf.getAbstractMgr().getAbstractFieldsMgr()
701        for f in afm.getFields():
702            id = f.getId()
703            self._abstract.setField( id, self._abstractData.getFieldValue(id))
704        self._abstract.clearAuthors()
705        #for authData in self._abstractData.authors.getList():
706        #    auth = self._abstract.newAuthor( title = authData["auth_title"], \
707        #                        firstName = authData["auth_firstName"], \
708        #                        surName = authData["auth_surName"], \
709        #                        email = authData["auth_email"], \
710        #                        affiliation = authData["auth_affiliation"], \
711        #                        address = authData["auth_address"], \
712        #                        telephone = authData["auth_phone"] )
713        #    if authData["auth_speaker"]:
714        #        self._abstract.addSpeaker( auth )
715        #    if authData["auth_primary"]:
716        #        self._abstract.addPrimaryAuthor( auth )
717        for authData in self._abstractData.authors.getPrimaryList():
718            auth=self._abstract.newPrimaryAuthor(title=authData["auth_title"], \
719                                firstName = authData["auth_firstName"], \
720                                surName = authData["auth_surName"], \
721                                email = authData["auth_email"], \
722                                affiliation = authData["auth_affiliation"], \
723                                address = authData["auth_address"], \
724                                telephone = authData["auth_phone"] )
725            if authData["auth_speaker"]:
726                self._abstract.addSpeaker( auth )
727        for authData in self._abstractData.authors.getSecondaryList():
728            auth=self._abstract.newCoAuthor(title=authData["auth_title"], \
729                                firstName = authData["auth_firstName"], \
730                                surName = authData["auth_surName"], \
731                                email = authData["auth_email"], \
732                                affiliation = authData["auth_affiliation"], \
733                                address = authData["auth_address"], \
734                                telephone = authData["auth_phone"] )
735            if authData["auth_speaker"]:
736                self._abstract.addSpeaker( auth )
737        self._abstract.setContribType( self._abstractData.type )
738        #self._abstract.clearTracks()
739        tracks = []
740        for trackId in self._abstractData.tracks:
741            tracks.append( self._conf.getTrackById( trackId ) )
742        self._abstract.setTracks( tracks )
743        self._abstract.setComments(self._abstractData.comments)
744        #We must perform some actions: email warning to the authors
745        #Finally, we display a confirmation form
746        self._redirect( urlHandlers.UHAbstractDisplay.getURL( self._abstract ) )
747
748    def _processIfOpened( self ):
749        #check if the modification period is not over or if the abstract
750        #   is in a different status than Submitted
751        if not self._conf.getAbstractMgr().inModificationPeriod() or \
752                not isinstance( self._abstract.getCurrentStatus(), \
753                                                AbstractStatusSubmitted ):
754            wp = abstracts.WPAbstractCannotBeModified( self, self._abstract )
755            return wp.display()
756        if self._action == "CANCEL":
757            self._redirect( urlHandlers.UHAbstractDisplay.getURL( self._abstract ) )
758        elif self._action == "VALIDATE":
759            return self._doValidate()
760        else:
761            p = abstracts.WPAbstractModify( self, self._target )
762            pars = self._abstractData.toDict()
763            pars["action"] = self._action
764            return p.display( **pars )
765
766
767class RHAbstractWithdraw( RHAbstractModificationBase ):
768    _uh = urlHandlers.UHAbstractWithdraw
769
770    def _checkParams( self, params ):
771        RHAbstractModificationBase._checkParams( self, params )
772        self._action = ""
773        self._comments = params.get( "comment", "" )
774        if params.has_key("OK"):
775            self._action = "WITHDRAW"
776        elif params.has_key("cancel"):
777            self._action = "CANCEL"
778
779    def _processIfOpened( self ):
780        if self._action == "CANCEL":
781            self._redirect( urlHandlers.UHAbstractDisplay.getURL( self._abstract ) )
782        elif self._action == "WITHDRAW":
783            if self._abstract.getCurrentStatus().__class__ not in \
784                    [review.AbstractStatusSubmitted,
785                    review.AbstractStatusUnderReview,
786                    review.AbstractStatusInConflict,
787                    review.AbstractStatusProposedToAccept,
788                    review.AbstractStatusProposedToReject]:
789                raise MaKaCError( _("this abstract cannot be withdrawn, please contact the conference organisers in order to do so"))
790            self._abstract.withdraw(self._getUser(),self._comments)
791            self._redirect( urlHandlers.UHAbstractDisplay.getURL( self._abstract ) )
792        else:
793            wp = abstracts.WPAbstractWithdraw( self, self._abstract )
794            return wp.display()
795
796
797class RHAbstractRecovery( RHAbstractModificationBase ):
798    _uh = urlHandlers.UHAbstractWithdraw
799
800    def _checkParams( self, params ):
801        RHAbstractModificationBase._checkParams( self, params )
802        self._action = ""
803        if params.has_key("OK"):
804            self._action = "RECOVER"
805        elif params.has_key("cancel"):
806            self._action = "CANCEL"
807
808    def _processIfOpened( self ):
809        if self._action == "CANCEL":
810            self._redirect( urlHandlers.UHAbstractDisplay.getURL( self._abstract ) )
811        elif self._action == "RECOVER":
812            status=self._abstract.getCurrentStatus()
813            if isinstance(status,review.AbstractStatusWithdrawn):
814                if status.getResponsible()!=self._getUser():
815                    raise MaKaCError( _("you are not allowed to recover this abstract"))
816                self._abstract.recover()
817            self._redirect( urlHandlers.UHAbstractDisplay.getURL( self._abstract ) )
818        else:
819            wp = abstracts.WPAbstractRecovery( self, self._abstract )
820            return wp.display()
Note: See TracBrowser for help on using the repository browser.