Show message instead of sending empty package
[cds-indico.git] / indico / MaKaC / webinterface / rh / conferenceModif.py
blobad8503a6c6e885dc3f33f81c27da337cfe1bdf1b
1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
17 import os
18 from cStringIO import StringIO
19 import tempfile
20 import types
21 from flask import session, request, flash, redirect
22 from persistent.list import PersistentList
23 from datetime import datetime,timedelta
24 from dateutil.relativedelta import relativedelta
25 from pytz import timezone
26 from BTrees.OOBTree import OOBTree
27 from MaKaC.webinterface.common.abstractDataWrapper import AbstractParam
28 import MaKaC.review as review
29 import MaKaC.webinterface.urlHandlers as urlHandlers
30 import MaKaC.webinterface.displayMgr as displayMgr
31 import MaKaC.webinterface.internalPagesMgr as internalPagesMgr
32 import MaKaC.webinterface.pages.conferences as conferences
33 import MaKaC.webinterface.pages.sessions as sessions
34 import MaKaC.conference as conference
35 from MaKaC.webinterface.general import normaliseListParam
36 from MaKaC.webinterface.rh.base import RHModificationBaseProtected
37 from MaKaC.webinterface.pages import admins
38 from MaKaC.webinterface.rh.conferenceBase import RHConferenceBase
39 from MaKaC.webinterface.rh.categoryDisplay import UtilsConference
40 from indico.core import signals
41 from indico.core.config import Config
42 from MaKaC.errors import MaKaCError, FormValuesError,ModificationError,\
43 ConferenceClosedError, NoReportError, NotFoundError
44 from MaKaC.PDFinterface.conference import ConfManagerAbstractsToPDF, ContribsToPDF, RegistrantsListToBadgesPDF, LectureToPosterPDF
45 from MaKaC.webinterface.common import AbstractStatusList, abstractFilters
46 from MaKaC.webinterface import locators
47 from MaKaC.common.xmlGen import XMLGen
48 from MaKaC.webinterface.common.abstractNotificator import EmailNotificator
49 import MaKaC.webinterface.common.registrantNotificator as registrantNotificator
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.common.contribPacker import ZIPFileHandler, AbstractPacker
54 from MaKaC.common import pendingQueues
55 from MaKaC.export.excel import AbstractListToExcel, ParticipantsListToExcel, ContributionsListToExcel
56 from MaKaC.common import utils
57 from MaKaC.i18n import _
58 from indico.modules.events.requests.util import is_request_manager
59 from indico.util.i18n import i18nformat
60 from indico.util.signals import values_from_signal
61 from MaKaC.common.timezoneUtils import nowutc
62 from MaKaC.review import AbstractStatusSubmitted, AbstractStatusProposedToAccept, AbstractStatusProposedToReject
63 import MaKaC.webinterface.pages.abstracts as abstracts
64 from MaKaC.fossils.conference import ISessionBasicFossil
66 from indico.util import json
67 from indico.web.http_api.metadata.serializer import Serializer
68 from indico.web.flask.util import send_file, url_for
69 from indico.modules.attachments.controllers.event_package import AttachmentPackageGeneratorMixin
72 class RHConferenceModifBase(RHConferenceBase, RHModificationBaseProtected):
74 def _checkParams(self, params):
75 RHConferenceBase._checkParams(self, params)
77 def _checkProtection(self):
78 RHModificationBaseProtected._checkProtection(self)
80 def _displayCustomPage(self, wf):
81 return None
83 def _displayDefaultPage(self):
84 return None
86 def _process(self):
87 wf = self.getWebFactory()
88 if wf is not None:
89 res = self._displayCustomPage(wf)
90 if res is not None:
91 return res
92 return self._displayDefaultPage()
95 class RHConferenceModification(RHConferenceModifBase):
96 _uh = urlHandlers.UHConferenceModification
98 def _process( self ):
99 pars={}
100 wf=self.getWebFactory()
101 if wf is not None:
102 pars["type"]=wf.getId()
103 if self._conf.isClosed():
104 p = conferences.WPConferenceModificationClosed( self, self._target )
105 return p.display(**pars)
106 else:
107 p = conferences.WPConferenceModification( self, self._target )
109 if wf is not None:
110 p = wf.getConfModif(self, self._conf)
111 return p.display(**pars)
114 class RHConfScreenDatesEdit(RHConferenceModifBase):
115 _uh = urlHandlers.UHConfScreenDatesEdit
117 def _checkParams(self,params):
118 RHConferenceModifBase._checkParams(self,params)
119 self._action=""
120 if params.has_key("CANCEL"):
121 self._action="CANCEL"
122 elif params.has_key("OK"):
123 self._action="EDIT"
124 self._sDate,self._eDate=None,None
125 tz = self._target.getTimezone()
126 if params.get("start_date","conference")=="own":
127 try:
128 self._sDate=timezone(tz).localize(datetime(int(params["sYear"]),
129 int(params["sMonth"]),
130 int(params["sDay"]),
131 int(params["sHour"]),
132 int(params["sMin"]))).astimezone(timezone('UTC'))
133 except ValueError:
134 raise MaKaCError( _("Please enter integers in all the start date fields"), _("Schedule"))
135 if params.get("end_date","conference")=="own":
136 try:
137 self._eDate=timezone(tz).localize(datetime(int(params["eYear"]),
138 int(params["eMonth"]),
139 int(params["eDay"]),
140 int(params["eHour"]),
141 int(params["eMin"]))).astimezone(timezone('UTC'))
142 except ValueError:
143 raise MaKaCError( _("Please enter integers in all the end date fields"), _("Schedule"))
145 def _process( self ):
146 url=urlHandlers.UHConferenceModification.getURL(self._target)
147 if self._action=="CANCEL":
148 self._redirect(url)
149 return
150 elif self._action=="EDIT":
151 self._target.setScreenStartDate(self._sDate)
152 self._target.setScreenEndDate(self._eDate)
153 self._redirect(url)
154 return
155 p = conferences.WPScreenDatesEdit(self, self._target)
156 return p.display()
159 class RHConferenceModifKey(RHConferenceModifBase):
161 def _checkParams(self, params):
162 RHConferenceBase._checkParams(self, params)
163 self._modifkey = params.get("modifKey", "").strip()
164 self._doNotSanitizeFields.append("modifKey")
165 self._redirectURL = params.get("redirectURL", "")
167 def _checkProtection(self):
168 modif_keys = session.setdefault('modifKeys', {})
169 modif_keys[self._conf.getId()] = self._modifkey
170 session.modified = True
172 RHConferenceModifBase._checkProtection(self)
174 def _process( self ):
175 if self._redirectURL != "":
176 url = self._redirectURL
177 else:
178 url = urlHandlers.UHConferenceDisplay.getURL( self._conf )
179 self._redirect( url )
181 class RHConferenceModifManagementAccess( RHConferenceModifKey ):
182 _uh = urlHandlers.UHConfManagementAccess
183 _tohttps = True
185 def _checkParams(self, params):
186 RHConferenceModifKey._checkParams(self, params)
187 from MaKaC.webinterface.rh.reviewingModif import RCPaperReviewManager, RCReferee
188 self._isRegistrar = self._target.isRegistrar( self._getUser() )
189 self._isPRM = RCPaperReviewManager.hasRights(self)
190 self._isReferee = RCReferee.hasRights(self)
191 self._requests_manager = is_request_manager(session.user)
192 self._plugin_urls = values_from_signal(signals.event_management.management_url.send(self._conf),
193 single_value=True)
195 def _checkProtection(self):
196 if not (self._isRegistrar or self._isPRM or self._isReferee or self._requests_manager or self._plugin_urls):
197 RHConferenceModifKey._checkProtection(self)
199 def _process(self):
200 url = None
201 if self._redirectURL != "":
202 url = self._redirectURL
204 elif self._conf.canModify(self.getAW()):
205 url = urlHandlers.UHConferenceModification.getURL( self._conf )
207 elif self._isRegistrar:
208 url = urlHandlers.UHConfModifRegForm.getURL( self._conf )
209 elif self._isPRM:
210 url = urlHandlers.UHConfModifReviewingPaperSetup.getURL( self._conf )
211 elif self._isReferee:
212 url = urlHandlers.UHConfModifReviewingAssignContributionsList.getURL( self._conf )
213 elif self._requests_manager:
214 url = url_for('requests.event_requests', self._conf)
215 elif self._plugin_urls:
216 url = next(iter(self._plugin_urls), None)
217 if not url:
218 url = urlHandlers.UHConfManagementAccess.getURL( self._conf )
220 self._redirect(url)
223 class RHConferenceCloseModifKey(RHConferenceBase):
225 def _checkParams(self, params):
226 RHConferenceBase._checkParams(self, params)
227 self._modifkey = params.get("modifKey", "").strip()
228 self._doNotSanitizeFields.append("modifKey")
229 self._redirectURL = params.get("redirectURL", "")
231 def _process(self):
232 modif_keys = session.get("modifKeys")
233 if modif_keys and modif_keys.pop(self._conf.getId(), None):
234 session.modified = True
235 if self._redirectURL != "":
236 url = self._redirectURL
237 else:
238 url = urlHandlers.UHConferenceDisplay.getURL(self._conf)
239 self._redirect(url)
242 class RHConferenceClose(RHConferenceModifBase):
243 _uh = urlHandlers.UHConferenceClose
245 def _checkParams(self, params):
246 RHConferenceBase._checkParams(self, params)
247 self._confirm = params.has_key("confirm")
248 self._cancel = params.has_key("cancel")
250 def _process(self):
252 if self._cancel:
253 url = urlHandlers.UHConferenceModification.getURL(self._conf)
254 self._redirect(url)
255 elif self._confirm:
256 self._target.setClosed(True)
257 url = urlHandlers.UHConferenceModification.getURL(self._conf)
258 self._redirect(url)
259 else:
260 return conferences.WPConfClosing(self, self._conf).display()
263 class RHConferenceOpen(RHConferenceModifBase):
264 _allowClosed = True
266 def _checkProtection(self):
267 RHConferenceModifBase._checkProtection(self)
269 user = self._getUser()
270 if user is self._conf.getCreator():
271 return
272 # If we are not the creator, check if we have category admin privileges
273 hasAccess = False
274 for owner in self._conf.getOwnerList():
275 if owner.canUserModify(user): # category or system admin
276 hasAccess = True
277 break
278 if not hasAccess:
279 if self._conf.isClosed():
280 raise ConferenceClosedError(self._target.getConference())
281 else:
282 raise ModificationError()
284 def _checkParams(self, params):
285 RHConferenceBase._checkParams(self, params)
287 def _process(self):
288 self._target.setClosed(False)
289 url = urlHandlers.UHConferenceModification.getURL(self._conf)
290 self._redirect(url)
293 class RHConfDataModif(RHConferenceModifBase):
294 _uh = urlHandlers.UHConfDataModif
296 def _displayCustomPage(self, wf):
297 return None
299 def _displayDefaultPage(self):
300 p = conferences.WPConfDataModif(self, self._target)
301 pars = {}
302 wf = self.getWebFactory()
303 if wf is not None:
304 pars["type"] = wf.getId()
305 return p.display(**pars)
308 class RHConfPerformDataModif(RHConferenceModifBase):
309 _uh = urlHandlers.UHConfPerformDataModif
311 def _checkParams( self, params ):
312 RHConferenceModifBase._checkParams( self, params )
313 if params.get("title", "").strip() =="" and not ("cancel" in params):
314 raise FormValuesError("Please, provide a name for the event")
315 self._cancel = params.has_key("cancel")
317 def _process( self ):
318 if not self._cancel:
319 UtilsConference.setValues( self._conf, self._getRequestParams() )
320 self._redirect( urlHandlers.UHConferenceModification.getURL( self._conf) )
323 #----------------------------------------------------------------
325 class RHConfModifSchedule(RHConferenceModifBase):
326 _uh = urlHandlers.UHConfModifSchedule
328 def _checkParams( self, params ):
329 RHConferenceModifBase._checkParams( self, params )
330 params["sessions"] = self._normaliseListParam( params.get("session", []) )
331 params["slot"] = params.get("slot", [])
332 params["days"] = params.get("day", "all")
333 params["contributions"] = self._normaliseListParam( params.get("contribution", []) )
334 if params.get("session", None) is not None :
335 del params["session"]
336 if params.get("day", None) is not None :
337 del params["day"]
339 def _process( self ):
341 # The timetable management page shouldn't be cached
342 self._disableCaching();
344 params = self._getRequestParams()
346 if self._conf.isClosed():
347 p = conferences.WPConferenceModificationClosed( self, self._target )
348 return p.display()
349 elif params['sessions'] == []:
350 p = conferences.WPConfModifScheduleGraphic( self, self._target )
352 wf=self.getWebFactory()
353 if wf is not None:
354 p=wf.getConfModifSchedule( self, self._target )
355 return p.display(**params)
356 else:
358 session = self._target.getSessionById(params['sessions'][0])
360 p = sessions.WPSessionModifSchedule( self, session )
362 wf=self.getWebFactory()
363 if wf is not None:
364 p=wf.getSessionModifSchedule( self, session )
365 return p.display(**params)
367 class RHScheduleDataEdit(RHConferenceModifBase):
368 _uh = urlHandlers.UHConfModScheduleDataEdit
370 def _checkParams(self,params):
371 RHConferenceModifBase._checkParams(self,params)
372 self._action=""
373 if params.has_key("CANCEL"):
374 self._action="CANCEL"
375 elif params.has_key("OK"):
376 self._action="EDIT"
377 self._sDate,self._eDate=None,None
378 try:
379 self._sDate=datetime(int(params["sYear"]),
380 int(params["sMonth"]),
381 int(params["sDay"]),
382 int(params["sHour"]),
383 int(params["sMin"]))
384 except ValueError:
385 raise MaKaCError( _("Please enter integers in all the start date fields"), _("Schedule"))
386 try:
387 self._eDate=datetime(int(params["eYear"]),
388 int(params["eMonth"]),
389 int(params["eDay"]),
390 int(params["eHour"]),
391 int(params["eMin"]))
392 except ValueError:
393 raise MaKaCError( _("Please enter integers in all the end date fields"), _("Schedule"))
395 def _process( self ):
396 url=urlHandlers.UHConfModifSchedule.getURL(self._target)
397 if self._action=="CANCEL":
398 self._redirect(url)
399 return
400 elif self._action=="EDIT":
402 # The times are naive relative to the conference tz, must
403 # convert to UTC.
405 confTZ = self._target.getTimezone()
406 sd = timezone(confTZ).localize(datetime(self._sDate.year,
407 self._sDate.month,
408 self._sDate.day,
409 self._sDate.hour,
410 self._sDate.minute))
411 sdUTC = sd.astimezone(timezone('UTC'))
412 ed = timezone(confTZ).localize(datetime(self._eDate.year,
413 self._eDate.month,
414 self._eDate.day,
415 self._eDate.hour,
416 self._eDate.minute))
417 edUTC = ed.astimezone(timezone('UTC'))
418 self._target.setDates(sdUTC,edUTC)
419 self._redirect(url)
420 return
421 p=conferences.WPModScheduleDataEdit(self,self._target)
422 return p.display()
425 class RConferenceGetSessions(RHConferenceModifBase):
427 def _process(self):
428 from MaKaC.common.fossilize import fossilize
429 return json.dumps(fossilize(self._conf.getSessionList(), ISessionBasicFossil))
432 #-------------------------------------------------------------------------------------
435 class RHConfModifAC( RHConferenceModifBase ):
436 _uh = urlHandlers.UHConfModifAC
438 def _process( self ):
439 if self._conf.isClosed():
440 p = conferences.WPConferenceModificationClosed( self, self._target )
441 return p.display()
442 else:
443 p = conferences.WPConfModifAC( self, self._target)
444 wf=self.getWebFactory()
445 if wf is not None:
446 p = wf.getConfModifAC(self, self._conf)
447 return p.display()
450 class RHConfSetVisibility( RHConferenceModifBase ):
451 _uh = urlHandlers.UHConfSetVisibility
453 def _checkParams( self, params ):
454 RHConferenceModifBase._checkParams( self, params )
455 if params.has_key("changeToPrivate"):
456 self._protectConference = 1
457 elif params.has_key("changeToInheriting"):
458 self._protectConference = 0
459 elif params.has_key("changeToPublic"):
460 self._protectConference = -1
462 def _process( self ):
463 self._conf.setProtection( self._protectConference )
464 self._redirect( urlHandlers.UHConfModifAC.getURL( self._conf ) )
466 class RHConfGrantSubmissionToAllSpeakers( RHConferenceModifBase ):
467 _uh = urlHandlers.UHConfGrantSubmissionToAllSpeakers
469 def _process( self ):
470 for cont in self._target.getContributionList():
471 speakers = cont.getSpeakerList()[:]
472 for sCont in cont.getSubContributionList():
473 speakers += sCont.getSpeakerList()[:]
474 for speaker in speakers:
475 cont.grantSubmission(speaker,False)
476 self._redirect( urlHandlers.UHConfModifAC.getURL( self._target ) )
478 class RHConfRemoveAllSubmissionRights( RHConferenceModifBase ):
479 _uh = urlHandlers.UHConfRemoveAllSubmissionRights
481 def _process( self ):
482 for cont in self._target.getContributionList():
483 cont.revokeAllSubmitters()
484 self._redirect( urlHandlers.UHConfModifAC.getURL( self._target ) )
486 class RHConfGrantModificationToAllConveners( RHConferenceModifBase ):
487 _uh = urlHandlers.UHConfGrantModificationToAllConveners
489 def _process( self ):
490 for ses in self._target.getSessionList():
491 for slot in ses.getSlotList():
492 for convener in slot.getConvenerList():
493 ses.grantModification(convener,False)
494 self._redirect( urlHandlers.UHConfModifAC.getURL( self._target ) )
497 class RHConfDeletion(RHConferenceModifBase):
498 _uh = urlHandlers.UHConfDeletion
500 def _checkParams( self, params ):
501 RHConferenceModifBase._checkParams( self, params )
502 self._confirm = params.has_key( "confirm" )
503 self._cancel = params.has_key( "cancel" )
505 def _process( self ):
506 if self._cancel:
507 self._redirect( urlHandlers.UHConfModifTools.getURL( self._conf ) )
508 elif self._confirm:
509 parent=None
510 if self._conf.getOwnerList()!=[]:
511 parent=self._conf.getOwnerList()[0]
512 self._conf.delete(session.user)
513 if parent is not None:
514 self._redirect( urlHandlers.UHCategoryModification.getURL(parent) )
515 else:
516 self._redirect( urlHandlers.UHWelcome.getURL() )
517 else:
518 return conferences.WPConfDeletion( self, self._conf ).display()
520 class RHConfModifParticipants( RHConferenceModifBase ):
521 _uh = urlHandlers.UHConfModifParticipants
523 def _process( self ):
524 if self._conf.isClosed():
525 return conferences.WPConferenceModificationClosed( self, self._target ).display()
526 else:
527 return conferences.WPConfModifParticipants( self, self._target ).display()
529 class RHConfModifParticipantsSetup(RHConferenceModifBase):
530 _uh = urlHandlers.UHConfModifParticipantsSetup
532 def _process( self ):
533 if self._conf.isClosed():
534 return conferences.WPConferenceModificationClosed( self, self._target ).display()
535 else:
536 return conferences.WPConfModifParticipantsSetup( self, self._target ).display()
538 class RHConfModifParticipantsPending(RHConferenceModifBase):
539 _uh = urlHandlers.UHConfModifParticipantsPending
541 def _process( self ):
542 if self._conf.isClosed():
543 return conferences.WPConferenceModificationClosed( self, self._target ).display()
544 elif self._target.getParticipation().getPendingParticipantList() and nowutc() < self._target.getStartDate():
545 return conferences.WPConfModifParticipantsPending( self, self._target ).display()
546 else:
547 return self._redirect(RHConfModifParticipants._uh.getURL(self._conf))
549 class RHConfModifParticipantsDeclined(RHConferenceModifBase):
550 _uh = urlHandlers.UHConfModifParticipantsDeclined
552 def _process( self ):
553 if self._conf.isClosed():
554 return conferences.WPConferenceModificationClosed( self, self._target ).display()
555 elif self._target.getParticipation().getDeclinedParticipantList():
556 return conferences.WPConfModifParticipantsDeclined( self, self._target ).display()
557 else:
558 return self._redirect(RHConfModifParticipants._uh.getURL(self._conf))
561 class RHConfModifParticipantsAction(RHConfModifParticipants):
562 _uh = urlHandlers.UHConfModifParticipantsAction
564 def _process( self ):
565 params = self._getRequestParams()
566 selectedList = self._normaliseListParam(self._getRequestParams().get("participants",[]))
567 toList = []
568 if selectedList == []:
569 raise FormValuesError(_("No participant selected! Please select at least one."))
570 else:
571 for id in selectedList :
572 participant = self._conf.getParticipation().getParticipantById(id)
573 toList.append(participant)
574 excel = ParticipantsListToExcel(self._conf, list=toList)
575 return send_file('ParticipantList.csv', StringIO(excel.getExcelFile()), 'CSV')
578 class RHConfModifParticipantsStatistics(RHConferenceModifBase):
579 _uh = urlHandlers.UHConfModifParticipantsStatistics
581 def _process( self ):
582 if self._conf.isClosed():
583 return conferences.WPConferenceModificationClosed( self, self._target ).display()
584 else:
585 return conferences.WPConfModifParticipantsStatistics( self, self._target ).display()
588 #######################################################################################
590 class RHConfClone( RHConferenceModifBase ):
591 _uh = urlHandlers.UHConfClone
592 _allowClosed = True
594 def _process( self ):
595 p = conferences.WPConfClone( self, self._conf )
596 wf=self.getWebFactory()
597 if wf is not None:
598 p = wf.getConfClone(self, self._conf)
599 return p.display()
602 #######################################################################################
604 class RHConfAllSessionsConveners( RHConferenceModifBase ):
605 _uh = urlHandlers.UHConfAllSessionsConveners
607 def _process(self):
608 p = conferences.WPConfAllSessionsConveners( self, self._conf )
609 # wf=self.getWebFactory()
610 # if wf is not None:
611 # p = wf.getConfClone(self, self._conf)
613 return p.display()
615 class RHConfAllSessionsConvenersAction( RHConferenceModifBase ):
617 def _checkParams( self, params ):
618 RHConferenceModifBase._checkParams(self, params)
619 self._selectedConveners = self._normaliseListParam(params.get("conveners",[]))
621 def _process( self ):
622 if len(self._selectedConveners)>0:
623 p = conferences.WPEMailConveners(self, self._conf, self._selectedConveners)
624 return p.display()
625 else:
626 self._redirect(urlHandlers.UHConfAllSessionsConveners.getURL(self._conf))
628 class RHConvenerSendEmail( RHConferenceModifBase ):
630 def _checkParams(self, params):
631 RHConferenceModifBase._checkParams( self, params )
633 self._toEmails = []
634 cclist = []
636 self._send = params.has_key("OK")
637 if self._send:
638 if len(params.get("toEmails","").strip()) > 0 :
639 self._toEmails = (params.get("toEmails","").strip()).split(",")
640 else :
641 raise FormValuesError( _("'To' address list is empty"))
642 if params.get("from","") == "":
643 raise FormValuesError( _("Please write from address"))
644 if params.get("subject","") == "":
645 raise FormValuesError( _("Please write a subject for the email"))
646 if params.get("body","") == "":
647 raise FormValuesError( _("Please write a body for the email"))
648 #####cclist emails
649 cclist = params.get("cc","").strip().split(",")
650 # remove empty elements
651 if '' in cclist:
652 cclist.remove('')
653 # strip all the elements in the list
654 cclist = map(lambda x: x.strip(), cclist)
655 #####
657 self._params={}
658 self._params["subject"]=params["subject"]
659 self._params["from"]=params["from"]
660 self._params["body"]=params["body"]
661 self._params["cc"]=cclist
662 self._params["conf"] = self._conf
663 self._preview = params.has_key("preview")
665 def _process(self):
666 if self._send:
667 self._params['to'] = self._toEmails
668 registrantNotificator.EmailNotificator().notifyAll(self._params)
669 p = conferences.WPConvenerSentEmail(self, self._target)
670 return p.display()
671 else:
672 self._redirect(urlHandlers.UHConfAllSessionsConveners.getURL(self._conf))
674 #######################################################################################
677 class RHConfAllSpeakers( RHConferenceModifBase ):
678 _uh = urlHandlers.UHConfAllSpeakers
680 def _process(self):
681 p = conferences.WPConfAllSpeakers( self, self._conf )
682 return p.display()
684 class RHConfAllSpeakersAction( RHConferenceModifBase ):
686 def _checkParams( self, params ):
687 RHConferenceModifBase._checkParams(self, params)
688 self._selectedSpeakers = self._normaliseListParam(params.get("participants",[]))
690 def _process( self ):
692 if len(self._selectedSpeakers)>0:
693 p = conferences.WPEMailContribParticipants(self, self._conf, self._selectedSpeakers)
694 return p.display()
695 else:
696 self._redirect(urlHandlers.UHConfAllSpeakers.getURL(self._conf))
698 class RHContribParticipantsSendEmail( RHConferenceModifBase ):
700 def _checkParams(self, params):
701 RHConferenceModifBase._checkParams( self, params )
703 self._toEmails = []
704 cclist = []
706 self._send = params.has_key("OK")
707 if self._send:
708 if len(params.get("toEmails","").strip()) > 0 :
709 self._toEmails = (params.get("toEmails","").strip()).split(",")
710 else :
711 raise FormValuesError( _("'To' address list is empty"))
712 if params.get("from","") == "":
713 raise FormValuesError( _("Please write from address"))
714 if params.get("subject","") == "":
715 raise FormValuesError( _("Please write a subject for the email"))
716 if params.get("body","") == "":
717 raise FormValuesError( _("Please write a body for the email"))
718 #####cclist emails
719 cclist = params.get("cc","").strip().split(",")
720 # remove empty elements
721 if '' in cclist:
722 cclist.remove('')
723 # strip all the elements in the list
724 cclist = map(lambda x: x.strip(), cclist)
725 #####
727 self._params={}
728 self._params["subject"]=params["subject"]
729 self._params["from"]=params["from"]
730 self._params["body"]=params["body"]
731 self._params["cc"]=cclist
732 self._params["conf"] = self._conf
733 self._preview = params.has_key("preview")
735 def _process(self):
736 if self._send:
737 self._params['to'] = self._toEmails
738 registrantNotificator.EmailNotificator().notifyAll(self._params)
739 p = conferences.WPContribParticipationSentEmail(self, self._target)
740 return p.display()
741 else:
742 self._redirect(urlHandlers.UHConfAllSpeakers.getURL(self._conf))
745 #######################################################################################
748 class RHConfPerformCloning(RHConferenceModifBase, object):
750 New version of clone functionality -
751 fully replace the old one, based on three different actions,
752 adds mechanism of selective cloning of materials and access
753 privileges attached to an event
755 _uh = urlHandlers.UHConfPerformCloning
756 _cloneType = "none"
757 _allowClosed = True
759 def _checkParams( self, params ):
760 RHConferenceModifBase._checkParams( self, params )
761 self._date = datetime.today()
762 self._cloneType = params.get("cloneType", None)
763 if self._cloneType is None:
764 raise FormValuesError( _("""Please choose a cloning interval for this event"""))
765 elif self._cloneType == "once" :
766 self._date = datetime( int(params["stdyo"]), \
767 int(params["stdmo"]), \
768 int(params["stddo"]), \
769 int(self._conf.getAdjustedStartDate().hour), \
770 int(self._conf.getAdjustedStartDate().minute) )
771 elif self._cloneType == "intervals" :
772 self._date = datetime( int(params["indyi"]), \
773 int(params["indmi"]), \
774 int(params["inddi"]), \
775 int(self._conf.getAdjustedStartDate().hour), \
776 int(self._conf.getAdjustedStartDate().minute) )
777 elif self._cloneType == "days" :
778 self._date = datetime( int(params["indyd"]), \
779 int(params["indmd"]), \
780 int(params["inddd"]), \
781 int(self._conf.getAdjustedStartDate().hour), \
782 int(self._conf.getAdjustedStartDate().minute) )
783 self._confirm = params.has_key( "confirm" )
784 self._cancel = params.has_key( "cancel" )
786 def _process( self ):
787 params = self._getRequestParams()
788 paramNames = params.keys()
789 options = { "access" : "cloneAccess" in paramNames,
790 "keys" : "cloneAccess" in paramNames,
791 "authors" : "cloneTimetable" in paramNames,
792 "contributions" : "cloneTimetable" in paramNames,
793 "subcontribs" : "cloneTimetable" in paramNames,
794 "sessions" : "cloneTimetable" in paramNames,
795 "tracks" : "cloneTracks" in paramNames,
796 "registration" : "cloneRegistration" in paramNames,
797 "abstracts" : "cloneAbstracts" in paramNames,
798 "participants" : "cloneParticipants" in paramNames,
799 "evaluation" : "cloneEvaluation" in paramNames,
800 "managing" : self._getUser()
802 #we notify the event in case any plugin wants to add their options
803 if self._cancel:
804 self._redirect( urlHandlers.UHConfClone.getURL( self._conf ) )
805 elif self._confirm:
806 if self._cloneType == "once" :
807 newConf = self._conf.clone( self._date, options, userPerformingClone = self._aw._currentUser )
808 self._redirect( urlHandlers.UHConferenceModification.getURL( newConf ) )
809 elif self._cloneType == "intervals" :
810 self._withIntervals(options)
811 elif self._cloneType == "days" :
812 self._days(options)
813 else :
814 self._redirect( urlHandlers.UHConfClone.getURL( self._conf ) )
815 else:
816 if self._cloneType == "once" :
817 nbClones = 1
818 elif self._cloneType == "intervals" :
819 nbClones = self._withIntervals(options,0)
820 elif self._cloneType == "days" :
821 nbClones = self._days(options,0)
822 return conferences.WPConfCloneConfirm( self, self._conf, nbClones ).display()
824 def _withIntervals(self, options, confirmed=1):
825 nbClones = 0
826 params = self._getRequestParams()
827 if params["freq"] == "day":
828 inter = timedelta(int(params["period"]))
829 elif params["freq"] == "week":
830 inter = timedelta( 7*int(params["period"]))
832 if params["intEndDateChoice"] == "until":
833 date=self._date
834 endDate = datetime(int(params["stdyi"]),int(params["stdmi"]),int(params["stddi"]), self._conf.getEndDate().hour,self._conf.getEndDate().minute)
835 while date <= endDate:
836 if confirmed:
837 self._conf.clone(date,options, userPerformingClone = self._aw._currentUser)
838 nbClones += 1
839 if params["freq"] == "day" or params["freq"] == "week":
840 date = date + inter
841 elif params["freq"] == "month":
842 month = int(date.month) + int(params["period"])
843 year = int(date.year)
844 while month > 12:
845 month = month - 12
846 year = year + 1
847 date = datetime(year,month,int(date.day), int(date.hour), int(date.minute))
848 elif params["freq"] == "year":
849 date = datetime(int(date.year)+int(params["period"]),int(date.month),int(date.day), int(date.hour), int(date.minute))
851 elif params["intEndDateChoice"] == "ntimes":
852 date = self._date
854 stop = int(params["numi"])
855 while i < stop:
856 i = i + 1
857 if confirmed:
858 self._conf.clone(date,options, userPerformingClone = self._aw._currentUser)
859 nbClones += 1
860 if params["freq"] == "day" or params["freq"] == "week":
861 date = date + inter
862 elif params["freq"] == "month":
863 month = int(date.month) + int(params["period"])
864 year = int(date.year)
865 while month > 12:
866 month = month - 12
867 year = year + 1
868 date = datetime(year,month,int(date.day), int(date.hour), int(date.minute))
869 elif params["freq"] == "year":
870 date = datetime(int(date.year)+int(params["period"]),int(date.month),int(date.day), int(date.hour), int(date.minute))
871 if confirmed:
872 self._redirect( urlHandlers.UHCategoryDisplay.getURL( self._conf.getOwner() ) )
873 return "done"
874 else:
875 return nbClones
877 def _getFirstDay(self, date, day):
879 return the first day 'day' for the month of 'date'
881 td = datetime(int(date.year), int(date.month), 1, int(date.hour), int(date.minute))
883 oneDay = timedelta(1)
884 while 1:
885 if td.weekday() == day:
886 return td
887 td = td + oneDay
889 def _getOpenDay(self, date, day):
891 return the first open day for the month of 'date'
893 if day!="last": # last open day of the month
894 td = datetime(int(date.year), int(date.month), int(date.day), int(date.hour), int(date.minute))
895 if td.weekday() > 4:
896 td = td + timedelta(7 - td.weekday())
897 td += timedelta(int(day)-1)
898 else:
899 td = self._getLastDay(date, -1)
900 if td.weekday() > 4:
901 td = td - timedelta(td.weekday() - 4)
902 return td
904 def _getLastDay(self, date, day):
906 return the last day 'day' for the month of 'date'
908 td = datetime(int(date.year), int(date.month), 28, int(date.hour), int(date.minute))
909 month=td.month
910 while td.month == month:
911 td += timedelta(1)
912 td -= timedelta(1)
913 if day==-1:
914 return td
915 else:
916 while 1:
917 if td.weekday() == day:
918 return td
919 td = td - timedelta(1)
921 def _days(self, options, confirmed=1):
922 nbClones = 0
923 params = self._getRequestParams()
924 #search the first day of the month
926 if params["day"] == "NOVAL":
927 #self._endRequest()
928 self.redirect( urlHandlers.UHConfClone.getURL( self._target ) )
930 if params["daysEndDateChoice"] == "until":
931 date = self._date
933 endDate = datetime(int(params["stdyd"]),int(params["stdmd"]),int(params["stddd"]),self._conf.getEndDate().hour,self._conf.getEndDate().minute)
935 if params["day"] == "OpenDay":
936 rd = self._getOpenDay(date, params["order"])
937 else:
938 if params["order"] == "last":
939 rd = self._getLastDay(date, int(params["day"]))
940 if rd < date:
941 date = (date + relativedelta(months=1)).replace(day=1)
942 else:
943 rd = self._getFirstDay(date, int(params["day"])) + timedelta((int(params["order"])-1)*7)
944 if rd < date:
945 date = (date + relativedelta(months=1)).replace(day=1)
946 while date <= endDate:
947 if params["day"] == "OpenDay":
948 od=self._getOpenDay(date,params["order"])
949 if od <= endDate:
950 if confirmed:
951 self._conf.clone(od, options, userPerformingClone = self._aw._currentUser)
952 nbClones += 1
953 else:
954 if params["order"] == "last":
955 if self._getLastDay(date,int(params["day"])) <= endDate:
956 if confirmed:
957 self._conf.clone(self._getLastDay(date,int(params["day"])), options, userPerformingClone = self._aw._currentUser)
958 nbClones += 1
959 else:
960 if self._getFirstDay(date, int(params["day"])) + timedelta((int(params["order"])-1)*7) <= endDate:
961 if confirmed:
962 self._conf.clone(self._getFirstDay(date, int(params["day"]))+ timedelta((int(params["order"])-1)*7), options, userPerformingClone = self._aw._currentUser)
963 nbClones += 1
964 month = int(date.month) + int(params["monthPeriod"])
965 year = int(date.year)
966 while month > 12:
967 month = month - 12
968 year = year + 1
969 date = datetime(year,month,1, int(date.hour), int(date.minute))
971 elif params["daysEndDateChoice"] == "ntimes":
973 date = self._date
974 if params["day"] == "OpenDay":
975 rd = self._getOpenDay(date,params["order"])
976 else:
977 if params["order"] == "last":
978 rd = self._getLastDay(date, int(params["day"]))
979 if rd < date:
980 date = (date + relativedelta(months=1)).replace(day=1)
981 else:
982 rd = self._getFirstDay(date, int(params["day"])) + timedelta((int(params["order"])-1)*7)
983 if rd < date:
984 date = (date + relativedelta(months=1)).replace(day=1)
987 stop = int(params["numd"])
988 while i < stop:
989 i = i + 1
990 if params["day"] == "OpenDay":
991 if confirmed:
992 self._conf.clone(self._getOpenDay(date, params["order"]), options, userPerformingClone = self._aw._currentUser)
993 nbClones += 1
994 else:
995 if params["order"] == "last":
996 if confirmed:
997 self._conf.clone(self._getLastDay(date,int(params["day"])), options, userPerformingClone = self._aw._currentUser)
998 nbClones += 1
999 else:
1000 if confirmed:
1001 self._conf.clone(self._getFirstDay(date, int(params["day"]))+ timedelta((int(params["order"])-1)*7), options, userPerformingClone = self._aw._currentUser)
1002 nbClones += 1
1003 month = int(date.month) + int(params["monthPeriod"])
1004 year = int(date.year)
1005 while month > 12:
1006 month = month - 12
1007 year = year + 1
1008 date = datetime(year,month,int(date.day), int(date.hour), int(date.minute))
1009 if confirmed:
1010 self._redirect( urlHandlers.UHCategoryDisplay.getURL( self._conf.getOwner() ) )
1011 else:
1012 return nbClones
1014 ####################################################################################
1017 class RHConfModifProgram( RHConferenceModifBase ):
1019 def _process( self ):
1020 p = conferences.WPConfModifProgram( self, self._target )
1021 return p.display()
1024 class RHConfAddTrack( RHConferenceModifBase ):
1026 def _process( self ):
1027 p = conferences.WPConfAddTrack( self, self._target )
1028 return p.display()
1031 class RHConfPerformAddTrack( RHConferenceModifBase ):
1033 def _checkParams( self, params ):
1034 RHConferenceModifBase._checkParams( self, params )
1035 self._cancel = params.has_key("cancel")
1037 def _process( self ):
1038 if self._cancel:
1039 self._redirect( urlHandlers.UHConfModifProgram.getURL( self._conf ) )
1040 else:
1041 t = self._conf.newTrack()
1042 params = self._getRequestParams()
1043 t.setTitle(params["title"])
1044 t.setDescription(params["description"])
1045 # Filtering criteria: by default make new contribution type checked
1046 dct = session.setdefault("ContributionFilterConf%s" % self._conf.getId(), {})
1047 if 'tracks' in dct:
1048 #Append the new type to the existing list
1049 newDict = dct['tracks'][:]
1050 newDict.append(t.getId())
1051 dct['tracks'] = newDict[:]
1052 else:
1053 #Create a new entry for the dictionary containing the new type
1054 dct['tracks'] = [t.getId()]
1055 session.modified = True
1056 self._redirect( urlHandlers.UHConfModifProgram.getURL( self._conf ) )
1058 class RHConfDelTracks( RHConferenceModifBase ):
1060 def _checkParams( self, params ):
1061 RHConferenceModifBase._checkParams( self, params )
1062 self._trackList = []
1063 for id in self._normaliseListParam( params.get("selTracks", []) ):
1064 self._trackList.append( self._conf.getTrackById( id ) )
1066 def _process( self ):
1067 for track in self._trackList:
1068 self._conf.removeTrack( track )
1069 self._redirect( urlHandlers.UHConfModifProgram.getURL( self._conf ) )
1072 class RHProgramTrackUp(RHConferenceModifBase):
1074 def _checkParams( self, params ):
1075 RHConferenceModifBase._checkParams( self, params )
1076 self._track=self._target.getTrackById(params.get("trackId",""))
1078 def _process( self ):
1079 self._disableCaching()
1080 self._target.moveUpTrack(self._track)
1081 self._redirect(urlHandlers.UHConfModifProgram.getURL(self._conf))
1084 class RHProgramTrackDown(RHConferenceModifBase):
1086 def _checkParams( self, params ):
1087 RHConferenceModifBase._checkParams( self, params )
1088 self._track=self._target.getTrackById(params.get("trackId",""))
1090 def _process( self ):
1091 self._disableCaching()
1092 self._target.moveDownTrack(self._track)
1093 self._redirect(urlHandlers.UHConfModifProgram.getURL(self._conf))
1095 class CFAEnabled(object):
1096 @staticmethod
1097 def checkEnabled(request):
1098 """ Returns true if abstracts has been enabled
1099 Otherwise, throws an exception
1101 if request._conf.hasEnabledSection("cfa"):
1102 return True
1103 else:
1104 raise MaKaCError( _("You cannot access this option because \"Abstracts\" was disabled"))
1106 class RHConfModifCFABase(RHConferenceModifBase):
1108 def _checkProtection(self):
1109 RHConferenceModifBase._checkProtection(self)
1110 CFAEnabled.checkEnabled(self)
1112 class RHConfModifCFA(RHConfModifCFABase):
1114 def _process( self ):
1115 p = conferences.WPConfModifCFA( self, self._target )
1116 return p.display()
1119 class RHConfModifCFAPreview(RHConfModifCFABase):
1121 def _process( self ):
1122 p = conferences.WPConfModifCFAPreview( self, self._target )
1123 return p.display()
1126 class RHConfModifCFAStatus( RHConfModifCFABase ):
1128 def _checkParams( self, params ):
1129 RHConfModifCFABase._checkParams( self, params )
1130 self._newStatus = params["changeTo"]
1132 def _process( self ):
1133 if self._newStatus == "True":
1134 self._conf.getAbstractMgr().activeCFA()
1135 else:
1136 self._conf.getAbstractMgr().desactiveCFA()
1137 self._redirect( urlHandlers.UHConfModifCFA.getURL( self._conf ) )
1140 class RHConfModifCFASwitchMultipleTracks( RHConfModifCFABase ):
1142 def _process( self ):
1143 self._conf.getAbstractMgr().setMultipleTracks(not self._conf.getAbstractMgr().getMultipleTracks())
1144 self._redirect( urlHandlers.UHConfModifCFA.getURL( self._conf ) )
1146 class RHConfModifCFAMakeTracksMandatory( RHConfModifCFABase ):
1148 def _process( self ):
1149 self._conf.getAbstractMgr().setTracksMandatory(not self._conf.getAbstractMgr().areTracksMandatory())
1150 self._redirect( urlHandlers.UHConfModifCFA.getURL( self._conf ) )
1153 class RHConfModifCFASwitchAttachFiles( RHConfModifCFABase ):
1155 def _process( self ):
1156 self._conf.getAbstractMgr().setAllowAttachFiles(not self._conf.getAbstractMgr().canAttachFiles())
1157 self._redirect( urlHandlers.UHConfModifCFA.getURL( self._conf ) )
1160 class RHConfModifCFASwitchShowSelectAsSpeaker( RHConfModifCFABase ):
1162 def _process( self ):
1163 self._conf.getAbstractMgr().setShowSelectAsSpeaker(not self._conf.getAbstractMgr().showSelectAsSpeaker())
1164 self._redirect( urlHandlers.UHConfModifCFA.getURL( self._conf ) )
1166 class RHConfModifCFASwitchSelectSpeakerMandatory( RHConfModifCFABase ):
1168 def _process( self ):
1169 self._conf.getAbstractMgr().setSelectSpeakerMandatory(not self._conf.getAbstractMgr().isSelectSpeakerMandatory())
1170 self._redirect( urlHandlers.UHConfModifCFA.getURL( self._conf ) )
1172 class RHConfModifCFASwitchShowAttachedFilesContribList( RHConfModifCFABase ):
1174 def _process( self ):
1175 self._conf.getAbstractMgr().setSwitchShowAttachedFilesContribList(not self._conf.getAbstractMgr().showAttachedFilesContribList())
1176 self._redirect( urlHandlers.UHConfModifCFA.getURL( self._conf ) )
1179 class RHCFADataModification( RHConfModifCFABase ):
1181 def _process( self ):
1182 p = conferences.WPCFADataModification( self, self._target )
1183 return p.display()
1186 class RHCFAPerformDataModification( RHConfModifCFABase ):
1188 def _checkParams( self, params ):
1189 RHConfModifCFABase._checkParams( self, params )
1190 self._cancel = params.has_key("cancel")
1191 self._modifDL = None
1192 mDay = str( params.get( "mDay", "" ) ).strip()
1193 mMonth = str( params.get( "mMonth", "" ) ).strip()
1194 mYear = str( params.get( "mYear", "" ) ).strip()
1195 if mDay != "" and mMonth !="" and mYear != "":
1196 self._modifDL = datetime( int(mYear), int(mMonth), int(mDay) )
1198 def _process( self ):
1199 if self._cancel:
1200 self._redirect( urlHandlers.UHConfModifCFA.getURL( self._conf ) )
1201 else:
1202 abMgr = self._conf.getAbstractMgr()
1203 params = self._getRequestParams()
1205 abMgr.setStartSubmissionDate(datetime(int(params["sYear"]), int(params["sMonth"]), int(params["sDay"])))
1206 abMgr.setEndSubmissionDate(datetime(int(params["eYear"]), int(params["eMonth"]), int(params["eDay"])))
1207 try:
1208 sDate = datetime(int(params["sYear"]), int(params["sMonth"]), int(params["sDay"]))
1209 except ValueError, e:
1210 raise FormValuesError("The start date you have entered is not correct: %s" % e, "Abstracts")
1211 try:
1212 eDate = datetime(int(params["eYear"]), int(params["eMonth"]), int(params["eDay"]))
1213 except ValueError, e:
1214 raise FormValuesError("The end date you have entered is not correct: %s" % e, "Abstracts")
1215 if eDate < sDate:
1216 raise FormValuesError("End date can't be before start date!", "Abstracts")
1217 try:
1218 mDate = None
1219 if params["mYear"] or params["mMonth"] or params["mDay"]:
1220 mDate = datetime(int(params["mYear"]), int(params["mMonth"]), int(params["mDay"]))
1221 except ValueError, e:
1222 raise FormValuesError("The modification end date you have entered is not correct: %s" % e, "Abstracts")
1223 if mDate is not None and mDate < eDate:
1224 raise FormValuesError("Modification end date must be after end date!", "Abstracts")
1226 abMgr.setAnnouncement(params["announcement"])
1227 abMgr.setModificationDeadline(self._modifDL)
1228 abMgr.getSubmissionNotification().setToList(utils.getEmailList(params.get("toList", "")))
1229 abMgr.getSubmissionNotification().setCCList(utils.getEmailList(params.get("ccList", "")))
1230 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
1233 class AbstractStatusFilter( filters.FilterField ):
1234 """Contains the filtering criteria for the status of an abstract.
1236 Implements the logic to determine whether abstracts are within a list
1237 of abstract status. Objects of this class will keep a list of status
1238 names; then an abstract will satisfy the filter if it is in an abstract
1239 which name is included in the list of values.
1241 Inherits from: AbstractFilterField
1243 Attributes:
1244 _values -- (list) List of abstract status names; if the name of the
1245 current status of an abstract is included in this list, the
1246 abstract will satisfy the filter field.
1247 _showNoValue -- (bool) Not used for this filter field.
1249 _id = "status"
1251 def satisfies( self, abstract ):
1252 if len(AbstractStatusList.getInstance().getStatusList()) == len(self._values):
1253 return True
1254 else:
1255 status = AbstractStatusList.getInstance().getId( abstract.getCurrentStatus().__class__ )
1256 return status in self._values
1258 def needsToBeApplied(self):
1259 for s in AbstractStatusList.getStatusList():
1260 if AbstractStatusList.getInstance().getId(s) not in self._values:
1261 return True
1262 return False
1265 class AbstractFilterCriteria(filters.FilterCriteria):
1268 _availableFields = {
1269 abstractFilters.TrackFilterField.getId(): \
1270 abstractFilters.TrackFilterField, \
1271 abstractFilters.ContribTypeFilterField.getId(): \
1272 abstractFilters.ContribTypeFilterField, \
1273 AbstractStatusFilter.getId() : AbstractStatusFilter, \
1274 abstractFilters.CommentFilterField.getId(): \
1275 abstractFilters.CommentFilterField, \
1276 abstractFilters.AccContribTypeFilterField.getId():\
1277 abstractFilters.AccContribTypeFilterField,
1278 abstractFilters.AccTrackFilterField.getId():\
1279 abstractFilters.AccTrackFilterField }
1282 class _AbstractStatusSF( filters.SortingField ):
1283 _id = "status"
1285 def compare( self, a1, a2 ):
1286 a1Stat, a2Stat = a1.getCurrentStatus(), a2.getCurrentStatus()
1287 if a1Stat == a2Stat:
1288 return 0
1289 a1StatLabel = AbstractStatusList.getInstance().getCaption( a1Stat.__class__ )
1290 a2StatLabel = AbstractStatusList.getInstance().getCaption( a2Stat.__class__ )
1291 return cmp( a1StatLabel, a2StatLabel )
1294 class _AbstractIdSF( filters.SortingField ):
1295 _id = "number"
1297 def compare( self, a1, a2 ):
1298 try:
1299 a = int(a1.getId())
1300 b = int(a2.getId())
1301 except:
1302 a = a1.getId()
1303 b = a2.getId()
1304 return cmp( a, b )
1306 class _AbstractRatingSF( filters.SortingField ):
1307 _id = "rating"
1309 def compare( self, a1, a2 ):
1310 a = a1.getRating()
1311 b = a2.getRating()
1312 # check if the rating is none because the abstract has no judgement
1313 if a == None:
1314 a = -1.0
1315 if b == None:
1316 b = -1.0
1317 return cmp( a, b )
1319 class _AbstractTrackSF( filters.SortingField ):
1320 _id = "track"
1322 def compare( self, a1, a2 ):
1323 trackList1 = a1.getTrackList()
1324 trackList2 = a2.getTrackList()
1325 # check if there is track assignement for the abstract and get the list of ids if needed
1326 if len(trackList1) == 0:
1327 a = [-1]
1328 else:
1329 a = [track.getId() for track in trackList1]
1330 if len(trackList2) == 0:
1331 b = [-1]
1332 else:
1333 b = [track.getId() for track in trackList2]
1334 return cmp( a, b )
1336 class AbstractSortingCriteria( filters.SortingCriteria ):
1339 _availableFields = {
1340 abstractFilters.ContribTypeSortingField.getId(): \
1341 abstractFilters.ContribTypeSortingField, \
1342 _AbstractTrackSF.getId(): _AbstractTrackSF, \
1343 _AbstractStatusSF.getId(): _AbstractStatusSF, \
1344 _AbstractIdSF.getId(): _AbstractIdSF, \
1345 _AbstractRatingSF.getId(): _AbstractRatingSF, \
1346 abstractFilters.SubmissionDateSortingField.getId() : \
1347 abstractFilters.SubmissionDateSortingField, \
1348 abstractFilters.ModificationDateSortingField.getId() : \
1349 abstractFilters.ModificationDateSortingField
1353 class RHAbstractList(RHConfModifCFABase):
1354 _uh = urlHandlers.UHConfAbstractManagment
1356 def _resetFilters( self, sessionData ):
1358 Brings the filter data to a consistent state (websession),
1359 marking everything as "checked"
1362 sessionData["track"] = sessionData["acc_track"] = [track.getId() for track in self._conf.getTrackList()]
1363 sessionData["type"] = sessionData["acc_type"] = [ct.getId() for ct in self._conf.getContribTypeList()]
1364 abstractStatusList = AbstractStatusList.getInstance()
1365 sessionData["status"] = map(lambda status: abstractStatusList.getId( status ), abstractStatusList.getStatusList())
1366 sessionData['authSearch'] = ""
1368 sessionData["trackShowNoValue"] = True
1369 sessionData["typeShowNoValue"] = True
1370 sessionData["accTypeShowNoValue"] = True
1371 sessionData["accTrackShowNoValue"] = True
1372 sessionData["trackShowMultiple"] = False
1373 sessionData.pop("comment", None)
1375 return sessionData
1377 def _updateFilters( self, sessionData, params ):
1379 Updates the filter parameters in the websession with those
1380 coming from the HTTP request
1382 sessionData['track'] = []
1383 sessionData['acc_track'] = []
1384 sessionData['type'] = []
1385 sessionData['acc_type'] = []
1386 sessionData['status'] = []
1387 sessionData['authSearch'] = ""
1389 sessionData.update(params)
1391 sessionData['track'] = utils.normalizeToList(sessionData.get("track"))
1392 sessionData['status'] = utils.normalizeToList(sessionData.get("status"))
1393 sessionData['acc_track'] = utils.normalizeToList(sessionData.get("acc_track"))
1395 # update these elements in the session so that the parameters that are
1396 # passed are always taken into account (sessionData.update is not
1397 # enough, since the elements that are ommitted in params would just be
1398 # ignored
1400 sessionData['trackShowNoValue'] = params.has_key('trackShowNoValue')
1401 sessionData['trackShowMultiple'] = params.has_key("trackShowMultiple")
1402 sessionData['accTrackShowNoValue'] = params.has_key("accTrackShowNoValue")
1403 sessionData['typeShowNoValue'] = params.has_key('typeShowNoValue')
1404 sessionData['accTypeShowNoValue'] = params.has_key('accTypeShowNoValue')
1405 if params.has_key("comment"):
1406 sessionData['comment'] = ""
1407 elif sessionData.has_key("comment"):
1408 del sessionData['comment']
1409 return sessionData
1411 def _buildFilteringCriteria(self, sessionData):
1413 Creates the Filtering Criteria object, without changing the existing
1414 session data (sessionData is cloned, not directly changed)
1416 sessionCopy = sessionData.copy()
1418 # Build the filtering criteria
1419 filterCrit = AbstractFilterCriteria(self._conf, sessionCopy)
1421 filterCrit.getField("track").setShowNoValue(sessionCopy.get("trackShowNoValue"))
1422 filterCrit.getField("track").setOnlyMultiple(sessionCopy.get("trackShowMultiple"))
1423 filterCrit.getField("acc_track").setShowNoValue(sessionCopy.get("accTrackShowNoValue"))
1424 filterCrit.getField("type").setShowNoValue(sessionCopy.get("typeShowNoValue"))
1425 filterCrit.getField("acc_type").setShowNoValue(sessionCopy.get("accTypeShowNoValue"))
1427 return filterCrit
1429 def _checkAction( self, params, filtersActive, sessionData, operation ):
1431 Decides what to do with the request parameters, depending
1432 on the type of operation that is requested
1434 # user chose to reset the filters
1435 if operation == 'resetFilters':
1436 self._filterUsed = False
1437 sessionData = self._resetFilters(sessionData)
1439 # user set the filters
1440 elif operation == 'setFilters':
1441 self._filterUsed = True
1442 sessionData = self._updateFilters(sessionData, params)
1444 # user has changed the display options
1445 elif operation == 'setDisplay':
1446 self._filterUsed = filtersActive
1447 sessionData['disp'] = params.get('disp',[])
1449 # session is empty (first time)
1450 elif not filtersActive:
1451 self._filterUsed = False
1452 sessionData = self._resetFilters(sessionData)
1453 else:
1454 self._filterUsed = True
1456 # preserve the order and sortBy parameters, whatever happens
1457 sessionData['order'] = params.get('order', 'down')
1458 sessionData['sortBy'] = params.get('sortBy', 'number')
1460 return sessionData
1462 def _checkParams( self, params ):
1463 RHConfModifCFABase._checkParams( self, params )
1465 operationType = params.get('operationType')
1467 # session data
1468 sessionData = session.get('abstractFilterAndSortingConf%s' % self._conf.getId())
1470 # check if there is information already
1471 # set in the session variables
1472 if sessionData:
1473 # work on a copy
1474 sessionData = sessionData.copy()
1475 filtersActive = sessionData['filtersActive']
1476 else:
1477 # set a default, empty dict
1478 sessionData = {}
1479 filtersActive = False
1481 if 'resetFilters' in params:
1482 operation = 'resetFilters'
1483 elif operationType == 'filter':
1484 operation = 'setFilters'
1485 elif operationType == 'display':
1486 operation = 'setDisplay'
1487 else:
1488 operation = None
1490 sessionData = self._checkAction(params, filtersActive, sessionData, operation)
1492 # Maintain the state abotu filter usage
1493 sessionData['filtersActive'] = self._filterUsed
1495 # Save the web session
1496 session['abstractFilterAndSortingConf%s' % self._conf.getId()] = sessionData
1498 self._filterCrit = self._buildFilteringCriteria(sessionData)
1500 self._sortingCrit = AbstractSortingCriteria( [sessionData.get( "sortBy", "number" ).strip()] )
1502 self._order = sessionData.get("order","down")
1504 self._msg = sessionData.get("directAbstractMsg","")
1505 self._authSearch = sessionData.get("authSearch", "")
1507 self._display = utils.normalizeToList(sessionData.get("disp",[]))
1509 def _process( self ):
1510 p = conferences.WPConfAbstractList(self,self._target, self._msg, self._filterUsed)
1511 return p.display( filterCrit = self._filterCrit,
1512 sortingCrit = self._sortingCrit,
1513 authSearch=self._authSearch, order=self._order,
1514 display = self._display)
1516 class RHAbstractsActions:
1518 class to select the action to do with the selected abstracts
1520 def process(self, params):
1521 if params.has_key("newAbstract"):
1522 return RHNewAbstract().process(params)
1523 elif params.has_key("pdf"):
1524 return RHAbstractsToPDF().process(params)
1525 elif params.has_key("excel"):
1526 return RHAbstractsListToExcel().process(params)
1527 elif params.has_key("xml"):
1528 return RHAbstractsToXML().process(params)
1529 elif params.has_key("auth"):
1530 return RHAbstractsParticipantList().process(params)
1531 elif params.has_key("merge"):
1532 return RHAbstractsMerge().process(params)
1533 elif params.has_key("acceptMultiple"):
1534 return RHAbstractManagmentAcceptMultiple().process(params)
1535 elif params.has_key("rejectMultiple"):
1536 return RHAbstractManagmentRejectMultiple().process(params)
1537 elif params.has_key("PKGA"):
1538 return RHMaterialPackageAbstract().process(params)
1539 return "no action to do"
1542 class RHAbstractsMerge(RHConfModifCFABase):
1544 def _checkParams(self, params):
1545 RHConfModifCFABase._checkParams(self, params)
1546 self._abstractIds = normaliseListParam(params.get("abstracts", []))
1547 self._targetAbsId = params.get("targetAbstract", "")
1548 self._inclAuthors = "includeAuthors" in params
1549 self._doNotify = "notify" in params
1550 self._comments = params.get("comments", "")
1551 self._action = ""
1552 if "CANCEL" in params:
1553 self._action = "CANCEL"
1554 elif "OK" in params:
1555 self._action = "MERGE"
1556 self._abstractIds = params.get("selAbstracts", "").split(",")
1557 else:
1558 self._doNotify = True
1560 def _process(self):
1561 errorList = []
1563 if self._action == "CANCEL":
1564 self._redirect(
1565 urlHandlers.UHConfAbstractManagment.getURL(self._target))
1566 return
1567 elif self._action == "MERGE":
1568 absMgr = self._target.getAbstractMgr()
1569 if len(self._abstractIds) == 0:
1570 errorList.append(
1571 _("No ABSTRACT TO BE MERGED has been specified"))
1572 else:
1573 self._abstracts = []
1574 for id in self._abstractIds:
1575 abst = absMgr.getAbstractById(id)
1576 if abst is None:
1577 errorList.append(_("ABSTRACT TO BE MERGED ID '%s' is not valid") % (id))
1578 else:
1579 statusKlass = abst.getCurrentStatus().__class__
1580 if statusKlass in (review.AbstractStatusAccepted,
1581 review.AbstractStatusRejected,
1582 review.AbstractStatusWithdrawn,
1583 review.AbstractStatusDuplicated,
1584 review.AbstractStatusMerged):
1585 label = AbstractStatusList.getInstance(
1586 ).getCaption(statusKlass)
1587 errorList.append(_("ABSTRACT TO BE MERGED %s is in status which does not allow to merge (%s)") % (abst.getId(), label.upper()))
1588 self._abstracts.append(abst)
1589 if self._targetAbsId == "":
1590 errorList.append(_("Invalid TARGET ABSTRACT ID"))
1591 else:
1592 if self._targetAbsId in self._abstractIds:
1593 errorList.append(_("TARGET ABSTRACT ID is among the ABSTRACT IDs TO BE MERGED"))
1594 self._targetAbs = absMgr.getAbstractById(self._targetAbsId)
1595 if self._targetAbs is None:
1596 errorList.append(_("Invalid TARGET ABSTRACT ID"))
1597 else:
1598 statusKlass = self._targetAbs.getCurrentStatus().__class__
1599 if statusKlass in (review.AbstractStatusAccepted,
1600 review.AbstractStatusRejected,
1601 review.AbstractStatusWithdrawn,
1602 review.AbstractStatusMerged,
1603 review.AbstractStatusDuplicated):
1604 label = AbstractStatusList.getInstance(
1605 ).getInstance().getCaption(statusKlass)
1606 errorList.append(_("TARGET ABSTRACT is in status which does not allow to merge (%s)") % label.upper())
1607 if len(errorList) == 0:
1608 for abs in self._abstracts:
1609 abs.mergeInto(self._getUser(), self._targetAbs,
1610 mergeAuthors=self._inclAuthors, comments=self._comments)
1611 if self._doNotify:
1612 abs.notify(EmailNotificator(), self._getUser())
1613 return self._redirect(urlHandlers.UHAbstractManagment.getURL(self._targetAbs))
1614 p = conferences.WPModMergeAbstracts(self, self._target)
1615 return p.display(absIdList=self._abstractIds,
1616 targetAbsId=self._targetAbsId,
1617 inclAuth=self._inclAuthors,
1618 comments=self._comments,
1619 errorMsgList=errorList,
1620 notify=self._doNotify)
1623 #Base class for multi abstract management
1624 class RHAbstractManagmentMultiple( RHConferenceModifBase ):
1626 def _checkParams( self, params ):
1627 RHConferenceModifBase._checkParams(self, params)
1628 abstractIds = params.get("abstracts",[])
1629 abMgr = self._conf.getAbstractMgr()
1630 self._abstracts = []
1631 #if single abstract id is sent it's not a list so it shouldn't be iterated
1632 if isinstance(abstractIds, types.ListType):
1633 for id in abstractIds:
1634 self._abstracts.append(abMgr.getAbstractById(id))
1635 else:
1636 self._abstracts.append(abMgr.getAbstractById(abstractIds))
1637 self._warningShown=params.has_key("confirm")
1638 self._comments = params.get("comments", "")
1639 self._doNotify=params.has_key("notify")
1641 #checks if notification email template is defined for all selected abstracts
1642 #returns List of abstracts which doesn't have required template
1643 def _checkNotificationTemplate(self, statusKlass):
1644 from MaKaC.webinterface.rh.abstractModif import _AbstractWrapper
1646 if statusKlass == review.AbstractStatusAccepted:
1647 cType=self._conf.getContribTypeById(self._typeId)
1649 abstractsWithMissingTemplate = []
1650 for abstract in self._abstracts:
1651 if statusKlass == review.AbstractStatusAccepted:
1652 status=statusKlass(abstract,None,self._track,cType)
1653 elif statusKlass == review.AbstractStatusRejected:
1654 status=statusKlass(abstract,None, None)
1655 else: # In case we pass an improper Status
1656 abstractsWithMissingTemplate.append(abstract)
1657 continue
1658 wrapper=_AbstractWrapper(status)
1659 if abstract.getOwner().getNotifTplForAbstract(wrapper) is None:
1660 abstractsWithMissingTemplate.append(abstract)
1661 return abstractsWithMissingTemplate
1663 #checks the status of selected abstracts
1664 #returns list of abstracts with improper status
1665 def _checkStatus(self):
1666 improperAbstracts = []
1667 for abstract in self._abstracts:
1668 status = abstract.getCurrentStatus()
1669 if not isinstance(status, AbstractStatusSubmitted) and \
1670 not isinstance(status, AbstractStatusProposedToAccept) and \
1671 not isinstance(status, AbstractStatusProposedToReject):
1672 improperAbstracts.append(abstract)
1673 return improperAbstracts
1676 class RHAbstractManagmentAcceptMultiple( RHAbstractManagmentMultiple ):
1678 def _checkParams( self, params ):
1679 RHAbstractManagmentMultiple._checkParams(self, params)
1680 self._accept = params.get("accept", None)
1681 self._track=self._conf.getTrackById(params.get("track", ""))
1682 self._session=self._conf.getSessionById(params.get("session", ""))
1683 self._typeId = params.get("type", "")
1685 def _process( self ):
1686 if self._abstracts != []:
1687 improperAbstracts = self._checkStatus()
1688 if improperAbstracts == []:
1689 if self._accept:
1690 improperTemplates = self._checkNotificationTemplate(review.AbstractStatusAccepted)
1691 if self._doNotify and not self._warningShown and improperTemplates != []:
1692 raise FormValuesError("""The abstracts with the following IDs can not be automatically
1693 notified: %s. Therefore, none of your request has been processed;
1694 go back, uncheck the relevant abstracts and try again."""%(", ".join(map(lambda x:x.getId(),improperTemplates))))
1695 cType=self._conf.getContribTypeById(self._typeId)
1696 for abstract in self._abstracts:
1697 abstract.accept(self._getUser(),self._track,cType,self._comments,self._session)
1698 if self._doNotify:
1699 n=EmailNotificator()
1700 abstract.notify(n,self._getUser())
1701 self._redirect(urlHandlers.UHConfAbstractManagment.getURL(self._conf))
1702 else:
1703 p = abstracts.WPAbstractManagmentAcceptMultiple( self, self._abstracts )
1704 return p.display( **self._getRequestParams() )
1705 else:
1706 raise FormValuesError("""The abstracts with the following IDs cannot be accepted because of their
1707 current status: %s. Therefore, none of your request has been processed;
1708 go back, uncheck the relevant abstracts and try again."""%(", ".join(map(lambda x:x.getId(),improperAbstracts))))
1709 else:
1710 raise FormValuesError("No abstracts selected")
1713 class RHAbstractManagmentRejectMultiple( RHAbstractManagmentMultiple ):
1715 def _checkParams( self, params ):
1716 RHAbstractManagmentMultiple._checkParams(self, params)
1717 self._reject = params.get("reject", None)
1718 self._comments = params.get("comments", "")
1719 self._doNotify=params.has_key("notify")
1720 self._warningShown=params.has_key("confirm")
1722 def _process( self ):
1723 if self._abstracts != []:
1724 improperAbstracts = self._checkStatus()
1725 if improperAbstracts == []:
1726 if self._reject:
1727 improperTemplates = self._checkNotificationTemplate(review.AbstractStatusRejected)
1728 if self._doNotify and not self._warningShown and improperTemplates != []:
1729 raise FormValuesError("""The abstracts with the following IDs can not be automatically
1730 notified: %s. Therefore, none of your request has been processed;
1731 go back, uncheck the relevant abstracts and try again."""%(", ".join(map(lambda x:x.getId(),improperTemplates))))
1732 for abstract in self._abstracts:
1733 abstract.reject(self._getUser(), self._comments)
1734 if self._doNotify:
1735 n=EmailNotificator()
1736 abstract.notify(n,self._getUser())
1737 self._redirect(urlHandlers.UHConfAbstractManagment.getURL(self._conf))
1738 else:
1739 p = abstracts.WPAbstractManagmentRejectMultiple( self, self._abstracts )
1740 return p.display( **self._getRequestParams() )
1741 else:
1742 raise FormValuesError("""The abstracts with the following IDs cannot be rejected because of their
1743 current status: %s. Therefore, none of your request has been processed;
1744 go back, uncheck the relevant abstracts and try again."""%(", ".join(map(lambda x:x.getId(),improperAbstracts))))
1745 else:
1746 raise FormValuesError("No abstracts selected")
1748 class RHAbstractSendNotificationMail(RHConfModifCFABase):
1750 def _checkParams( self, params ):
1751 RHConfModifCFABase._checkParams( self, params )
1752 notifTplId = params.get("notifTpl", "")
1753 self._notifTpl = self._conf.getAbstractMgr().getNotificationTplById(notifTplId)
1754 self._abstractIds = normaliseListParam( params.get("abstracts", []) )
1755 self._abstracts = []
1756 abMgr = self._conf.getAbstractMgr()
1757 for id in self._abstractIds:
1758 self._abstracts.append(abMgr.getAbstractById(id))
1760 def _process( self ):
1761 p = conferences.WPAbstractSendNotificationMail(self, self._conf, count )
1762 return p.display()
1765 class RHAbstractsToPDF(RHConfModifCFABase):
1767 def _checkParams( self, params ):
1768 RHConfModifCFABase._checkParams( self, params )
1769 self._abstractIds = normaliseListParam( params.get("abstracts", []) )
1771 def _process(self):
1772 tz = self._conf.getTimezone()
1773 if not self._abstractIds:
1774 return _("No abstract to print")
1776 pdf = ConfManagerAbstractsToPDF(self._conf, self._abstractIds, tz=tz)
1777 return send_file('Abstracts.pdf', pdf.generate(), 'PDF')
1780 class RHAbstractsToXML(RHConfModifCFABase):
1782 def _checkParams( self, params ):
1783 RHConfModifCFABase._checkParams( self, params )
1784 self._abstractIds = normaliseListParam( params.get("abstracts", []) )
1785 self._abstracts = []
1786 abMgr = self._conf.getAbstractMgr()
1787 for id in self._abstractIds:
1788 #if abMgr.getAbstractById(id).canView( self._aw ):
1789 self._abstracts.append(abMgr.getAbstractById(id))
1791 def _process(self):
1792 x = XMLGen()
1794 x.openTag("AbstractBook")
1795 x.writeTag("Conference", self._target.getConference().getTitle())
1796 for abstract in self._abstracts:
1797 x.openTag("abstract")
1798 x.writeTag("Id", abstract.getId())
1799 x.writeTag("Title", abstract.getTitle())
1800 x.writeTag("Content", abstract.getField("content"))
1801 for f in self._conf.getAbstractMgr().getAbstractFieldsMgr().getFields():
1802 id = f.getId()
1803 x.writeTag("field",abstract.getField(id),[("id",id)])
1804 l = []
1805 for au in abstract.getAuthorList():
1806 if abstract.isPrimaryAuthor(au):
1807 x.openTag("PrimaryAuthor")
1808 x.writeTag("FirstName", au.getFirstName())
1809 x.writeTag("FamilyName", au.getSurName())
1810 x.writeTag("Email", au.getEmail())
1811 x.writeTag("Affiliation", au.getAffiliation())
1812 x.closeTag("PrimaryAuthor")
1813 else:
1814 l.append(au)
1816 for au in l:
1817 x.openTag("Co-Author")
1818 x.writeTag("FirstName", au.getFirstName())
1819 x.writeTag("FamilyName", au.getSurName())
1820 x.writeTag("Email", au.getEmail())
1821 x.writeTag("Affiliation", au.getAffiliation())
1822 x.closeTag("Co-Author")
1824 for au in abstract.getSpeakerList():
1825 x.openTag("Speaker")
1826 x.writeTag("FirstName", au.getFirstName ())
1827 x.writeTag("FamilyName", au.getSurName())
1828 x.writeTag("Email", au.getEmail())
1829 x.writeTag("Affiliation", au.getAffiliation())
1830 x.closeTag("Speaker")
1832 #To change for the new contribution type system to:
1833 #x.writeTag("ContributionType", abstract.getContribType().getName())
1834 if abstract.getContribType() <> None:
1835 x.writeTag("ContributionType", abstract.getContribType().getName())
1836 else:
1837 x.writeTag("ContributionType", None)
1838 #x.writeTag("ContributionType", abstract.getContribType())
1840 for t in abstract.getTrackList():
1841 x.writeTag("Track", t.getTitle())
1842 accepted_track = abstract.getAcceptedTrack()
1843 if accepted_track:
1844 x.writeTag('AcceptedTrack', accepted_track.getTitle())
1846 x.closeTag("abstract")
1848 x.closeTag("AbstractBook")
1850 return send_file('Abstracts.xml', StringIO(x.getXml()), 'XML')
1853 #-------------------------------------------------------------------------------------
1855 class RHAbstractsListToExcel(RHConfModifCFABase):
1857 def _checkParams( self, params ):
1858 RHConfModifCFABase._checkParams( self, params )
1859 self._abstracts = normaliseListParam( params.get("abstracts", []) )
1860 self._display = self._normaliseListParam(params.get("disp",[]))
1862 def _process( self ):
1863 abstractList = []
1864 for abs_id in self._abstracts :
1865 abstractList.append(self._conf.getAbstractMgr().getAbstractById(abs_id))
1867 generator = AbstractListToExcel(self._conf,abstractList, self._display)
1868 return send_file('AbstractList.csv', StringIO(generator.getExcelFile()), 'CSV')
1871 #-------------------------------------------------------------------------------------
1873 class RHConfModifDisplayCustomization( RHConferenceModifBase ):
1874 _uh = urlHandlers.UHConfModifDisplayCustomization
1876 def _checkParams( self, params ):
1877 RHConferenceModifBase._checkParams( self, params )
1879 def _process( self ):
1880 p = conferences.WPConfModifDisplayCustomization(self, self._target)
1881 return p.display()
1883 class RHConfModifDisplayMenu( RHConferenceModifBase ):
1884 _uh = urlHandlers.UHConfModifDisplayMenu
1886 def _checkParams( self, params ):
1887 RHConferenceModifBase._checkParams( self, params )
1888 self._linkId = params.get("linkId", "")
1890 def _process( self ):
1891 p = conferences.WPConfModifDisplayMenu(self, self._target, self._linkId)
1892 return p.display()
1894 class RHConfModifDisplayResources( RHConferenceModifBase ):
1895 _uh = urlHandlers.UHConfModifDisplayResources
1897 def _checkParams( self, params ):
1898 RHConferenceModifBase._checkParams( self, params )
1900 def _process( self ):
1901 p = conferences.WPConfModifDisplayResources(self, self._target)
1902 return p.display()
1904 class RHConfModifDisplayConfHeader( RHConferenceModifBase ):
1905 _uh = urlHandlers.UHConfModifDisplayConfHeader
1907 def _checkParams( self, params ):
1908 RHConferenceModifBase._checkParams( self, params )
1909 self._optionalParams={}
1910 if params.has_key("modifiedText"):
1911 self._optionalParams["modifiedText"]=params.has_key("modifiedText")
1913 def _process( self ):
1914 p = conferences.WPConfModifDisplayConfHeader(self, self._target, optionalParams=self._optionalParams )
1915 return p.display()
1917 class RHConfModifDisplayAddLink( RHConferenceModifBase ):
1918 _uh = urlHandlers.UHConfModifDisplayAddLink
1920 def _checkParams( self, params ):
1921 RHConferenceModifBase._checkParams( self, params )
1922 self._linkId = params.get("linkId", "")
1923 self._cancel = params.get("cancel", "")
1924 self._submit = params.get("submit", "")
1925 self._params = params
1927 def _process( self ):
1928 if self._cancel:
1929 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
1930 target = menu
1931 if self._linkId:
1932 target = menu.getLinkById(self._linkId)
1933 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(target))
1934 elif self._submit:
1935 #create the link
1936 name = self._params.get("name", "[empty name]")
1937 if name.strip()=="":
1938 name="[empty name]"
1939 url = self._params.get("URL", "")
1940 displayTarget = self._params.get("displayTarget", "_blank")
1941 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
1942 target = menu
1943 if self._linkId:
1944 target = menu.getLinkById(self._linkId)
1945 link = displayMgr.ExternLink(name, url)
1946 link.setCaption(name)
1947 link.setDisplayTarget(displayTarget)
1948 target.addLink(link)
1949 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
1950 else:
1951 p = conferences.WPConfModifDisplayAddLink(self, self._target, self._linkId )
1952 return p.display()
1955 class RHConfModifDisplayAddPage( RHConferenceModifBase ):
1956 _uh = urlHandlers.UHConfModifDisplayAddLink
1958 def _checkParams( self, params ):
1959 RHConferenceModifBase._checkParams( self, params )
1960 self._linkId = params.get("linkId", "")
1961 self._cancel = params.get("cancel", "")
1962 self._submit = params.get("submit", "")
1963 self._params = params
1965 def _process( self ):
1966 if self._cancel:
1967 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
1968 target = menu
1969 if self._linkId:
1970 target = menu.getLinkById(self._linkId)
1971 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(target))
1972 elif self._submit:
1973 #create the page
1974 intPagesMgr=internalPagesMgr.InternalPagesMgrRegistery().getInternalPagesMgr(self._conf)
1975 intPage=internalPagesMgr.InternalPage(self._conf)
1976 intPage.setTitle(self._params.get("title","[no title]"))
1977 intPage.setContent(self._params.get("content",""))
1978 intPagesMgr.addPage(intPage)
1979 #create the link
1980 name = self._params.get("name", "[empty name]")
1981 if name.strip()=="":
1982 name="[empty name]"
1983 content = self._params.get("content", "")
1984 displayTarget = self._params.get("displayTarget", "_blank")
1985 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
1986 target = menu
1987 if self._linkId:
1988 target = menu.getLinkById(self._linkId)
1989 link = displayMgr.PageLink(name, intPage)
1990 link.setCaption(name)
1991 link.setDisplayTarget(displayTarget)
1992 target.addLink(link)
1993 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
1994 else:
1995 p = conferences.WPConfModifDisplayAddPage(self, self._target, self._linkId )
1996 return p.display()
1998 class RHConfModifDisplayAddSpacer( RHConferenceModifBase ):
1999 _uh = urlHandlers.UHConfModifDisplayAddSpacer
2002 def _process( self ):
2003 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2004 spacer = displayMgr.Spacer()
2005 menu.addLink(spacer)
2006 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(spacer))
2009 class RHConfModifDisplayRemoveLink( RHConferenceModifBase ):
2010 _uh = urlHandlers.UHConfModifDisplayRemoveLink
2012 def _checkParams( self, params ):
2013 RHConferenceModifBase._checkParams( self, params )
2014 self._linkId = params.get("linkId", "")
2015 self._cancel = params.get("cancel", "")
2016 self._confirm = params.get("confirm", "")
2019 def _process( self ):
2020 if self._cancel:
2021 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2022 link = menu.getLinkById(self._linkId)
2023 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2024 elif self._confirm:
2025 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2026 link = menu.getLinkById(self._linkId)
2027 if isinstance(link, displayMgr.SystemLink):
2028 raise MaKaCError( _("You cannot remove a system link"))
2029 parent = link.getParent()
2030 if link.getType() == "page":
2031 page = link.getPage()
2032 internalPagesMgr.InternalPagesMgrRegistery().getInternalPagesMgr(self._conf).removePage(page)
2033 parent.removeLink(link)
2034 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(self._target))
2035 else:
2036 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2037 link = menu.getLinkById(self._linkId)
2038 if link is None:
2039 raise NotFoundError( _("The link you are trying to delete no longer exists"))
2040 if isinstance(link, displayMgr.SystemLink):
2041 raise MaKaCError( _("You cannot remove a system link"))
2042 p = conferences.WPConfModifDisplayRemoveLink(self, self._target, link )
2043 return p.display()
2046 class RHConfModifDisplayToggleLinkStatus( RHConferenceModifBase ):
2047 _uh = urlHandlers.UHConfModifDisplayToggleLinkStatus
2049 def _checkParams( self, params ):
2050 RHConferenceModifBase._checkParams( self, params )
2051 self._linkId = params.get("linkId", "")
2054 def _process( self ):
2055 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2056 link=menu.getLinkById(self._linkId)
2057 if link.isEnabled():
2058 link.disable()
2059 else:
2060 link.enable()
2061 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2064 class RHConfModifDisplayToggleHomePage( RHConferenceModifBase ):
2065 _uh = urlHandlers.UHConfModifDisplayToggleHomePage
2067 def _checkParams( self, params ):
2068 RHConferenceModifBase._checkParams( self, params )
2069 self._linkId = params.get("linkId", "")
2072 def _process( self ):
2073 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2074 link=menu.getLinkById(self._linkId)
2075 if link.getPage().isHome():
2076 link.getPage().setHome(False)
2077 else:
2078 for page in internalPagesMgr.InternalPagesMgrRegistery().getInternalPagesMgr(self._conf).getPagesList():
2079 page.setHome(False)
2080 link.getPage().setHome(True)
2081 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2084 class RHConfModifDisplayUpLink( RHConferenceModifBase ):
2085 _uh = urlHandlers.UHConfModifDisplayUpLink
2087 def _checkParams( self, params ):
2088 RHConferenceModifBase._checkParams( self, params )
2089 self._linkId = params.get("linkId", "")
2092 def _process( self ):
2093 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2094 link = menu.getLinkById(self._linkId)
2095 parent = link.getParent()
2096 parent.upLink(link)
2097 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2100 class RHConfModifDisplayDownLink( RHConferenceModifBase ):
2101 _uh = urlHandlers.UHConfModifDisplayDownLink
2103 def _checkParams( self, params ):
2104 RHConferenceModifBase._checkParams( self, params )
2105 self._linkId = params.get("linkId", "")
2108 def _process( self ):
2109 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2110 link = menu.getLinkById(self._linkId)
2111 parent = link.getParent()
2112 parent.downLink(link)
2113 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2116 class RHConfModifDisplayToggleTimetableView(RHConferenceModifBase):
2117 _uh = urlHandlers.UHConfModifDisplayToggleTimetableView
2119 def _checkParams(self, params):
2120 RHConferenceModifBase._checkParams(self, params)
2121 self._linkId = params.get("linkId", "")
2123 def _process(self):
2124 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2125 link = menu.getLinkById(self._linkId)
2126 menu.set_timetable_detailed_view(not menu.is_timetable_detailed_view())
2127 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2130 class RHConfModifDisplayToggleTTDefaultLayout(RHConferenceModifBase):
2131 _uh = urlHandlers.UHConfModifDisplayToggleTTDefaultLayout
2133 def _checkParams(self, params):
2134 RHConferenceModifBase._checkParams(self, params)
2135 self._linkId = params.get("linkId", "")
2137 def _process(self):
2138 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2139 link = menu.getLinkById(self._linkId)
2140 menu.toggle_timetable_layout()
2141 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2144 class RHConfModifDisplayModifyData(RHConferenceModifBase):
2145 _uh = urlHandlers.UHConfModifDisplayRemoveLink
2147 def _checkParams(self, params):
2148 RHConferenceModifBase._checkParams(self, params)
2149 self._linkId = params.get("linkId", "")
2150 self._cancel = params.get("cancel", "")
2151 self._confirm = params.get("confirm", "")
2152 self._params = params
2154 def _process(self):
2156 if self._cancel:
2157 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2158 link = menu.getLinkById(self._linkId)
2159 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2160 elif self._confirm:
2161 #create the link
2162 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2163 link = menu.getLinkById(self._linkId)
2164 if isinstance(link, displayMgr.SystemLink):
2165 raise MaKaCError( _("You cannot modify a system link"))
2166 name=self._params.get("name","[empty name]")
2167 if name.strip()=="":
2168 name="[empty name]"
2169 link.setCaption(name)
2170 if isinstance(link, displayMgr.ExternLink):
2171 link.setURL(self._params["url"])
2172 elif isinstance(link, displayMgr.PageLink):
2173 link.getPage().setContent(self._params.get("content",""))
2174 link.setDisplayTarget(self._params.get("displayTarget", "_blank"))
2175 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2176 else:
2177 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2178 link = menu.getLinkById(self._linkId)
2179 if isinstance(link, displayMgr.SystemLink):
2180 raise MaKaCError( _("You cannot modify a system link"))
2181 if isinstance(link, displayMgr.ExternLink):
2182 p = conferences.WPConfModifDisplayModifyData(self, self._target, link )
2183 else:
2184 p = conferences.WPConfModifDisplayModifyPage(self, self._target, link )
2185 return p.display()
2187 class RHConfModifDisplayModifySystemData( RHConferenceModifBase ):
2188 _uh = urlHandlers.UHConfModifDisplayRemoveLink
2190 def _checkParams( self, params ):
2191 RHConferenceModifBase._checkParams( self, params )
2192 self._linkId = params.get("linkId", "")
2193 self._cancel = params.get("cancel", "")
2194 self._confirm = params.get("confirm", "")
2195 self._params = params
2197 def _process( self ):
2199 if self._cancel:
2200 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2201 link = menu.getLinkById(self._linkId)
2202 elif self._confirm:
2203 #create the link
2204 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2205 link = menu.getLinkById(self._linkId)
2206 if isinstance(link, displayMgr.SystemLink):
2207 name=self._params.get("name","[empty name]")
2208 if name.strip()=="":
2209 name="[empty name]"
2210 link.setCaption(name)
2211 else:
2212 menu = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getMenu()
2213 link = menu.getLinkById(self._linkId)
2214 if isinstance(link, displayMgr.SystemLink):
2215 p = conferences.WPConfModifDisplayModifySystemData(self, self._target, link )
2216 return p.display()
2217 self._redirect(urlHandlers.UHConfModifDisplayMenu.getURL(link))
2219 class RHConfModifFormatTitleColorBase( RHConferenceModifBase ):
2221 def _checkParams( self, params ):
2222 RHConferenceModifBase._checkParams( self, params )
2223 self._linkId = params.get("linkId", "")
2224 self._formatOption = params.get("formatOption", "")
2225 self._colorCode = params.get("colorCode", "")
2226 self._apply = params.has_key( "apply" )
2227 self._remove = params.has_key( "remove" )
2229 def _process( self ):
2230 format = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getFormat()
2231 if self._formatOption:
2232 if self._apply:
2233 format.setColorCode(self._formatOption, "#" + self._colorCode)
2234 elif self._remove:
2235 format.clearColorCode(self._formatOption)
2236 redirecturl = urlHandlers.UHConfModifDisplayCustomization.getURL(self._conf)
2237 redirecturl.addParam("formatOption", self._formatOption)
2238 self._redirect("%s#colors"%redirecturl)
2240 class RHConfModifFormatTitleBgColor( RHConfModifFormatTitleColorBase ):
2241 _uh = urlHandlers.UHConfModifFormatTitleBgColor
2243 class RHConfModifFormatTitleTextColor( RHConfModifFormatTitleColorBase ):
2244 _uh = urlHandlers.UHConfModifFormatTitleBgColor
2246 class RHConfSaveLogo( RHConferenceModifBase ):
2248 def _getNewTempFile( self ):
2249 cfg = Config.getInstance()
2250 tempPath = cfg.getUploadedFilesTempDir()
2251 tempFileName = tempfile.mkstemp( suffix="IndicoLogo.tmp", dir = tempPath )[1]
2252 return tempFileName
2254 def _saveFileToTemp(self, fs):
2255 fileName = self._getNewTempFile()
2256 fs.save(fileName)
2257 return fileName
2259 def _checkParams( self, params ):
2260 RHConferenceModifBase._checkParams( self, params )
2261 if not hasattr(self,"_filePath"):
2262 self._filePath = self._saveFileToTemp(params["file"])
2263 self._tempFilesToDelete.append(self._filePath)
2264 self._fileName = params["file"].filename
2267 def _process( self ):
2268 f = conference.LocalFile()
2269 f.setName( "Logo" )
2270 f.setDescription( "This is the logo for the conference" )
2271 f.setFileName( self._fileName )
2272 f.setFilePath( self._filePath )
2273 self._conf.setLogo( f )
2274 self._redirect( "%s#logo"%urlHandlers.UHConfModifDisplayCustomization.getURL( self._conf ) )
2277 class RHConfRemoveLogo( RHConferenceModifBase ):
2279 def _checkParams( self, params ):
2280 RHConferenceModifBase._checkParams( self, params )
2282 def _process( self ):
2283 self._conf.removeLogo()
2284 self._redirect( "%s#logo"%urlHandlers.UHConfModifDisplayCustomization.getURL( self._conf ) )
2286 class RHConfSaveCSS( RHConferenceModifBase ):
2288 def _getNewTempFile( self ):
2289 cfg = Config.getInstance()
2290 tempPath = cfg.getUploadedFilesTempDir()
2291 tempFileName = tempfile.mkstemp( suffix="IndicoCSS.tmp", dir = tempPath )[1]
2292 return tempFileName
2294 def _saveFileToTemp(self, fs):
2295 fileName = self._getNewTempFile()
2296 fs.save(fileName)
2297 return fileName
2299 def _checkParams( self, params ):
2300 RHConferenceModifBase._checkParams( self, params )
2301 self._params = params
2302 if self._params.has_key("FP"):
2303 self._filePath = self._params["FP"]
2304 self._fileName = "TemplateInUse"
2305 else:
2306 if not hasattr(self,"_filePath"):
2307 self._filePath = self._saveFileToTemp(params["file"])
2308 self._tempFilesToDelete.append(self._filePath)
2309 self._fileName = params["file"].filename
2310 if self._fileName.strip() == "":
2311 raise FormValuesError(_("Please, choose the file to upload first"))
2313 def _process( self ):
2314 f = conference.LocalFile()
2315 f.setName( "CSS" )
2316 f.setDescription( "This is the css for the conference" )
2317 f.setFileName( self._fileName )
2318 f.setFilePath( self._filePath )
2319 sm = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getStyleManager()
2320 sm.setCSS( f )
2321 self._redirect( "%s#css"%urlHandlers.UHConfModifDisplayCustomization.getURL( self._conf ) )
2324 class RHConfRemoveCSS( RHConferenceModifBase ):
2326 def _checkParams( self, params ):
2327 RHConferenceModifBase._checkParams( self, params )
2329 def _process( self ):
2330 sm = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getStyleManager()
2331 sm.removeCSS()
2332 # Since this function makes sure no template is used make sure that
2333 # one of the standard ones is not used
2334 sm.useLocalCSS()
2335 self._redirect( "%s#css"%urlHandlers.UHConfModifDisplayCustomization.getURL( self._conf ) )
2338 class RHConfModifPreviewCSS(RHConferenceModifBase):
2340 def _checkParams( self, params ):
2341 RHConferenceModifBase._checkParams( self, params )
2342 self._params = params
2344 def _process( self ):
2345 # Call a webpage that will handle the task
2346 CSS_Temp_Id = self._params.get("cssId", "")
2347 p = conferences.WPConfModifPreviewCSS(self, self._conf, CSS_Temp_Id)
2348 return p.display()
2351 class RHConfUseCSS( RHConferenceModifBase ):
2353 def _checkParams( self, params ):
2354 RHConferenceModifBase._checkParams( self, params )
2355 self._params = params
2356 self._selectedTpl = self._params.get("selectedTpl")
2358 def _process( self ):
2359 styleMgr = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getStyleManager()
2360 if self._selectedTpl == "css":
2361 styleMgr.useLocalCSS()
2362 elif self._selectedTpl:
2363 styleMgr.setCSS(self._selectedTpl)
2364 self._redirect( "%s#css"%urlHandlers.UHConfModifDisplayCustomization.getURL( self._conf ) )
2366 class RHConfSavePic( RHConferenceModifBase ):
2368 def __init__(self):
2369 RHConferenceModifBase.__init__(self)
2370 self._tempFiles = {}
2372 def _getNewTempFile( self ):
2373 cfg = Config.getInstance()
2374 tempPath = cfg.getUploadedFilesTempDir()
2375 tempFileName = tempfile.mkstemp( suffix="IndicoPic.tmp", dir = tempPath )[1]
2376 return tempFileName
2378 def _saveFileToTemp(self, fs):
2379 if fs not in self._tempFiles:
2380 fileName = self._getNewTempFile()
2381 fs.save(fileName)
2382 self._tempFiles[fs] = fileName
2383 return self._tempFiles[fs]
2385 def _checkParams( self, params ):
2386 RHConferenceModifBase._checkParams( self, params )
2387 self._filePath = self._saveFileToTemp(params["file"])
2388 self._tempFilesToDelete.append(self._filePath)
2389 self._fileName = params["file"].filename
2390 self._params = params
2393 def _process( self ):
2394 if self._fileName == "":
2395 return json.dumps({'status': "ERROR", 'info': {'message':_("No file has been attached")}})
2396 f = conference.LocalFile()
2397 f.setFileName( self._fileName )
2398 f.setFilePath( self._filePath )
2399 im = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf).getImagesManager()
2400 pic = im.addPic( f )
2401 info={"name": f.getFileName(),
2402 "id": f.getId(),
2403 "picURL": str(urlHandlers.UHConferencePic.getURL(pic))}
2404 return json.dumps({'status': "OK", 'info': info}, textarea=True)
2406 class RHConfModifTickerTapeAction( RHConferenceModifBase ):
2408 def _checkParams( self, params ):
2409 RHConferenceModifBase._checkParams( self, params )
2410 dm = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf)
2411 self._tickerTape=dm.getTickerTape()
2412 self._status=params.has_key("ttStatus")
2413 self._saveText=params.has_key("savettText")
2414 self._text=params.get("ttText","")
2415 self._simpleTextEnabled=params.has_key("simpleText")
2416 self._nowHappeningEnabled=params.has_key("nowHappening")
2418 def _process( self ):
2419 url=urlHandlers.UHConfModifDisplayConfHeader.getURL( self._conf )
2420 if self._status:
2421 self._tickerTape.setActive(not self._tickerTape.isActive())
2422 if self._saveText:
2423 self._tickerTape.setText(self._text)
2424 url.addParam("modifiedText", "True")
2425 if self._nowHappeningEnabled:
2426 self._tickerTape.setNowHappeningEnabled(not self._tickerTape.isNowHappeningEnabled())
2427 if self._simpleTextEnabled:
2428 self._tickerTape.setSimpleTextEnabled(not self._tickerTape.isSimpleTextEnabled())
2429 self._redirect( "%s#tickertape"%url )
2431 class RHConfModifToggleSearch( RHConferenceModifBase ):
2433 def _checkParams( self, params ):
2434 RHConferenceModifBase._checkParams( self, params )
2435 self._displayMgr = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf)
2436 self._searchEnabled=self._displayMgr.getSearchEnabled()
2438 def _process( self ):
2439 url=urlHandlers.UHConfModifDisplayConfHeader.getURL( self._conf )
2440 self._displayMgr.setSearchEnabled(not self._searchEnabled)
2441 self._redirect( "%s#headerFeatures"%url )
2444 class RHConfModifToggleNavigationBar( RHConferenceModifBase ):
2446 def _checkParams( self, params ):
2447 RHConferenceModifBase._checkParams( self, params )
2448 self._displayMgr = displayMgr.ConfDisplayMgrRegistery().getDisplayMgr(self._conf)
2449 self._navigationBarEnabled=self._displayMgr.getDisplayNavigationBar()
2451 def _process( self ):
2452 url=urlHandlers.UHConfModifDisplayConfHeader.getURL( self._conf )
2453 self._displayMgr.setDisplayNavigationBar(not self._navigationBarEnabled)
2454 self._redirect( "%s#headerFeatures"%url )
2456 class RHConfAddContribType(RHConferenceModifBase):
2457 _uh = urlHandlers.UHConfAddContribType
2459 def _checkParams(self, params):
2460 RHConferenceModifBase._checkParams(self, params)
2461 self._typeName = params.get("ctName", "")
2462 self._typeDescription = params.get("ctDescription", "")
2463 self._typeId = params.get("typeId", "")
2464 self._cancel = params.get("cancel", "")
2465 self._save = params.get("save", "")
2467 def _process( self ):
2468 if self._cancel:
2469 self._redirect(urlHandlers.UHConferenceModification.getURL(self._conf))
2470 elif self._save:
2471 ct = self._conf.newContribType(self._typeName, self._typeDescription)
2473 # Filtering criteria: by default make new contribution type checked
2474 filters = session.setdefault('ContributionFilterConf%s' % self._conf.getId(), {})
2475 if 'types' in filters:
2476 #Append the new type to the existing list
2477 newDict = filters['types'][:]
2478 newDict.append(ct.getId())
2479 filters['types'] = newDict[:]
2480 else:
2481 #Create a new entry for the dictionary containing the new type
2482 filters['types'] = [ct.getId()]
2483 session.modified = True
2485 self._redirect(urlHandlers.UHConferenceModification.getURL(self._conf))
2486 else:
2487 p = conferences.WPConfAddContribType(self, self._target )
2488 return p.display()
2491 class RHConfRemoveContribType(RHConferenceModifBase):
2492 _uh = urlHandlers.UHConfRemoveContribType
2494 def _checkParams(self, params):
2495 RHConferenceModifBase._checkParams(self, params)
2496 selTypeId = self._normaliseListParam( params.get( "types", [] ) )
2497 self._contribTypes = []
2498 for id in selTypeId:
2499 self._contribTypes.append(self._conf.getContribTypeById(id))
2502 def _process(self):
2503 for ct in self._contribTypes:
2504 self._conf.removeContribType(ct)
2505 self._redirect(urlHandlers.UHConferenceModification.getURL(self._conf))
2508 class RHConfContribTypeBase(RHConferenceModifBase):
2510 def _checkParams(self, params):
2511 RHConferenceModifBase._checkParams(self, params)
2512 l = locators.WebLocator()
2513 l.setContribType( params )
2514 self._contribType = self._target = l.getObject()
2517 class RHConfEditContribType(RHConfContribTypeBase):
2519 def _checkParams(self, params):
2520 RHConfContribTypeBase._checkParams(self, params)
2521 self._save = params.get("save", "")
2522 self._name = params.get("ctName", "")
2523 self._cancel = params.get("cancel", "")
2524 self._description = params.get("ctDescription", "")
2526 def _process(self):
2527 if self._cancel:
2528 self._redirect(urlHandlers.UHConferenceModification.getURL(self._conf))
2529 elif self._save:
2530 self._target.setName(self._name)
2531 self._target.setDescription(self._description)
2532 self._redirect(urlHandlers.UHConferenceModification.getURL(self._conf))
2533 else:
2534 p = conferences.WPConfEditContribType(self, self._target )
2535 return p.display()
2538 class ContribFilterCrit(filters.FilterCriteria):
2539 _availableFields = { \
2540 contribFilters.TypeFilterField.getId():contribFilters.TypeFilterField, \
2541 contribFilters.StatusFilterField.getId():contribFilters.StatusFilterField, \
2542 contribFilters.TrackFilterField.getId():contribFilters.TrackFilterField, \
2543 contribFilters.SessionFilterField.getId():contribFilters.SessionFilterField }
2546 class ContribSortingCrit(filters.SortingCriteria):
2547 _availableFields = {
2548 contribFilters.NumberSF.getId():contribFilters.NumberSF,
2549 contribFilters.DateSF.getId():contribFilters.DateSF,
2550 contribFilters.ContribTypeSF.getId():contribFilters.ContribTypeSF,
2551 contribFilters.TrackSF.getId():contribFilters.TrackSF,
2552 contribFilters.SpeakerSF.getId():contribFilters.SpeakerSF,
2553 contribFilters.BoardNumberSF.getId():contribFilters.BoardNumberSF,
2554 contribFilters.SessionSF.getId():contribFilters.SessionSF,
2555 contribFilters.TitleSF.getId():contribFilters.TitleSF
2559 class RHContributionListBase(RHConferenceModifBase):
2561 def _checkProtection(self):
2562 from MaKaC.webinterface.rh.reviewingModif import RCPaperReviewManager
2563 if not RCPaperReviewManager.hasRights(self):
2564 RHConferenceModifBase._checkProtection(self)
2567 class RHContributionList(RHContributionListBase):
2568 _uh = urlHandlers.UHConfModifContribList
2570 def _checkProtection(self):
2571 from MaKaC.webinterface.rh.reviewingModif import RCPaperReviewManager
2572 if not RCPaperReviewManager.hasRights(self):
2573 RHContributionListBase._checkProtection(self)
2575 def _resetFilters( self, sessionData ):
2577 Brings the filter data to a consistent state (websession),
2578 marking everything as "checked"
2581 sessionData.clear()
2582 sessionData["type"] = map(lambda ctype: ctype.getId(), self._conf.getContribTypeList())
2583 sessionData["track"] = map(lambda track: track.getId(), self._conf.getTrackList())
2584 sessionData["session"] = map(lambda ses: ses.getId(), self._conf.getSessionList())
2585 sessionData["status"] = map(lambda status: ContribStatusList.getId(status), ContribStatusList.getList())
2586 sessionData["typeShowNoValue"] = True
2587 sessionData["trackShowNoValue"] = True
2588 sessionData["sessionShowNoValue"] = True
2590 return sessionData
2592 def _updateFilters( self, sessionData, params ):
2594 Updates the filter parameters in the websession with those
2595 coming from the HTTP request
2598 sessionData["status"] = []
2599 sessionData.update(params)
2600 sessionData["type"] = utils.normalizeToList(params.get('types', []))
2601 sessionData["track"] = utils.normalizeToList(params.get('tracks', []))
2602 sessionData['session'] = utils.normalizeToList(params.get('sessions', []))
2604 # update these elements in the session so that the parameters that are
2605 # passed are always taken into account (sessionData.update is not
2606 # enough, since the elements that are ommitted in params would just be
2607 # ignored
2609 sessionData['typeShowNoValue'] = params.has_key('typeShowNoValue')
2610 sessionData['trackShowNoValue'] = params.has_key('trackShowNoValue')
2611 sessionData['sessionShowNoValue'] = params.has_key('sessionShowNoValue')
2613 return sessionData
2615 def _buildFilteringCriteria(self, sessionData):
2617 Creates the Filtering Criteria object, without changing the existing
2618 session data (sessionData is cloned, not directly changed)
2620 sessionCopy = sessionData.copy()
2622 # Build the filtering criteria
2623 filterCrit = ContribFilterCrit(self._conf, sessionCopy)
2625 filterCrit.getField("type").setShowNoValue(sessionCopy.get('typeShowNoValue'))
2626 filterCrit.getField("track").setShowNoValue(sessionCopy.get('trackShowNoValue'))
2627 filterCrit.getField("session").setShowNoValue(sessionCopy.get('sessionShowNoValue'))
2629 return filterCrit
2631 def _checkAction(self, params, filtersActive, sessionData, operation, isBookmark):
2633 Decides what to do with the request parameters, depending
2634 on the type of operation that is requested
2637 # user chose to reset the filters
2638 if operation == 'resetFilters':
2639 self._filterUsed = False
2640 sessionData = self._resetFilters(sessionData)
2642 # user set the filters
2643 elif operation == 'setFilters':
2644 self._filterUsed = True
2645 sessionData = self._updateFilters(sessionData, params)
2647 # user has changed the display options
2648 elif operation == 'setDisplay':
2649 self._filterUsed = filtersActive
2651 # session is empty (first time)
2652 elif not filtersActive:
2653 self._filterUsed = False
2654 sessionData = self._resetFilters(sessionData)
2655 else:
2656 self._filterUsed = True
2658 # if this is accessed through a direct link, the session is empty, so set default values
2659 if isBookmark:
2660 sessionData = self._resetFilters(sessionData)
2661 if operation != 'resetFilters':
2662 sessionData = self._updateFilters(sessionData, params)
2664 # preserve the order and sortBy parameters, whatever happens
2665 sessionData['order'] = params.get('order', 'down')
2666 sessionData['sortBy'] = params.get('sortBy', 'number')
2668 return sessionData
2670 def _checkParams( self, params ):
2671 RHContributionListBase._checkParams( self, params )
2672 operationType = params.get('operationType')
2673 sessionData = session.get('ContributionFilterConf%s' % self._conf.getId())
2675 # check if there is information already
2676 # set in the session variables
2677 if sessionData:
2678 # work on a copy
2679 sessionData = sessionData.copy()
2680 filtersActive = sessionData.get('filtersActive', False)
2681 else:
2682 # set a default, empty dict
2683 sessionData = {}
2684 filtersActive = False
2686 if params.has_key("resetFilters"):
2687 operation = 'resetFilters'
2688 elif operationType == 'filter':
2689 operation = 'setFilters'
2690 elif operationType == 'display':
2691 operation = 'setDisplay'
2692 else:
2693 operation = None
2695 isBookmark = params.has_key("isBookmark")
2696 sessionData = self._checkAction(params, filtersActive, sessionData, operation, isBookmark)
2697 # Maintain the state about filter usage
2698 sessionData['filtersActive'] = self._filterUsed;
2699 # Save the web session
2700 session['ContributionFilterConf%s' % self._conf.getId()] = sessionData
2701 self._filterCrit = self._buildFilteringCriteria(sessionData)
2702 self._sortingCrit = ContribSortingCrit([sessionData.get("sortBy", "number").strip()])
2703 self._order = sessionData.get("order", "down")
2704 self._authSearch = sessionData.get("authSearch", "")
2706 def _process( self ):
2707 p = conferences.WPModifContribList(self, self._target, self._filterUsed)
2708 return p.display(authSearch=self._authSearch,\
2709 filterCrit=self._filterCrit, sortingCrit=self._sortingCrit, order=self._order)
2712 class RHContribQuickAccess(RHConferenceModifBase):
2714 def _checkParams(self,params):
2715 RHConferenceModifBase._checkParams(self,params)
2716 self._contrib=self._target.getContributionById(params.get("selContrib",""))
2718 def _process(self):
2719 url=urlHandlers.UHConfModifContribList.getURL(self._target)
2720 if self._contrib is not None:
2721 url=urlHandlers.UHContributionModification.getURL(self._contrib)
2722 self._redirect(url)
2724 #-------------------------------------------------------------------------------------
2726 class RHAbstractsParticipantList(RHConfModifCFABase):
2728 def _checkProtection( self ):
2729 if len( self._conf.getCoordinatedTracks( self._getUser() ) ) == 0:
2730 RHConferenceModifBase._checkProtection( self )
2732 def _checkParams( self, params ):
2733 RHConfModifCFABase._checkParams( self, params )
2734 self._abstractIds = normaliseListParam( params.get("abstracts", []) )
2735 self._displayedGroups = params.get("displayedGroups", [])
2736 if type(self._displayedGroups) != list:
2737 self._displayedGroups = [self._displayedGroups]
2738 self._clickedGroup = params.get("clickedGroup","")
2740 def _setGroupsToDisplay(self):
2741 if self._clickedGroup in self._displayedGroups:
2742 self._displayedGroups.remove(self._clickedGroup)
2743 else:
2744 self._displayedGroups.append(self._clickedGroup)
2746 def _process( self ):
2747 #This is a plain text exception but an exception should be raised here !
2748 if not self._abstractIds:
2749 return _("There is no abstract.")
2751 submitters = OOBTree()
2752 primaryAuthors = OOBTree()
2753 coAuthors = OOBTree()
2754 submitterEmails = set()
2755 primaryAuthorEmails = set()
2756 coAuthorEmails = set()
2758 self._setGroupsToDisplay()
2760 abMgr = self._conf.getAbstractMgr()
2761 for abstId in self._abstractIds:
2762 abst = abMgr.getAbstractById(abstId)
2763 #Submitters
2765 subm = abst.getSubmitter()
2766 if subm.getSurName().lower().strip() != "" or subm.getFirstName().lower().strip() != "" or subm.getEmail().lower().strip() != "":
2767 keySB = "%s-%s-%s"%(subm.getSurName().lower(), subm.getFirstName().lower(), subm.getEmail().lower())
2768 submitters[keySB] = subm
2769 submitterEmails.add(subm.getEmail())
2770 #Primary authors
2771 for pAut in abst.getPrimaryAuthorList():
2772 if pAut.getSurName().lower().strip() == "" and pAut.getFirstName().lower().strip() == "" and pAut.getEmail().lower().strip() == "":
2773 continue
2774 keyPA = "%s-%s-%s"%(pAut.getSurName().lower(), pAut.getFirstName().lower(), pAut.getEmail().lower())
2775 primaryAuthors[keyPA] = pAut
2776 primaryAuthorEmails.add(pAut.getEmail())
2777 #Co-authors
2778 for coAut in abst.getCoAuthorList():
2779 if coAut.getSurName().lower().strip() == "" and coAut.getFirstName().lower().strip() == "" and coAut.getEmail().lower().strip() == "":
2780 continue
2781 keyCA = "%s-%s-%s"%(coAut.getSurName().lower(), coAut.getFirstName().lower(), coAut.getEmail().lower())
2782 coAuthors[keyCA] = coAut
2783 coAuthorEmails.add(coAut.getEmail())
2784 emailList = {"submitters":{},"primaryAuthors":{},"coAuthors":{}}
2785 emailList["submitters"]["tree"] = submitters
2786 emailList["primaryAuthors"]["tree"] = primaryAuthors
2787 emailList["coAuthors"]["tree"] = coAuthors
2788 emailList["submitters"]["emails"] = submitterEmails
2789 emailList["primaryAuthors"]["emails"] = primaryAuthorEmails
2790 emailList["coAuthors"]["emails"] = coAuthorEmails
2791 p = conferences.WPConfParticipantList(self, self._target, emailList, self._displayedGroups, self._abstractIds )
2792 return p.display()
2795 class RHNewAbstract(RHConfModifCFABase, AbstractParam):
2797 def __init__(self):
2798 RHConfModifCFABase.__init__(self)
2799 AbstractParam.__init__(self)
2801 def _checkParams(self, params):
2802 RHConfModifCFABase._checkParams(self, params)
2803 #if the user is not logged in we return immediately as this form needs
2804 # the user to be logged in and therefore all the checking below is not
2805 # necessary
2806 if self._getUser() is None:
2807 return
2808 AbstractParam._checkParams(self, params, self._conf, request.content_length)
2810 def _doValidate(self):
2811 #First, one must validate that the information is fine
2812 errors = self._abstractData.check()
2813 if errors:
2814 p = conferences.WPModNewAbstract(
2815 self, self._target, self._abstractData)
2816 pars = self._abstractData.toDict()
2817 pars["action"] = self._action
2818 return p.display(**pars)
2819 #Then, we create the abstract object and set its data to the one
2820 # received
2821 cfaMgr = self._target.getAbstractMgr()
2822 abstract = cfaMgr.newAbstract(self._getUser())
2823 #self._setAbstractData(abstract)
2824 self._abstractData.setAbstractData(abstract)
2825 #Finally, we display the abstract list page
2826 self._redirect(urlHandlers.UHConfAbstractList.getURL(self._conf))
2828 def _process(self):
2829 if self._action == "CANCEL":
2830 self._redirect(
2831 urlHandlers.UHConfAbstractManagment.getURL(self._target))
2832 elif self._action == "VALIDATE":
2833 return self._doValidate()
2834 else:
2835 p = conferences.WPModNewAbstract(
2836 self, self._target, self._abstractData)
2837 pars = self._abstractData.toDict()
2838 return p.display(**pars)
2842 class RHContribsActions:
2844 class to select the action to do with the selected abstracts
2846 def process(self, params):
2847 if params.has_key("PDF"):
2848 return RHContribsToPDF().process(params)
2849 elif params.has_key("excel.x"):
2850 return RHContribsToExcel().process(params)
2851 elif params.has_key("xml.x"):
2852 return RHContribsToXML().process(params)
2853 elif params.has_key("AUTH"):
2854 return RHContribsParticipantList().process(params)
2855 elif params.has_key("move"):
2856 return RHMoveContribsToSession().process(params)
2857 elif params.has_key("PKG"):
2858 return RHMaterialPackage().process(params)
2859 return "no action to do"
2862 class RHContribsToPDFMenu(RHConferenceModifBase):
2864 def _checkParams( self, params ):
2865 RHConferenceModifBase._checkParams( self, params )
2866 self._contribIds = self._normaliseListParam( params.get("contributions", []) )
2867 self._contribs = []
2868 for id in self._contribIds:
2869 self._contribs.append(self._conf.getContributionById(id))
2870 self._displayType = params.get("displaytype", None)
2872 def _process( self ):
2873 from MaKaC.PDFinterface.conference import ContributionBook
2874 if not self._displayType:
2875 wp = conferences.WPConfModifContribToPDFMenu(self, self._conf, self._contribIds)
2876 return wp.display()
2878 elif self._displayType == "bookOfAbstract":
2879 tz = self._target.getTimezone()
2880 filename = "{0} - Book of abstracts.pdf".format(self._target.getTitle())
2882 pdf = ContributionBook(self._target, self.getAW(), self._contribs, tz=tz)
2883 return send_file(filename, pdf.generate(), 'PDF')
2885 elif self._displayType == "bookOfAbstractBoardNo":
2886 tz = self._target.getTimezone()
2887 filename = "{0} - Book of abstracts.pdf".format(self._target.getTitle())
2888 pdf = ContributionBook(self._target, self.getAW(), self._contribs, tz=tz, sort_by="boardNo")
2889 return send_file(filename, pdf.generate(), 'PDF')
2891 elif self._displayType == "ContributionList":
2892 tz = self._conf.getTimezone()
2893 filename = "{0} - Contributions.pdf".format(self._target.getTitle())
2894 if not self._contribs:
2895 return "No contributions to print"
2897 contrib_pdf = ContribsToPDF(self._conf, self._contribs)
2898 fpath = contrib_pdf.generate()
2900 return send_file(filename, fpath, 'PDF')
2903 class RHContribsToPDF(RHConferenceModifBase):
2905 def _checkParams( self, params ):
2906 RHConferenceModifBase._checkParams( self, params )
2907 self._contribIds = self._normaliseListParam( params.get("contributions", []) )
2908 self._contribs = []
2909 for id in self._contribIds:
2910 self._contribs.append(self._conf.getContributionById(id))
2912 def _process( self ):
2913 tz = self._conf.getTimezone()
2914 filename = "Contributions.pdf"
2915 if not self._contribs:
2916 return "No contributions to print"
2917 pdf = ContribsToPDF(self._conf, self._contribs)
2918 return send_file(filename, pdf.generate(), 'PDF')
2921 class RHContribsToExcel(RHConferenceModifBase):
2923 def _checkParams( self, params ):
2924 RHConferenceModifBase._checkParams( self, params )
2925 self._contribIds = self._normaliseListParam( params.get("contributions", []) )
2926 self._contribs = []
2927 for id in self._contribIds:
2928 self._contribs.append(self._conf.getContributionById(id))
2930 def _process( self ):
2931 tz = self._conf.getTimezone()
2932 filename = "Contributions.csv"
2933 if not self._contribs:
2934 return "No contributions to print"
2935 excel = ContributionsListToExcel(self._conf, self._contribs, tz=tz)
2936 return send_file(filename, StringIO(excel.getExcelFile()), 'CSV')
2939 class RHContribsToXML(RHConferenceModifBase):
2941 def _checkParams( self, params ):
2942 RHConferenceModifBase._checkParams( self, params )
2943 self._contribIds = self._normaliseListParam( params.get("contributions", []) )
2944 self._contribs = []
2945 for id in self._contribIds:
2946 self._contribs.append(self._conf.getContributionById(id))
2947 def _process( self ):
2948 filename = "Contributions.xml"
2949 from MaKaC.common.fossilize import fossilize
2950 resultFossil = fossilize(self._contribs)
2951 serializer = Serializer.create('xml')
2952 return send_file(filename, StringIO(serializer(resultFossil)), 'XML')
2955 class RHContribsParticipantList(RHConferenceModifBase):
2957 def _checkParams( self, params ):
2958 RHConferenceModifBase._checkParams( self, params )
2959 self._contribIds = normaliseListParam( params.get("contributions", []) )
2960 self._displayedGroups = self._normaliseListParam( params.get("displayedGroups", []) )
2961 self._clickedGroup = params.get("clickedGroup","")
2963 def _setGroupsToDisplay(self):
2964 if self._clickedGroup in self._displayedGroups:
2965 self._displayedGroups.remove(self._clickedGroup)
2966 else:
2967 self._displayedGroups.append(self._clickedGroup)
2969 def _process( self ):
2970 if not self._contribIds:
2971 return i18nformat("""<table align=\"center\" width=\"100%%\"><tr><td> _("There are no contributions") </td></tr></table>""")
2973 speakers = OOBTree()
2974 primaryAuthors = OOBTree()
2975 coAuthors = OOBTree()
2976 speakerEmails = set()
2977 primaryAuthorEmails = set()
2978 coAuthorEmails = set()
2980 self._setGroupsToDisplay()
2982 for contribId in self._contribIds:
2983 contrib = self._conf.getContributionById(contribId)
2984 #Primary authors
2985 for pAut in contrib.getPrimaryAuthorList():
2986 if pAut.getFamilyName().lower().strip() == "" and pAut.getFirstName().lower().strip() == "" and pAut.getEmail().lower().strip() == "":
2987 continue
2988 keyPA = "%s-%s-%s"%(pAut.getFamilyName().lower(), pAut.getFirstName().lower(), pAut.getEmail().lower())
2989 primaryAuthors[keyPA] = pAut
2990 if pAut.getEmail() != "":
2991 primaryAuthorEmails.add(pAut.getEmail())
2992 #Co-authors
2993 for coAut in contrib.getCoAuthorList():
2994 if coAut.getFamilyName().lower().strip() == "" and coAut.getFirstName().lower().strip() == "" and coAut.getEmail().lower().strip() == "":
2995 continue
2996 keyCA = "%s-%s-%s"%(coAut.getFamilyName().lower(), coAut.getFirstName().lower(), coAut.getEmail().lower())
2997 coAuthors[keyCA] = coAut
2998 if coAut.getEmail() != "":
2999 coAuthorEmails.add(coAut.getEmail())
3000 #Presenters
3001 for pres in contrib.getSpeakerList():
3002 if pres.getFamilyName().lower().strip() == "" and pres.getFirstName().lower().strip() == "" and pres.getEmail().lower().strip() == "":
3003 continue
3004 keyP = "%s-%s-%s"%(pres.getFamilyName().lower(), pres.getFirstName().lower(), pres.getEmail().lower())
3005 speakers[keyP] = pres
3006 if pres.getEmail() != "":
3007 speakerEmails.add(pres.getEmail())
3008 emailList = {"speakers":{},"primaryAuthors":{},"coAuthors":{}}
3009 emailList["speakers"]["tree"] = speakers
3010 emailList["primaryAuthors"]["tree"] = primaryAuthors
3011 emailList["coAuthors"]["tree"] = coAuthors
3012 emailList["speakers"]["emails"] = speakerEmails
3013 emailList["primaryAuthors"]["emails"] = primaryAuthorEmails
3014 emailList["coAuthors"]["emails"] = coAuthorEmails
3015 p = conferences.WPConfModifParticipantList(self, self._target, emailList, self._displayedGroups, self._contribIds )
3016 return p.display()
3019 class RHMoveContribsToSession(RHConferenceModifBase):
3021 def _checkParams(self,params):
3022 RHConferenceModifBase._checkParams(self,params)
3023 self._action=""
3024 self._session=self._target.getSessionById(params.get("targetSession",""))
3025 self._contribIds=self._normaliseListParam(params.get("contributions",[]))
3026 if params.has_key("OK"):
3027 if self._session is not None and self._session.isClosed():
3028 raise NoReportError(_("""The modification of the session "%s" is not allowed because it is closed""")%self._session.getTitle())
3029 self._contribIds=self._normaliseListParam(params.get("contributions","").split(","))
3030 self._action="MOVE"
3031 elif params.has_key("CANCEL"):
3032 self._action="CANCEL"
3033 elif params.has_key("CONFIRM"):
3034 self._action="MOVE_CONFIRMED"
3035 elif params.has_key("CONFIRM_ALL"):
3036 self._action="MOVE_ALL_CONFIRMED"
3038 def _needsWarning(self,contrib):
3039 return (contrib.getSession() is not None and \
3040 contrib.getSession()!=self._session) or \
3041 (contrib.getSession() is None and \
3042 self._session is not None and \
3043 contrib.isScheduled())
3045 def _process( self ):
3046 url=urlHandlers.UHConfModifContribList.getURL(self._target)
3047 if self._action=="CANCEL":
3048 self._redirect(url)
3049 return
3050 elif self._action in ("MOVE","MOVE_CONFIRMED","MOVE_ALL_CONFIRMED"):
3051 contribList=[]
3052 for id in self._contribIds:
3053 contrib=self._target.getContributionById(id)
3054 if contrib is None:
3055 continue
3056 if self._needsWarning(contrib):
3057 if self._action=="MOVE":
3058 p=conferences.WPModMoveContribsToSessionConfirmation(self,self._target)
3059 return p.display(contribIds=self._contribIds,targetSession=self._session)
3060 elif self._action=="MOVE_CONFIRMED":
3061 continue
3062 if contrib.getSession() is not None and contrib.getSession().isClosed():
3063 raise NoReportError(_("""The contribution "%s" cannot be moved because it is inside of the session "%s" that is closed""")%(contrib.getId(), contrib.getSession().getTitle()))
3064 contribList.append(contrib)
3065 for contrib in contribList:
3066 contrib.setSession(self._session)
3067 self._redirect(url)
3068 return
3069 p=conferences.WPModMoveContribsToSession(self,self._target)
3070 return p.display(contribIds=self._contribIds)
3072 class RHMaterialPackageAbstract(RHConferenceModifBase):
3073 # Export a Zip file
3075 def _checkParams( self, params ):
3076 RHConferenceModifBase._checkParams( self, params )
3077 abstractIds = self._normaliseListParam( params.get("abstracts", []) )
3078 self._abstracts = []
3079 for aID in abstractIds:
3080 self._abstracts.append(self._conf.getAbstractMgr().getAbstractById(aID))
3082 def _process( self ):
3083 if not self._abstracts:
3084 return FormValuesError(_("No abstract selected"))
3085 p = AbstractPacker(self._conf)
3086 path = p.pack(self._abstracts, ZIPFileHandler())
3087 return send_file('abstractFiles.zip', path, 'ZIP', inline=False)
3090 class RHMaterialPackage(RHConferenceModifBase, AttachmentPackageGeneratorMixin):
3092 def _checkParams(self, params):
3093 RHConferenceModifBase._checkParams(self, params)
3094 self._contribIds = self._normaliseListParam(params.get("contributions", []))
3096 def _process(self):
3097 if not self._contribIds:
3098 flash(_('You did not select any contributions.'), 'warning')
3099 return redirect(url_for('event_mgmt.confModifContribList', self._conf))
3100 attachments = self._filter_by_contributions(self._contribIds, None)
3101 if not attachments:
3102 flash(_('The selected contributions do not have any materials.'), 'warning')
3103 return redirect(url_for('event_mgmt.confModifContribList', self._conf))
3104 return self._generate_zip_file(attachments)
3107 class RHAbstractBook( RHConfModifCFABase ):
3108 _uh = urlHandlers.UHConfModAbstractBook
3110 def _checkParams( self, params ):
3111 RHConfModifCFABase._checkParams( self, params )
3113 def _process( self ):
3114 p = conferences.WPModAbstractBook(self,self._target)
3115 return p.display()
3118 class RHAbstractBookToogleShowIds( RHConfModifCFABase ):
3119 _uh = urlHandlers.UHConfModAbstractBookToogleShowIds
3121 def _process( self ):
3122 self._conf.getBOAConfig().setShowIds(not self._conf.getBOAConfig().getShowIds())
3123 self._redirect( urlHandlers.UHConfModAbstractBook.getURL( self._conf ) )
3126 class RHModifSessionCoordRights( RHConferenceModifBase ):
3127 _uh = urlHandlers.UHConfPerformDataModif
3129 def _checkParams( self, params ):
3130 RHConferenceModifBase._checkParams( self, params )
3131 self._rightId = params.get("rightId", "")
3133 def _process( self ):
3134 if self._rightId != "":
3135 if self._conf.hasSessionCoordinatorRight(self._rightId):
3136 self._conf.removeSessionCoordinatorRight(self._rightId)
3137 else:
3138 self._conf.addSessionCoordinatorRight(self._rightId)
3139 self._redirect( "%s#sessionCoordinatorRights"%urlHandlers.UHConfModifAC.getURL( self._conf) )
3142 class RHConfModifPendingQueues( RHConferenceModifBase ):
3143 _uh = urlHandlers.UHConfModifPendingQueues
3145 def _process( self ):
3146 p = conferences.WPConfModifPendingQueues( self, self._target, self._getRequestParams().get("tab","conf_submitters") )
3147 return p.display()
3149 class RHConfModifPendingQueuesActionConfMgr:
3151 class to select the action to do with the selected pending conference submitters
3154 _uh = urlHandlers.UHConfModifPendingQueuesActionConfMgr
3156 def process(self, params):
3157 if 'remove' in params:
3158 return RHConfModifPendingQueuesRemoveConfMgr().process(params)
3159 elif 'reminder' in params:
3160 return RHConfModifPendingQueuesReminderConfMgr().process(params)
3161 return "no action to do"
3163 class RHConfModifPendingQueuesRemoveConfMgr( RHConferenceModifBase ):
3165 def _checkParams( self, params ):
3166 RHConferenceModifBase._checkParams( self, params )
3167 self._pendingConfMgrIds = self._normaliseListParam( params.get("pendingUsers", []) )
3168 self._pendingConfMgrs = []
3169 for id in self._pendingConfMgrIds:
3170 self._pendingConfMgrs.extend(self._conf.getPendingQueuesMgr().getPendingConfManagersByEmail(id))
3171 self._remove=params.has_key("confirm")
3172 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3174 def _process( self ):
3175 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3176 url.addParam("tab","conf_managers")
3177 if self._pendingConfMgrs == []:
3178 self._redirect(url)
3179 if self._confirmed:
3180 if self._remove:
3181 for ps in self._pendingConfMgrs:
3182 self._conf.getPendingQueuesMgr().removePendingConfManager(ps)
3183 self._redirect(url)
3184 else:
3185 wp = conferences.WPConfModifPendingQueuesRemoveConfMgrConfirm(self, self._conf, self._pendingConfMgrIds)
3186 return wp.display()
3188 class RHConfModifPendingQueuesReminderConfMgr( RHConferenceModifBase ):
3190 def _checkParams( self, params ):
3191 RHConferenceModifBase._checkParams( self, params )
3192 self._pendingConfMgrIds = self._normaliseListParam( params.get("pendingUsers", []) )
3193 self._pendingConfMgrs = []
3194 for email in self._pendingConfMgrIds:
3195 self._pendingConfMgrs.append(self._conf.getPendingQueuesMgr().getPendingConfManagersByEmail(email))
3196 self._send=params.has_key("confirm")
3197 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3200 def _process( self ):
3201 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3202 url.addParam("tab","conf_managers")
3203 if self._pendingConfMgrs == []:
3204 self._redirect(url)
3205 if self._confirmed:
3206 if self._send:
3207 pendings=pendingQueues.PendingConfManagersHolder()
3208 for pss in self._pendingConfMgrs:
3209 pendings._sendReminderEmail(pss)
3210 self._redirect(url)
3211 else:
3212 wp = conferences.WPConfModifPendingQueuesReminderConfMgrConfirm(self, self._conf, self._pendingConfMgrIds)
3213 return wp.display()
3215 class RHConfModifPendingQueuesActionConfSubm:
3217 class to select the action to do with the selected pending conference submitters
3220 _uh = urlHandlers.UHConfModifPendingQueuesActionConfSubm
3222 def process(self, params):
3223 if 'remove' in params:
3224 return RHConfModifPendingQueuesRemoveConfSubm().process(params)
3225 elif 'reminder' in params:
3226 return RHConfModifPendingQueuesReminderConfSubm().process(params)
3227 return "no action to do"
3229 class RHConfModifPendingQueuesRemoveConfSubm( RHConferenceModifBase ):
3231 def _checkParams( self, params ):
3232 RHConferenceModifBase._checkParams( self, params )
3233 self._pendingConfSubmIds = self._normaliseListParam( params.get("pendingUsers", []) )
3234 self._pendingConfSubms = []
3235 for id in self._pendingConfSubmIds:
3236 self._pendingConfSubms.extend(self._conf.getPendingQueuesMgr().getPendingConfSubmittersByEmail(id))
3237 self._remove=params.has_key("confirm")
3238 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3240 def _process( self ):
3241 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3242 url.addParam("tab","conf_submitters")
3243 if self._pendingConfSubms == []:
3244 self._redirect(url)
3245 if self._confirmed:
3246 if self._remove:
3247 for ps in self._pendingConfSubms:
3248 self._conf.getPendingQueuesMgr().removePendingConfSubmitter(ps)
3249 self._redirect(url)
3250 else:
3251 wp = conferences.WPConfModifPendingQueuesRemoveConfSubmConfirm(self, self._conf, self._pendingConfSubmIds)
3252 return wp.display()
3254 class RHConfModifPendingQueuesReminderConfSubm( RHConferenceModifBase ):
3256 def _checkParams( self, params ):
3257 RHConferenceModifBase._checkParams( self, params )
3258 self._pendingConfSubmIds = self._normaliseListParam( params.get("pendingUsers", []) )
3259 self._pendingConfSubms = []
3260 for email in self._pendingConfSubmIds:
3261 self._pendingConfSubms.append(self._conf.getPendingQueuesMgr().getPendingConfSubmittersByEmail(email))
3262 self._send=params.has_key("confirm")
3263 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3266 def _process( self ):
3267 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3268 url.addParam("tab","conf_submitters")
3269 if self._pendingConfSubms == []:
3270 self._redirect(url)
3271 if self._confirmed:
3272 if self._send:
3273 pendings=pendingQueues.PendingConfSubmittersHolder()
3274 for pss in self._pendingConfSubms:
3275 pendings._sendReminderEmail(pss)
3276 self._redirect(url)
3277 else:
3278 wp = conferences.WPConfModifPendingQueuesReminderConfSubmConfirm(self, self._conf, self._pendingConfSubmIds)
3279 return wp.display()
3281 class RHConfModifPendingQueuesActionSubm:
3283 class to select the action to do with the selected pending contribution submitters
3286 _uh = urlHandlers.UHConfModifPendingQueuesActionSubm
3288 def process(self, params):
3289 if 'remove' in params:
3290 return RHConfModifPendingQueuesRemoveSubm().process(params)
3291 elif 'reminder' in params:
3292 return RHConfModifPendingQueuesReminderSubm().process(params)
3293 return "no action to do"
3295 class RHConfModifPendingQueuesRemoveSubm( RHConferenceModifBase ):
3297 def _checkParams( self, params ):
3298 RHConferenceModifBase._checkParams( self, params )
3299 self._pendingSubmIds = self._normaliseListParam( params.get("pendingUsers", []) )
3300 self._pendingSubms = []
3301 for id in self._pendingSubmIds:
3302 self._pendingSubms.extend(self._conf.getPendingQueuesMgr().getPendingSubmittersByEmail(id))
3303 self._remove=params.has_key("confirm")
3304 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3306 def _process( self ):
3307 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3308 url.addParam("tab","submitters")
3309 if self._pendingSubms == []:
3310 self._redirect(url)
3311 if self._confirmed:
3312 if self._remove:
3313 for ps in self._pendingSubms:
3314 self._conf.getPendingQueuesMgr().removePendingSubmitter(ps)
3315 self._redirect(url)
3316 else:
3317 wp = conferences.WPConfModifPendingQueuesRemoveSubmConfirm(self, self._conf, self._pendingSubmIds)
3318 return wp.display()
3320 class RHConfModifPendingQueuesReminderSubm( RHConferenceModifBase ):
3322 def _checkParams( self, params ):
3323 RHConferenceModifBase._checkParams( self, params )
3324 self._pendingSubmIds = self._normaliseListParam( params.get("pendingUsers", []) )
3325 self._pendingSubms = []
3326 for email in self._pendingSubmIds:
3327 self._pendingSubms.append(self._conf.getPendingQueuesMgr().getPendingSubmittersByEmail(email))
3328 self._send=params.has_key("confirm")
3329 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3332 def _process( self ):
3333 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3334 url.addParam("tab","submitters")
3335 if self._pendingSubms == []:
3336 self._redirect(url)
3337 if self._confirmed:
3338 if self._send:
3339 pendings=pendingQueues.PendingSubmittersHolder()
3340 for pss in self._pendingSubms:
3341 pendings._sendReminderEmail(pss)
3342 self._redirect(url)
3343 else:
3344 wp = conferences.WPConfModifPendingQueuesReminderSubmConfirm(self, self._conf, self._pendingSubmIds)
3345 return wp.display()
3347 class RHConfModifPendingQueuesActionMgr:
3349 class to select the action to do with the selected pending submitters
3352 _uh = urlHandlers.UHConfModifPendingQueuesActionMgr
3354 def process(self, params):
3355 if 'remove' in params:
3356 return RHConfModifPendingQueuesRemoveMgr().process(params)
3357 elif 'reminder' in params:
3358 return RHConfModifPendingQueuesReminderMgr().process(params)
3359 return "no action to do"
3361 class RHConfModifPendingQueuesRemoveMgr( RHConferenceModifBase ):
3363 def _checkParams( self, params ):
3364 RHConferenceModifBase._checkParams( self, params )
3365 self._pendingMgrIds = self._normaliseListParam( params.get("pendingUsers", []) )
3366 self._pendingMgrs = []
3367 for id in self._pendingMgrIds:
3368 self._pendingMgrs.extend(self._conf.getPendingQueuesMgr().getPendingManagersByEmail(id))
3369 self._remove=params.has_key("confirm")
3370 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3373 def _process( self ):
3374 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3375 url.addParam("tab","managers")
3376 if self._pendingMgrs == []:
3377 self._redirect(url)
3378 if self._confirmed:
3379 if self._remove:
3380 for ps in self._pendingMgrs:
3381 self._conf.getPendingQueuesMgr().removePendingManager(ps)
3382 self._redirect(url)
3383 else:
3384 wp = conferences.WPConfModifPendingQueuesRemoveMgrConfirm(self, self._conf, self._pendingMgrIds)
3385 return wp.display()
3387 class RHConfModifPendingQueuesReminderMgr( RHConferenceModifBase ):
3389 def _checkParams( self, params ):
3390 RHConferenceModifBase._checkParams( self, params )
3391 self._pendingMgrIds = self._normaliseListParam( params.get("pendingUsers", []) )
3392 self._pendingMgrs = []
3393 for email in self._pendingMgrIds:
3394 self._pendingMgrs.append(self._conf.getPendingQueuesMgr().getPendingManagersByEmail(email))
3395 self._send=params.has_key("confirm")
3396 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3399 def _process( self ):
3400 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3401 url.addParam("tab","managers")
3402 if self._pendingMgrs == []:
3403 self._redirect(url)
3404 if self._confirmed:
3405 if self._send:
3406 pendings=pendingQueues.PendingManagersHolder()
3407 for pss in self._pendingMgrs:
3408 pendings._sendReminderEmail(pss)
3409 self._redirect(url)
3410 else:
3411 wp = conferences.WPConfModifPendingQueuesReminderMgrConfirm(self, self._conf, self._pendingMgrIds)
3412 return wp.display()
3414 class RHConfModifPendingQueuesActionCoord:
3416 class to select the action to do with the selected pending submitters
3419 _uh = urlHandlers.UHConfModifPendingQueuesActionCoord
3421 def process(self, params):
3422 if 'remove' in params:
3423 return RHConfModifPendingQueuesRemoveCoord().process(params)
3424 elif 'reminder' in params:
3425 return RHConfModifPendingQueuesReminderCoord().process(params)
3426 return "no action to do"
3428 class RHConfModifPendingQueuesRemoveCoord( RHConferenceModifBase ):
3430 def _checkParams( self, params ):
3431 RHConferenceModifBase._checkParams( self, params )
3432 self._pendingCoordIds = self._normaliseListParam( params.get("pendingUsers", []) )
3433 self._pendingCoords = []
3434 for id in self._pendingCoordIds:
3435 self._pendingCoords.extend(self._conf.getPendingQueuesMgr().getPendingCoordinatorsByEmail(id))
3436 self._remove=params.has_key("confirm")
3437 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3440 def _process( self ):
3441 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3442 url.addParam("tab", "coordinators")
3443 if self._pendingCoords == []:
3444 self._redirect(url)
3445 if self._confirmed:
3446 if self._remove:
3447 for ps in self._pendingCoords:
3448 self._conf.getPendingQueuesMgr().removePendingCoordinator(ps)
3449 self._redirect(url)
3450 else:
3451 wp = conferences.WPConfModifPendingQueuesRemoveCoordConfirm(self, self._conf, self._pendingCoordIds)
3452 return wp.display()
3454 class RHConfModifPendingQueuesReminderCoord( RHConferenceModifBase ):
3456 def _checkParams( self, params ):
3457 RHConferenceModifBase._checkParams( self, params )
3458 self._pendingCoordIds = self._normaliseListParam( params.get("pendingUsers", []) )
3459 self._pendingCoords = []
3460 for email in self._pendingCoordIds:
3461 self._pendingCoords.append(self._conf.getPendingQueuesMgr().getPendingCoordinatorsByEmail(email))
3462 self._send=params.has_key("confirm")
3463 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3466 def _process( self ):
3467 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3468 url.addParam("tab", "coordinators")
3469 if self._pendingCoords == []:
3470 self._redirect(url)
3471 if self._confirmed:
3472 if self._send:
3473 pendings=pendingQueues.PendingCoordinatorsHolder()
3474 for pss in self._pendingCoords:
3475 pendings._sendReminderEmail(pss)
3476 self._redirect(url)
3477 else:
3478 wp = conferences.WPConfModifPendingQueuesReminderCoordConfirm(self, self._conf, self._pendingCoordIds)
3479 return wp.display()
3481 class RHConfAbstractFields( RHConfModifCFABase ):
3482 _uh = urlHandlers.UHConfModifCFAOptFld
3484 def _checkParams( self, params ):
3485 RHConfModifCFABase._checkParams( self, params )
3486 self._fieldId = params.get("fieldId", "")
3487 if self._fieldId.strip()!="":
3488 if not self._conf.getAbstractMgr().getAbstractFieldsMgr().hasField(self._fieldId):
3489 raise MaKaCError( _("The field that you are trying to enable/disable does not exist"))
3491 def _process( self ):
3492 if self._fieldId.strip() != "":
3493 if self._conf.getAbstractMgr().hasEnabledAbstractField(self._fieldId):
3494 self._conf.getAbstractMgr().disableAbstractField(self._fieldId)
3495 else:
3496 self._conf.getAbstractMgr().enableAbstractField(self._fieldId)
3497 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
3500 class RHConfRemoveAbstractField( RHConfModifCFABase ):
3501 _uh = urlHandlers.UHConfModifCFARemoveOptFld
3503 def _checkParams( self, params ):
3504 RHConfModifCFABase._checkParams( self, params )
3505 self._fieldIds = []
3506 if params.get("fieldId","") != "":
3507 self._fieldIds = self._normaliseListParam( params["fieldId"] )
3509 def _process( self ):
3510 for id in self._fieldIds:
3511 self._conf.getAbstractMgr().removeAbstractField(id)
3512 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
3514 class RHConfMoveAbsFieldUp( RHConfModifCFABase ):
3515 _uh = urlHandlers.UHConfModifCFAAbsFieldUp
3517 def _checkParams( self, params ):
3518 RHConfModifCFABase._checkParams( self, params )
3519 self._fieldId = params.get("fieldId", "")
3521 def _process( self ):
3522 if self._fieldId != "":
3523 self._conf.getAbstractMgr().moveAbsFieldUp(self._fieldId)
3524 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
3526 class RHConfMoveAbsFieldDown( RHConfModifCFABase ):
3527 _uh = urlHandlers.UHConfModifCFAAbsFieldDown
3529 def _checkParams( self, params ):
3530 RHConfModifCFABase._checkParams( self, params )
3531 self._fieldId = params.get("fieldId", "")
3533 def _process( self ):
3534 if self._fieldId != "":
3535 self._conf.getAbstractMgr().moveAbsFieldDown(self._fieldId)
3536 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
3539 class RHReschedule(RHConferenceModifBase):
3541 def _checkParams(self, params):
3542 RHConferenceModifBase._checkParams(self, params)
3543 self._cancel=params.has_key("CANCEL")
3544 self._ok=params.has_key("OK")
3545 self._hour=params.get("hour","")
3546 self._minute=params.get("minute","")
3547 self._action=params.get("action","duration")
3548 self._fit= params.get("fit","noFit") == "doFit"
3549 self._targetDay=params.get("targetDay",None) #comes in format YYYYMMDD, ex: 20100317
3550 self._sessionId = params.get("sessionId", "")
3551 if self._targetDay is None:
3552 raise MaKaCError( _("Error while rescheduling timetable: not target day"))
3553 else:
3554 self._day=timezone(self._conf.getTimezone()).localize(datetime(int(params["targetDay"][0:4]),
3555 int(params["targetDay"][4:6]),
3556 int(params["targetDay"][6:8])))
3557 if self._ok:
3558 if self._hour.strip() == "" or self._minute.strip() == "":
3559 raise FormValuesError( _("Please write the time with the format HH:MM. For instance, 00:05 to indicate 'O hours' and '5 minutes'"))
3560 try:
3561 if int(self._hour) or int(self._hour):
3562 pass
3563 except ValueError, e:
3564 raise FormValuesError( _("Please write a number to specify the time HH:MM. For instance, 00:05 to indicate 'O hours' and '5 minutes'"))
3566 def _process(self):
3567 if not self._cancel:
3568 if not self._ok:
3569 p = conferences.WPConfModifReschedule(self, self._conf, self._targetDay)
3570 return p.display()
3571 else:
3572 t = timedelta(hours=int(self._hour), minutes=int(self._minute))
3573 if self._sessionId:
3574 self._conf.getSessionById(self._sessionId).getSchedule().rescheduleTimes(self._action, t, self._day, self._fit)
3575 self._redirect("%s#%s" % (urlHandlers.UHSessionModifSchedule.getURL(self._conf.getSessionById(self._sessionId)), self._targetDay))
3576 else :
3577 self._conf.getSchedule().rescheduleTimes(self._action, t, self._day, self._fit)
3578 self._redirect("%s#%s" % (urlHandlers.UHConfModifSchedule.getURL(self._conf), self._targetDay))
3582 # ============================================================================
3583 # === Badges related =========================================================
3584 # ============================================================================
3586 ##------------------------------------------------------------------------------------------------------------
3587 class RHConfBadgeBase(RHConferenceModifBase):
3589 def _checkProtection( self ):
3590 if not self._target.canManageRegistration(self.getAW().getUser()):
3591 RHConferenceModifBase._checkProtection(self)
3594 Badge Design and Printing classes
3596 class RHConfBadgePrinting(RHConfBadgeBase):
3597 """ This class corresponds to the screen where templates are
3598 listed and can be created, edited, deleted and tried.
3599 It always displays the list of templates; but we can
3600 arrive to this page in different scenarios:
3601 -A template has just been created (templateId = new template id, new = True). The template
3602 will be stored and the temporary backgrounds stored in the session object archived.
3603 -A template has been edited (templateId = existing template id, new = False or not set).
3604 The template will be updated and the temporary backgrounds stored in it, archived.
3605 -A template had been deleted (deleteTemplateId = id of the template to delete)
3606 -We were creating / editing a template but we pressed the "Cancel" button
3607 (templateId = id of the template that was being created / edited, Cancel = True).
3608 Temporary backgrounds (in the session object or in the template object) will be deleted.
3611 def _checkParams(self, params):
3612 RHConfBadgeBase._checkParams(self, params)
3613 self.__templateId = params.get("templateId",None)
3614 self.__templateData = params.get("templateData",None)
3615 self.__deleteTemplateId = params.get("deleteTemplateId",None)
3616 self.__copyTemplateId = params.get("copyTemplateId",None)
3617 self.__new = params.get("new","False") == "True"
3618 self.__cancel = params.get("cancel","False") == "True"
3620 def _process(self):
3621 if self._target.isClosed():
3622 return conferences.WPConferenceModificationClosed(self, self._target).display()
3623 else:
3624 if self.__templateId and self.__templateData and not self.__deleteTemplateId:
3626 if self.__new:
3627 self._target.getBadgeTemplateManager().storeTemplate(self.__templateId, self.__templateData)
3628 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3629 filePaths = session.get(key)
3630 if filePaths:
3631 cfg = Config.getInstance()
3632 tempPath = cfg.getUploadedFilesSharedTempDir()
3633 for filePath in filePaths:
3634 self._target.getBadgeTemplateManager().getTemplateById(self.__templateId).addTempBackgroundFilePath(filePath)
3635 self._tempFilesToDelete.append(os.path.join(tempPath, filePath))
3636 self._target.getBadgeTemplateManager().getTemplateById(self.__templateId).archiveTempBackgrounds(self._conf)
3637 else:
3638 self._target.getBadgeTemplateManager().storeTemplate(self.__templateId, self.__templateData)
3640 elif self.__deleteTemplateId:
3641 self._target.getBadgeTemplateManager().deleteTemplate(self.__deleteTemplateId)
3643 elif self.__copyTemplateId:
3644 self._target.getBadgeTemplateManager().copyTemplate(self.__copyTemplateId)
3645 elif self.__cancel:
3646 if self._target.getBadgeTemplateManager().hasTemplate(self.__templateId):
3647 self._target.getBadgeTemplateManager().getTemplateById(self.__templateId).deleteTempBackgrounds()
3648 else:
3649 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3650 session.pop(key, None)
3652 if self._target.getId() == "default":
3653 p = admins.WPBadgeTemplates(self)
3654 url = urlHandlers.UHBadgeTemplates.getURL()
3655 else:
3656 p = conferences.WPConfModifBadgePrinting(self, self._target)
3657 url = urlHandlers.UHConfModifBadgePrinting.getURL(self._target)
3658 if request.method == 'POST':
3659 self._redirect(url)
3660 else:
3661 return p.display()
3664 class RHConfBadgeDesign(RHConfBadgeBase):
3665 """ This class corresponds to the screen where templates are
3666 designed. We can arrive to this screen from different scenarios:
3667 -We are creating a new template (templateId = new template id, new = True)
3668 -We are editing an existing template (templateId = existing template id, new = False or not set)
3671 def _checkParams(self, params):
3672 RHConfBadgeBase._checkParams(self, params)
3673 self.__templateId = params.get("templateId",None)
3674 new = params.get("new",'False')
3675 if new == 'False':
3676 self.__new = False
3677 else:
3678 self.__new = True
3679 self.__baseTemplate = params.get("baseTemplate",'blank')
3682 def _process(self):
3683 if self._target.isClosed():
3684 p = conferences.WPConferenceModificationClosed( self, self._target )
3685 else:
3686 p = conferences.WPConfModifBadgeDesign(self, self._target, self.__templateId, self.__new, self.__baseTemplate)
3687 return p.display()
3689 class RHConfBadgePrintingPDF(RHConfBadgeBase):
3690 """ This class is used to print the PDF from a badge template.
3691 There are 2 scenarios:
3692 -We are printing badges for all registrants (registrantList = 'all' or not set).
3693 -We are printing badges just for some registrants (registrantList = list of id's of registrants)
3696 def _checkParams(self, params):
3697 """ Default values (1.5, etc...) are CERN's defaults in cm.
3698 These default values also appear in ConfModifBadgePDFOptions.tpl
3699 marginTop: top margin
3700 marginBottom: bottom margin
3701 marginLeft: left margin
3702 marginRight: right margin
3703 marginColumns: margin between columns
3704 marginRows: margin between rows
3705 keepPDFOptions: tells if we should keep the other params for the next time
3706 by storing them in the database (in the conference object)
3708 RHConfBadgeBase._checkParams(self, params)
3710 self.__templateId = params.get("templateId",None)
3712 #we retrieve the present PDF options of the conference in order to use
3713 #its values in case of input error
3714 self.__PDFOptions = self._target.getBadgeTemplateManager().getPDFOptions()
3716 self.__keepPDFOptions = params.get("keepPDFOptions", False)
3717 #in case of input error, this will be set to False
3719 try:
3720 self.__marginTop = float(params.get("marginTop",''))
3721 except ValueError:
3722 self.__marginTop = self.__PDFOptions.getTopMargin()
3723 self.__keepPDFOptions = False
3725 try:
3726 self.__marginBottom = float(params.get("marginBottom",''))
3727 except ValueError:
3728 self.__marginBottom = self.__PDFOptions.getBottomMargin()
3729 self.__keepPDFOptions = False
3731 try:
3732 self.__marginLeft = float(params.get("marginLeft",''))
3733 except ValueError:
3734 self.__marginLeft = self.__PDFOptions.getLeftMargin()
3735 self.__keepPDFOptions = False
3737 try:
3738 self.__marginRight = float(params.get("marginRight",''))
3739 except ValueError:
3740 self.__marginRight = self.__PDFOptions.getRightMargin()
3741 self.__keepPDFOptions = False
3743 try:
3744 self.__marginColumns = float(params.get("marginColumns",''))
3745 except ValueError:
3746 self.__marginColumns = self.__PDFOptions.getMarginColumns()
3747 self.__keepPDFOptions = False
3749 try:
3750 self.__marginRows = float(params.get("marginRows",''))
3751 except ValueError:
3752 self.__marginRows = self.__PDFOptions.getMarginRows()
3753 self.__keepPDFOptions = False
3755 self.__pagesize = params.get("pagesize",'A4')
3757 self.__drawDashedRectangles = params.get("drawDashedRectangles", False) is not False
3758 self.__landscape = params.get('landscape') == '1'
3760 self.__registrantList = params.get("registrantList","all")
3761 if self.__registrantList != "all":
3762 self.__registrantList = self.__registrantList.split(',')
3765 def _process(self):
3766 if self._target.isClosed():
3767 p = conferences.WPConferenceModificationClosed( self, self._target )
3768 return p
3769 else:
3770 if self._conf.getRegistrantsList() == []:
3771 return _("There are no registrants, so no badges to print.")
3772 elif self.__templateId == None:
3773 return _("There is no badge template selected for this conference.")
3775 if self.__keepPDFOptions:
3776 #we store the pdf options into the conference
3777 self.__PDFOptions.setTopMargin(self.__marginTop)
3778 self.__PDFOptions.setBottomMargin(self.__marginBottom)
3779 self.__PDFOptions.setLeftMargin(self.__marginLeft)
3780 self.__PDFOptions.setRightMargin(self.__marginRight)
3781 self.__PDFOptions.setMarginColumns(self.__marginColumns)
3782 self.__PDFOptions.setMarginRows(self.__marginRows)
3783 self.__PDFOptions.setPagesize(self.__pagesize)
3784 self.__PDFOptions.setDrawDashedRectangles(self.__drawDashedRectangles)
3785 self.__PDFOptions.setLandscape(self.__landscape)
3788 pdf = RegistrantsListToBadgesPDF(self._conf,
3789 self._conf.getBadgeTemplateManager().getTemplateById(self.__templateId),
3790 self.__marginTop,
3791 self.__marginBottom,
3792 self.__marginLeft,
3793 self.__marginRight,
3794 self.__marginColumns,
3795 self.__marginRows,
3796 self.__pagesize,
3797 self.__drawDashedRectangles,
3798 self.__registrantList,
3799 self.__landscape)
3800 return send_file('Badges.pdf', StringIO(pdf.getPDFBin()), 'PDF')
3803 class RHConfBadgeSaveTempBackground(RHConfBadgeBase):
3804 """ This class is used to save a background as a temporary file,
3805 before it is archived. Temporary backgrounds are archived
3806 after pressing the "save" button.
3807 The temporary background filepath can be stored in the session
3808 object (if we are creating a new template and it has not been stored yet)
3809 or in the corresponding template if we are editing a template.
3812 def _getNewTempFile( self ):
3813 cfg = Config.getInstance()
3814 tempPath = cfg.getUploadedFilesSharedTempDir()
3815 tempFileName = tempfile.mkstemp( suffix="IndicoBadgeBG.tmp", dir = tempPath )[1]
3816 return tempFileName
3818 def _saveFileToTemp(self, fs):
3819 fileName = self._getNewTempFile()
3820 fs.save(fileName)
3821 return os.path.split(fileName)[-1]
3823 def _checkParams(self, params):
3824 RHConfBadgeBase._checkParams(self, params)
3825 self.__templateId = params.get("templateId",None)
3826 try:
3827 self._tempFilePath = self._saveFileToTemp(params["file"])
3828 except AttributeError:
3829 self._tempFilePath = None
3831 def _process(self):
3832 if self._target.isClosed():
3833 return json.dumps({'status': 'error'}, textarea=True)
3834 else:
3835 if self._tempFilePath is not None:
3836 if self._conf.getBadgeTemplateManager().hasTemplate(self.__templateId):
3837 backgroundId = self._conf.getBadgeTemplateManager().getTemplateById(self.__templateId).addTempBackgroundFilePath(self._tempFilePath)
3838 else:
3839 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3840 value = session.get(key)
3841 if value is None:
3842 tempFilePathList = PersistentList()
3843 tempFilePathList.append(self._tempFilePath)
3844 session[key] = tempFilePathList
3845 backgroundId = 0
3846 else:
3847 value.append(self._tempFilePath)
3848 backgroundId = len(value) - 1
3849 session.modified = True
3851 return json.dumps({
3852 'status': 'OK',
3853 'id': backgroundId,
3854 'url': str(urlHandlers.UHConfModifBadgeGetBackground.getURL(self._conf, self.__templateId, backgroundId))
3855 }, textarea=True)
3857 class RHConfBadgeGetBackground(RHConfBadgeBase):
3858 """ Class used to obtain a background in order to display it
3859 on the Badge Design screen.
3860 The background can be obtained from the archived files
3861 or from the temporary files.
3864 def _checkParams(self, params):
3865 RHConfBadgeBase._checkParams(self, params)
3866 self.__templateId = params.get("templateId",None)
3867 self.__backgroundId = int(params.get("backgroundId",None))
3868 self.__width = int(params.get("width","-1"))
3869 self.__height = int(params.get("height","-1"))
3871 def __imageBin(self, image):
3872 mimetype = image.getFileType() or 'application/octet-stream'
3873 return send_file(image.getFileName(), image.getFilePath(), mimetype)
3875 def __fileBin(self, filePath):
3876 return send_file('tempBackground', filePath, 'application/octet-stream')
3878 def _process(self):
3879 if self._target.isClosed():
3880 p = conferences.WPConferenceModificationClosed( self, self._target )
3881 return p
3882 else:
3883 cfg = Config.getInstance()
3884 tempPath = cfg.getUploadedFilesSharedTempDir()
3885 if self._conf.getBadgeTemplateManager().hasTemplate(self.__templateId):
3886 isArchived, image = self._conf.getBadgeTemplateManager().getTemplateById(self.__templateId).getBackground(self.__backgroundId)
3887 if image is not None:
3888 if isArchived:
3889 return self.__imageBin(image)
3890 else:
3891 image = os.path.join(tempPath,image)
3892 return self.__fileBin(image)
3894 else:
3895 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3896 filePath = os.path.join(tempPath, session[key][int(self.__backgroundId)])
3897 return self.__fileBin(filePath)
3900 # ============================================================================
3901 # === Posters related ========================================================
3902 # ============================================================================
3904 ##------------------------------------------------------------------------------------------------------------
3906 Poster Design and Printing classes
3908 class RHConfPosterPrinting(RHConferenceModifBase):
3909 """ This class corresponds to the screen where templates are
3910 listed and can be created, edited, deleted and tried.
3911 It always displays the list of templates; but we can
3912 arrive to this page in different scenarios:
3913 -A template has just been created (templateId = new template id, new = True). The template
3914 will be stored and the temporary backgrounds stored in the session object archived.
3915 -A template has been edited (templateId = existing template id, new = False or not set).
3916 The template will be updated and the temporary backgrounds stored in it, archived.
3917 -A template had been deleted (deleteTemplateId = id of the template to delete)
3918 -We were creating / editing a template but we pressed the "Cancel" button
3919 (templateId = id of the template that was being created / edited, Cancel = True).
3920 Temporary backgrounds (in the session object or in the template object) will be deleted.
3923 def _checkParams(self, params):
3924 RHConferenceModifBase._checkParams(self, params)
3925 self.__templateId = params.get("templateId",None)
3926 self.__templateData = params.get("templateData",None)
3927 self.__deleteTemplateId = params.get("deleteTemplateId",None)
3928 self.__copyTemplateId = params.get("copyTemplateId",None)
3929 self.__bgPosition = params.get("bgPosition",None)
3930 self.__new = params.get("new","False") == "True"
3931 self.__cancel = params.get("cancel","False") == "True"
3934 def _process(self):
3935 if self._target.isClosed():
3936 return conferences.WPConferenceModificationClosed(self, self._target).display()
3937 else:
3938 if self.__templateId and self.__templateData and not self.__deleteTemplateId:
3939 if self.__new:
3940 # template is new
3941 self._target.getPosterTemplateManager().storeTemplate(self.__templateId, self.__templateData)
3942 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3943 filePaths = session.get(key)
3944 if filePaths:
3945 for filePath in filePaths:
3946 self._target.getPosterTemplateManager().getTemplateById(self.__templateId).addTempBackgroundFilePath(filePath[0],filePath[1])
3947 self._target.getPosterTemplateManager().getTemplateById(self.__templateId).archiveTempBackgrounds(self._conf)
3948 else:
3949 # template already exists
3950 self._target.getPosterTemplateManager().storeTemplate(self.__templateId, self.__templateData)
3951 elif self.__deleteTemplateId:
3952 self._target.getPosterTemplateManager().deleteTemplate(self.__deleteTemplateId)
3953 elif self.__copyTemplateId:
3954 self._target.getPosterTemplateManager().copyTemplate(self.__copyTemplateId)
3955 elif self.__cancel:
3956 if self._target.getPosterTemplateManager().hasTemplate(self.__templateId):
3957 self._target.getPosterTemplateManager().getTemplateById(self.__templateId).deleteTempBackgrounds()
3958 else:
3959 fkey = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3960 session.pop(fkey, None)
3962 if self._target.getId() == "default":
3963 p = admins.WPPosterTemplates(self)
3964 url = urlHandlers.UHPosterTemplates.getURL()
3965 else:
3966 p = conferences.WPConfModifPosterPrinting(self, self._target)
3967 url = urlHandlers.UHConfModifPosterPrinting.getURL(self._target)
3968 if request.method == 'POST':
3969 self._redirect(url)
3970 else:
3971 return p.display()
3974 class RHConfPosterDesign(RHConferenceModifBase):
3975 """ This class corresponds to the screen where templates are
3976 designed. We can arrive to this screen from different scenarios:
3977 -We are creating a new template (templateId = new template id, new = True)
3978 -We are editing an existing template (templateId = existing template id, new = False or not set)
3981 def _checkParams(self, params):
3982 RHConferenceModifBase._checkParams(self, params)
3983 self.__templateId = params.get("templateId",None)
3984 new = params.get("new",'False')
3985 if new == 'False':
3986 self.__new = False
3987 else:
3988 self.__new = True
3989 self.__baseTemplate = params.get("baseTemplate",'blank')
3991 def _process(self):
3992 if self._target.isClosed():
3993 p = conferences.WPConferenceModificationClosed( self, self._target )
3994 else:
3995 if (self._target.getId() == "default"):
3996 p = admins.WPPosterTemplateDesign(self, self._target, self.__templateId, self.__new)
3997 else:
3998 if self.__new == True and self.__baseTemplate != 'blank':
3999 dconf = conference.CategoryManager().getDefaultConference()
4000 templMan = self._target.getPosterTemplateManager()
4001 newId = self.__templateId
4002 dconf.getPosterTemplateManager().getTemplateById(self.__baseTemplate).clone(templMan, newId)
4003 url = urlHandlers.UHConfModifPosterPrinting().getURL(self._target)
4004 self._redirect(url)
4005 return
4006 else:
4007 p = conferences.WPConfModifPosterDesign(self, self._target, self.__templateId, self.__new, self.__baseTemplate)
4008 return p.display()
4010 class RHConfPosterPrintingPDF(RHConferenceModifBase):
4012 This class is used to print the PDF from a poster template.
4014 def _checkParams(self, params):
4015 RHConferenceModifBase._checkParams(self, params)
4016 self.__templateId = params.get("templateId",None)
4017 if self.__templateId == None:
4018 raise FormValuesError(_("Poster not selected"))
4019 if self.__templateId.find('global') != -1:
4020 self.__templateId = self.__templateId.replace('global','')
4021 self.__template = conference.CategoryManager().getDefaultConference().getPosterTemplateManager().getTemplateById(self.__templateId)
4022 else:
4023 self.__template = self._conf.getPosterTemplateManager().getTemplateById(self.__templateId)
4024 try:
4025 self.__marginH = int(params.get("marginH",'2'))
4026 except ValueError:
4027 self.__marginH = 2
4028 try:
4029 self.__marginV = int(params.get("marginV",'2'))
4030 except ValueError:
4031 self.__marginV = 2
4032 self.__pagesize = params.get("pagesize",'A4')
4035 def _process(self):
4036 if self._target.isClosed():
4037 p = conferences.WPConferenceModificationClosed( self, self._target )
4038 return p
4039 else:
4040 pdf = LectureToPosterPDF(self._conf,
4041 self.__template,
4042 self.__marginH,
4043 self.__marginV,
4044 self.__pagesize)
4046 return send_file('Poster.pdf', StringIO(pdf.getPDFBin()), 'PDF')
4049 class RHConfPosterSaveTempBackground(RHConferenceModifBase):
4050 """ This class is used to save a background as a temporary file,
4051 before it is archived. Temporary backgrounds are archived
4052 after pressing the "save" button.
4053 The temporary background filepath can be stored in the session
4054 object (if we are creating a new template and it has not been stored yet)
4055 or in the corresponding template if we are editing a template.
4058 def _getNewTempFile( self ):
4059 cfg = Config.getInstance()
4060 tempPath = cfg.getUploadedFilesSharedTempDir()
4061 tempFileName = tempfile.mkstemp( suffix="IndicoPosterBG.tmp", dir = tempPath )[1]
4062 return tempFileName
4064 def _saveFileToTemp(self, fs):
4065 fileName = self._getNewTempFile()
4066 fs.save(fileName)
4067 return os.path.split(fileName)[-1]
4069 def _checkParams(self, params):
4070 RHConferenceModifBase._checkParams(self, params)
4071 self.__templateId = params.get("templateId",None)
4073 self._bgPosition = params.get("bgPosition",None)
4075 try:
4076 self._tempFilePath = self._saveFileToTemp(params["file"])
4077 except AttributeError:
4078 self._tempFilePath = None
4080 def _process(self):
4081 if self._target.isClosed():
4082 return json.dumps({'status': 'error'}, textarea=True)
4083 else:
4084 if self._tempFilePath is not None:
4085 if self._conf.getPosterTemplateManager().hasTemplate(self.__templateId):
4086 # Save
4087 backgroundId = self._conf.getPosterTemplateManager().getTemplateById(self.__templateId).addTempBackgroundFilePath(self._tempFilePath,self._bgPosition)
4088 else:
4089 # New
4090 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
4091 value = session.get(key)
4092 if value is None:
4093 # First background
4094 tempFilePathList = PersistentList()
4095 tempFilePathList.append((self._tempFilePath,self._bgPosition))
4096 session[key] = tempFilePathList
4097 backgroundId = 0
4098 else:
4099 # We have more
4100 value.append((self._tempFilePath, self._bgPosition))
4101 backgroundId = len(value) - 1
4102 session.modified = True
4104 return json.dumps({
4105 'status': 'OK',
4106 'id': backgroundId,
4107 'url': str(urlHandlers.UHConfModifPosterGetBackground.getURL(self._conf, self.__templateId, backgroundId)),
4108 'pos': self._bgPosition
4109 }, textarea=True)
4112 class RHConfPosterGetBackground(RHConferenceModifBase):
4113 """ Class used to obtain a background in order to display it
4114 on the Poster Design screen.
4115 The background can be obtained from the archived files
4116 or from the temporary files.
4119 def _checkParams(self, params):
4120 RHConferenceModifBase._checkParams(self, params)
4121 self.__templateId = params.get("templateId",None)
4122 self.__backgroundId = int(params.get("backgroundId",None))
4123 self.__width = int(params.get("width","-1"))
4124 self.__height = int(params.get("height","-1"))
4126 def __imageBin(self, image):
4127 mimetype = image.getFileType() or 'application/octet-stream'
4128 return send_file(image.getFileName(), image.getFilePath(), mimetype)
4130 def __fileBin(self, filePath):
4131 return send_file('tempBackground', filePath, mimetype='application/octet-stream')
4133 def _process(self):
4135 if self._target.isClosed():
4136 p = conferences.WPConferenceModificationClosed( self, self._target )
4137 return p
4138 else:
4139 cfg = Config.getInstance()
4140 tempPath = cfg.getUploadedFilesSharedTempDir()
4142 if self._conf.getPosterTemplateManager().hasTemplate(self.__templateId):
4144 isArchived, image = self._conf.getPosterTemplateManager().getTemplateById(self.__templateId).getBackground(self.__backgroundId)
4146 if image is not None:
4147 if isArchived:
4148 return self.__imageBin(image)
4149 else:
4150 image = os.path.join(tempPath,image)
4151 return self.__fileBin(image)
4153 else:
4154 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
4155 filePath = os.path.join(tempPath, session[key][int(self.__backgroundId)][0])
4156 return self.__fileBin(filePath)