Use new material package module for contributions
[cds-indico.git] / indico / MaKaC / webinterface / rh / conferenceModif.py
blob58b7e24894915e20ad8089fd0fa1a9da6cb716c2
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
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", []))
3095 self._contribs = []
3096 for id in self._contribIds:
3097 self._contribs.append(self._conf.getContributionById(id))
3099 def _process(self):
3100 if not self._contribs:
3101 return "No contribution selected"
3102 return self._generate_zip_file(self._filter_protected(self._filter_by_contributions(self._contribIds, None)))
3105 class RHAbstractBook( RHConfModifCFABase ):
3106 _uh = urlHandlers.UHConfModAbstractBook
3108 def _checkParams( self, params ):
3109 RHConfModifCFABase._checkParams( self, params )
3111 def _process( self ):
3112 p = conferences.WPModAbstractBook(self,self._target)
3113 return p.display()
3116 class RHAbstractBookToogleShowIds( RHConfModifCFABase ):
3117 _uh = urlHandlers.UHConfModAbstractBookToogleShowIds
3119 def _process( self ):
3120 self._conf.getBOAConfig().setShowIds(not self._conf.getBOAConfig().getShowIds())
3121 self._redirect( urlHandlers.UHConfModAbstractBook.getURL( self._conf ) )
3124 class RHModifSessionCoordRights( RHConferenceModifBase ):
3125 _uh = urlHandlers.UHConfPerformDataModif
3127 def _checkParams( self, params ):
3128 RHConferenceModifBase._checkParams( self, params )
3129 self._rightId = params.get("rightId", "")
3131 def _process( self ):
3132 if self._rightId != "":
3133 if self._conf.hasSessionCoordinatorRight(self._rightId):
3134 self._conf.removeSessionCoordinatorRight(self._rightId)
3135 else:
3136 self._conf.addSessionCoordinatorRight(self._rightId)
3137 self._redirect( "%s#sessionCoordinatorRights"%urlHandlers.UHConfModifAC.getURL( self._conf) )
3140 class RHConfModifPendingQueues( RHConferenceModifBase ):
3141 _uh = urlHandlers.UHConfModifPendingQueues
3143 def _process( self ):
3144 p = conferences.WPConfModifPendingQueues( self, self._target, self._getRequestParams().get("tab","conf_submitters") )
3145 return p.display()
3147 class RHConfModifPendingQueuesActionConfMgr:
3149 class to select the action to do with the selected pending conference submitters
3152 _uh = urlHandlers.UHConfModifPendingQueuesActionConfMgr
3154 def process(self, params):
3155 if 'remove' in params:
3156 return RHConfModifPendingQueuesRemoveConfMgr().process(params)
3157 elif 'reminder' in params:
3158 return RHConfModifPendingQueuesReminderConfMgr().process(params)
3159 return "no action to do"
3161 class RHConfModifPendingQueuesRemoveConfMgr( RHConferenceModifBase ):
3163 def _checkParams( self, params ):
3164 RHConferenceModifBase._checkParams( self, params )
3165 self._pendingConfMgrIds = self._normaliseListParam( params.get("pendingUsers", []) )
3166 self._pendingConfMgrs = []
3167 for id in self._pendingConfMgrIds:
3168 self._pendingConfMgrs.extend(self._conf.getPendingQueuesMgr().getPendingConfManagersByEmail(id))
3169 self._remove=params.has_key("confirm")
3170 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3172 def _process( self ):
3173 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3174 url.addParam("tab","conf_managers")
3175 if self._pendingConfMgrs == []:
3176 self._redirect(url)
3177 if self._confirmed:
3178 if self._remove:
3179 for ps in self._pendingConfMgrs:
3180 self._conf.getPendingQueuesMgr().removePendingConfManager(ps)
3181 self._redirect(url)
3182 else:
3183 wp = conferences.WPConfModifPendingQueuesRemoveConfMgrConfirm(self, self._conf, self._pendingConfMgrIds)
3184 return wp.display()
3186 class RHConfModifPendingQueuesReminderConfMgr( RHConferenceModifBase ):
3188 def _checkParams( self, params ):
3189 RHConferenceModifBase._checkParams( self, params )
3190 self._pendingConfMgrIds = self._normaliseListParam( params.get("pendingUsers", []) )
3191 self._pendingConfMgrs = []
3192 for email in self._pendingConfMgrIds:
3193 self._pendingConfMgrs.append(self._conf.getPendingQueuesMgr().getPendingConfManagersByEmail(email))
3194 self._send=params.has_key("confirm")
3195 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3198 def _process( self ):
3199 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3200 url.addParam("tab","conf_managers")
3201 if self._pendingConfMgrs == []:
3202 self._redirect(url)
3203 if self._confirmed:
3204 if self._send:
3205 pendings=pendingQueues.PendingConfManagersHolder()
3206 for pss in self._pendingConfMgrs:
3207 pendings._sendReminderEmail(pss)
3208 self._redirect(url)
3209 else:
3210 wp = conferences.WPConfModifPendingQueuesReminderConfMgrConfirm(self, self._conf, self._pendingConfMgrIds)
3211 return wp.display()
3213 class RHConfModifPendingQueuesActionConfSubm:
3215 class to select the action to do with the selected pending conference submitters
3218 _uh = urlHandlers.UHConfModifPendingQueuesActionConfSubm
3220 def process(self, params):
3221 if 'remove' in params:
3222 return RHConfModifPendingQueuesRemoveConfSubm().process(params)
3223 elif 'reminder' in params:
3224 return RHConfModifPendingQueuesReminderConfSubm().process(params)
3225 return "no action to do"
3227 class RHConfModifPendingQueuesRemoveConfSubm( RHConferenceModifBase ):
3229 def _checkParams( self, params ):
3230 RHConferenceModifBase._checkParams( self, params )
3231 self._pendingConfSubmIds = self._normaliseListParam( params.get("pendingUsers", []) )
3232 self._pendingConfSubms = []
3233 for id in self._pendingConfSubmIds:
3234 self._pendingConfSubms.extend(self._conf.getPendingQueuesMgr().getPendingConfSubmittersByEmail(id))
3235 self._remove=params.has_key("confirm")
3236 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3238 def _process( self ):
3239 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3240 url.addParam("tab","conf_submitters")
3241 if self._pendingConfSubms == []:
3242 self._redirect(url)
3243 if self._confirmed:
3244 if self._remove:
3245 for ps in self._pendingConfSubms:
3246 self._conf.getPendingQueuesMgr().removePendingConfSubmitter(ps)
3247 self._redirect(url)
3248 else:
3249 wp = conferences.WPConfModifPendingQueuesRemoveConfSubmConfirm(self, self._conf, self._pendingConfSubmIds)
3250 return wp.display()
3252 class RHConfModifPendingQueuesReminderConfSubm( RHConferenceModifBase ):
3254 def _checkParams( self, params ):
3255 RHConferenceModifBase._checkParams( self, params )
3256 self._pendingConfSubmIds = self._normaliseListParam( params.get("pendingUsers", []) )
3257 self._pendingConfSubms = []
3258 for email in self._pendingConfSubmIds:
3259 self._pendingConfSubms.append(self._conf.getPendingQueuesMgr().getPendingConfSubmittersByEmail(email))
3260 self._send=params.has_key("confirm")
3261 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3264 def _process( self ):
3265 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3266 url.addParam("tab","conf_submitters")
3267 if self._pendingConfSubms == []:
3268 self._redirect(url)
3269 if self._confirmed:
3270 if self._send:
3271 pendings=pendingQueues.PendingConfSubmittersHolder()
3272 for pss in self._pendingConfSubms:
3273 pendings._sendReminderEmail(pss)
3274 self._redirect(url)
3275 else:
3276 wp = conferences.WPConfModifPendingQueuesReminderConfSubmConfirm(self, self._conf, self._pendingConfSubmIds)
3277 return wp.display()
3279 class RHConfModifPendingQueuesActionSubm:
3281 class to select the action to do with the selected pending contribution submitters
3284 _uh = urlHandlers.UHConfModifPendingQueuesActionSubm
3286 def process(self, params):
3287 if 'remove' in params:
3288 return RHConfModifPendingQueuesRemoveSubm().process(params)
3289 elif 'reminder' in params:
3290 return RHConfModifPendingQueuesReminderSubm().process(params)
3291 return "no action to do"
3293 class RHConfModifPendingQueuesRemoveSubm( RHConferenceModifBase ):
3295 def _checkParams( self, params ):
3296 RHConferenceModifBase._checkParams( self, params )
3297 self._pendingSubmIds = self._normaliseListParam( params.get("pendingUsers", []) )
3298 self._pendingSubms = []
3299 for id in self._pendingSubmIds:
3300 self._pendingSubms.extend(self._conf.getPendingQueuesMgr().getPendingSubmittersByEmail(id))
3301 self._remove=params.has_key("confirm")
3302 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3304 def _process( self ):
3305 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3306 url.addParam("tab","submitters")
3307 if self._pendingSubms == []:
3308 self._redirect(url)
3309 if self._confirmed:
3310 if self._remove:
3311 for ps in self._pendingSubms:
3312 self._conf.getPendingQueuesMgr().removePendingSubmitter(ps)
3313 self._redirect(url)
3314 else:
3315 wp = conferences.WPConfModifPendingQueuesRemoveSubmConfirm(self, self._conf, self._pendingSubmIds)
3316 return wp.display()
3318 class RHConfModifPendingQueuesReminderSubm( RHConferenceModifBase ):
3320 def _checkParams( self, params ):
3321 RHConferenceModifBase._checkParams( self, params )
3322 self._pendingSubmIds = self._normaliseListParam( params.get("pendingUsers", []) )
3323 self._pendingSubms = []
3324 for email in self._pendingSubmIds:
3325 self._pendingSubms.append(self._conf.getPendingQueuesMgr().getPendingSubmittersByEmail(email))
3326 self._send=params.has_key("confirm")
3327 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3330 def _process( self ):
3331 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3332 url.addParam("tab","submitters")
3333 if self._pendingSubms == []:
3334 self._redirect(url)
3335 if self._confirmed:
3336 if self._send:
3337 pendings=pendingQueues.PendingSubmittersHolder()
3338 for pss in self._pendingSubms:
3339 pendings._sendReminderEmail(pss)
3340 self._redirect(url)
3341 else:
3342 wp = conferences.WPConfModifPendingQueuesReminderSubmConfirm(self, self._conf, self._pendingSubmIds)
3343 return wp.display()
3345 class RHConfModifPendingQueuesActionMgr:
3347 class to select the action to do with the selected pending submitters
3350 _uh = urlHandlers.UHConfModifPendingQueuesActionMgr
3352 def process(self, params):
3353 if 'remove' in params:
3354 return RHConfModifPendingQueuesRemoveMgr().process(params)
3355 elif 'reminder' in params:
3356 return RHConfModifPendingQueuesReminderMgr().process(params)
3357 return "no action to do"
3359 class RHConfModifPendingQueuesRemoveMgr( RHConferenceModifBase ):
3361 def _checkParams( self, params ):
3362 RHConferenceModifBase._checkParams( self, params )
3363 self._pendingMgrIds = self._normaliseListParam( params.get("pendingUsers", []) )
3364 self._pendingMgrs = []
3365 for id in self._pendingMgrIds:
3366 self._pendingMgrs.extend(self._conf.getPendingQueuesMgr().getPendingManagersByEmail(id))
3367 self._remove=params.has_key("confirm")
3368 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3371 def _process( self ):
3372 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3373 url.addParam("tab","managers")
3374 if self._pendingMgrs == []:
3375 self._redirect(url)
3376 if self._confirmed:
3377 if self._remove:
3378 for ps in self._pendingMgrs:
3379 self._conf.getPendingQueuesMgr().removePendingManager(ps)
3380 self._redirect(url)
3381 else:
3382 wp = conferences.WPConfModifPendingQueuesRemoveMgrConfirm(self, self._conf, self._pendingMgrIds)
3383 return wp.display()
3385 class RHConfModifPendingQueuesReminderMgr( RHConferenceModifBase ):
3387 def _checkParams( self, params ):
3388 RHConferenceModifBase._checkParams( self, params )
3389 self._pendingMgrIds = self._normaliseListParam( params.get("pendingUsers", []) )
3390 self._pendingMgrs = []
3391 for email in self._pendingMgrIds:
3392 self._pendingMgrs.append(self._conf.getPendingQueuesMgr().getPendingManagersByEmail(email))
3393 self._send=params.has_key("confirm")
3394 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3397 def _process( self ):
3398 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3399 url.addParam("tab","managers")
3400 if self._pendingMgrs == []:
3401 self._redirect(url)
3402 if self._confirmed:
3403 if self._send:
3404 pendings=pendingQueues.PendingManagersHolder()
3405 for pss in self._pendingMgrs:
3406 pendings._sendReminderEmail(pss)
3407 self._redirect(url)
3408 else:
3409 wp = conferences.WPConfModifPendingQueuesReminderMgrConfirm(self, self._conf, self._pendingMgrIds)
3410 return wp.display()
3412 class RHConfModifPendingQueuesActionCoord:
3414 class to select the action to do with the selected pending submitters
3417 _uh = urlHandlers.UHConfModifPendingQueuesActionCoord
3419 def process(self, params):
3420 if 'remove' in params:
3421 return RHConfModifPendingQueuesRemoveCoord().process(params)
3422 elif 'reminder' in params:
3423 return RHConfModifPendingQueuesReminderCoord().process(params)
3424 return "no action to do"
3426 class RHConfModifPendingQueuesRemoveCoord( RHConferenceModifBase ):
3428 def _checkParams( self, params ):
3429 RHConferenceModifBase._checkParams( self, params )
3430 self._pendingCoordIds = self._normaliseListParam( params.get("pendingUsers", []) )
3431 self._pendingCoords = []
3432 for id in self._pendingCoordIds:
3433 self._pendingCoords.extend(self._conf.getPendingQueuesMgr().getPendingCoordinatorsByEmail(id))
3434 self._remove=params.has_key("confirm")
3435 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3438 def _process( self ):
3439 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3440 url.addParam("tab", "coordinators")
3441 if self._pendingCoords == []:
3442 self._redirect(url)
3443 if self._confirmed:
3444 if self._remove:
3445 for ps in self._pendingCoords:
3446 self._conf.getPendingQueuesMgr().removePendingCoordinator(ps)
3447 self._redirect(url)
3448 else:
3449 wp = conferences.WPConfModifPendingQueuesRemoveCoordConfirm(self, self._conf, self._pendingCoordIds)
3450 return wp.display()
3452 class RHConfModifPendingQueuesReminderCoord( RHConferenceModifBase ):
3454 def _checkParams( self, params ):
3455 RHConferenceModifBase._checkParams( self, params )
3456 self._pendingCoordIds = self._normaliseListParam( params.get("pendingUsers", []) )
3457 self._pendingCoords = []
3458 for email in self._pendingCoordIds:
3459 self._pendingCoords.append(self._conf.getPendingQueuesMgr().getPendingCoordinatorsByEmail(email))
3460 self._send=params.has_key("confirm")
3461 self._confirmed=params.has_key("confirm") or params.has_key("cancel")
3464 def _process( self ):
3465 url=urlHandlers.UHConfModifPendingQueues.getURL(self._conf)
3466 url.addParam("tab", "coordinators")
3467 if self._pendingCoords == []:
3468 self._redirect(url)
3469 if self._confirmed:
3470 if self._send:
3471 pendings=pendingQueues.PendingCoordinatorsHolder()
3472 for pss in self._pendingCoords:
3473 pendings._sendReminderEmail(pss)
3474 self._redirect(url)
3475 else:
3476 wp = conferences.WPConfModifPendingQueuesReminderCoordConfirm(self, self._conf, self._pendingCoordIds)
3477 return wp.display()
3479 class RHConfAbstractFields( RHConfModifCFABase ):
3480 _uh = urlHandlers.UHConfModifCFAOptFld
3482 def _checkParams( self, params ):
3483 RHConfModifCFABase._checkParams( self, params )
3484 self._fieldId = params.get("fieldId", "")
3485 if self._fieldId.strip()!="":
3486 if not self._conf.getAbstractMgr().getAbstractFieldsMgr().hasField(self._fieldId):
3487 raise MaKaCError( _("The field that you are trying to enable/disable does not exist"))
3489 def _process( self ):
3490 if self._fieldId.strip() != "":
3491 if self._conf.getAbstractMgr().hasEnabledAbstractField(self._fieldId):
3492 self._conf.getAbstractMgr().disableAbstractField(self._fieldId)
3493 else:
3494 self._conf.getAbstractMgr().enableAbstractField(self._fieldId)
3495 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
3498 class RHConfRemoveAbstractField( RHConfModifCFABase ):
3499 _uh = urlHandlers.UHConfModifCFARemoveOptFld
3501 def _checkParams( self, params ):
3502 RHConfModifCFABase._checkParams( self, params )
3503 self._fieldIds = []
3504 if params.get("fieldId","") != "":
3505 self._fieldIds = self._normaliseListParam( params["fieldId"] )
3507 def _process( self ):
3508 for id in self._fieldIds:
3509 self._conf.getAbstractMgr().removeAbstractField(id)
3510 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
3512 class RHConfMoveAbsFieldUp( RHConfModifCFABase ):
3513 _uh = urlHandlers.UHConfModifCFAAbsFieldUp
3515 def _checkParams( self, params ):
3516 RHConfModifCFABase._checkParams( self, params )
3517 self._fieldId = params.get("fieldId", "")
3519 def _process( self ):
3520 if self._fieldId != "":
3521 self._conf.getAbstractMgr().moveAbsFieldUp(self._fieldId)
3522 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
3524 class RHConfMoveAbsFieldDown( RHConfModifCFABase ):
3525 _uh = urlHandlers.UHConfModifCFAAbsFieldDown
3527 def _checkParams( self, params ):
3528 RHConfModifCFABase._checkParams( self, params )
3529 self._fieldId = params.get("fieldId", "")
3531 def _process( self ):
3532 if self._fieldId != "":
3533 self._conf.getAbstractMgr().moveAbsFieldDown(self._fieldId)
3534 self._redirect(urlHandlers.UHConfModifCFA.getURL(self._conf))
3537 class RHReschedule(RHConferenceModifBase):
3539 def _checkParams(self, params):
3540 RHConferenceModifBase._checkParams(self, params)
3541 self._cancel=params.has_key("CANCEL")
3542 self._ok=params.has_key("OK")
3543 self._hour=params.get("hour","")
3544 self._minute=params.get("minute","")
3545 self._action=params.get("action","duration")
3546 self._fit= params.get("fit","noFit") == "doFit"
3547 self._targetDay=params.get("targetDay",None) #comes in format YYYYMMDD, ex: 20100317
3548 self._sessionId = params.get("sessionId", "")
3549 if self._targetDay is None:
3550 raise MaKaCError( _("Error while rescheduling timetable: not target day"))
3551 else:
3552 self._day=timezone(self._conf.getTimezone()).localize(datetime(int(params["targetDay"][0:4]),
3553 int(params["targetDay"][4:6]),
3554 int(params["targetDay"][6:8])))
3555 if self._ok:
3556 if self._hour.strip() == "" or self._minute.strip() == "":
3557 raise FormValuesError( _("Please write the time with the format HH:MM. For instance, 00:05 to indicate 'O hours' and '5 minutes'"))
3558 try:
3559 if int(self._hour) or int(self._hour):
3560 pass
3561 except ValueError, e:
3562 raise FormValuesError( _("Please write a number to specify the time HH:MM. For instance, 00:05 to indicate 'O hours' and '5 minutes'"))
3564 def _process(self):
3565 if not self._cancel:
3566 if not self._ok:
3567 p = conferences.WPConfModifReschedule(self, self._conf, self._targetDay)
3568 return p.display()
3569 else:
3570 t = timedelta(hours=int(self._hour), minutes=int(self._minute))
3571 if self._sessionId:
3572 self._conf.getSessionById(self._sessionId).getSchedule().rescheduleTimes(self._action, t, self._day, self._fit)
3573 self._redirect("%s#%s" % (urlHandlers.UHSessionModifSchedule.getURL(self._conf.getSessionById(self._sessionId)), self._targetDay))
3574 else :
3575 self._conf.getSchedule().rescheduleTimes(self._action, t, self._day, self._fit)
3576 self._redirect("%s#%s" % (urlHandlers.UHConfModifSchedule.getURL(self._conf), self._targetDay))
3580 # ============================================================================
3581 # === Badges related =========================================================
3582 # ============================================================================
3584 ##------------------------------------------------------------------------------------------------------------
3585 class RHConfBadgeBase(RHConferenceModifBase):
3587 def _checkProtection( self ):
3588 if not self._target.canManageRegistration(self.getAW().getUser()):
3589 RHConferenceModifBase._checkProtection(self)
3592 Badge Design and Printing classes
3594 class RHConfBadgePrinting(RHConfBadgeBase):
3595 """ This class corresponds to the screen where templates are
3596 listed and can be created, edited, deleted and tried.
3597 It always displays the list of templates; but we can
3598 arrive to this page in different scenarios:
3599 -A template has just been created (templateId = new template id, new = True). The template
3600 will be stored and the temporary backgrounds stored in the session object archived.
3601 -A template has been edited (templateId = existing template id, new = False or not set).
3602 The template will be updated and the temporary backgrounds stored in it, archived.
3603 -A template had been deleted (deleteTemplateId = id of the template to delete)
3604 -We were creating / editing a template but we pressed the "Cancel" button
3605 (templateId = id of the template that was being created / edited, Cancel = True).
3606 Temporary backgrounds (in the session object or in the template object) will be deleted.
3609 def _checkParams(self, params):
3610 RHConfBadgeBase._checkParams(self, params)
3611 self.__templateId = params.get("templateId",None)
3612 self.__templateData = params.get("templateData",None)
3613 self.__deleteTemplateId = params.get("deleteTemplateId",None)
3614 self.__copyTemplateId = params.get("copyTemplateId",None)
3615 self.__new = params.get("new","False") == "True"
3616 self.__cancel = params.get("cancel","False") == "True"
3618 def _process(self):
3619 if self._target.isClosed():
3620 return conferences.WPConferenceModificationClosed(self, self._target).display()
3621 else:
3622 if self.__templateId and self.__templateData and not self.__deleteTemplateId:
3624 if self.__new:
3625 self._target.getBadgeTemplateManager().storeTemplate(self.__templateId, self.__templateData)
3626 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3627 filePaths = session.get(key)
3628 if filePaths:
3629 cfg = Config.getInstance()
3630 tempPath = cfg.getUploadedFilesSharedTempDir()
3631 for filePath in filePaths:
3632 self._target.getBadgeTemplateManager().getTemplateById(self.__templateId).addTempBackgroundFilePath(filePath)
3633 self._tempFilesToDelete.append(os.path.join(tempPath, filePath))
3634 self._target.getBadgeTemplateManager().getTemplateById(self.__templateId).archiveTempBackgrounds(self._conf)
3635 else:
3636 self._target.getBadgeTemplateManager().storeTemplate(self.__templateId, self.__templateData)
3638 elif self.__deleteTemplateId:
3639 self._target.getBadgeTemplateManager().deleteTemplate(self.__deleteTemplateId)
3641 elif self.__copyTemplateId:
3642 self._target.getBadgeTemplateManager().copyTemplate(self.__copyTemplateId)
3643 elif self.__cancel:
3644 if self._target.getBadgeTemplateManager().hasTemplate(self.__templateId):
3645 self._target.getBadgeTemplateManager().getTemplateById(self.__templateId).deleteTempBackgrounds()
3646 else:
3647 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3648 session.pop(key, None)
3650 if self._target.getId() == "default":
3651 p = admins.WPBadgeTemplates(self)
3652 url = urlHandlers.UHBadgeTemplates.getURL()
3653 else:
3654 p = conferences.WPConfModifBadgePrinting(self, self._target)
3655 url = urlHandlers.UHConfModifBadgePrinting.getURL(self._target)
3656 if request.method == 'POST':
3657 self._redirect(url)
3658 else:
3659 return p.display()
3662 class RHConfBadgeDesign(RHConfBadgeBase):
3663 """ This class corresponds to the screen where templates are
3664 designed. We can arrive to this screen from different scenarios:
3665 -We are creating a new template (templateId = new template id, new = True)
3666 -We are editing an existing template (templateId = existing template id, new = False or not set)
3669 def _checkParams(self, params):
3670 RHConfBadgeBase._checkParams(self, params)
3671 self.__templateId = params.get("templateId",None)
3672 new = params.get("new",'False')
3673 if new == 'False':
3674 self.__new = False
3675 else:
3676 self.__new = True
3677 self.__baseTemplate = params.get("baseTemplate",'blank')
3680 def _process(self):
3681 if self._target.isClosed():
3682 p = conferences.WPConferenceModificationClosed( self, self._target )
3683 else:
3684 p = conferences.WPConfModifBadgeDesign(self, self._target, self.__templateId, self.__new, self.__baseTemplate)
3685 return p.display()
3687 class RHConfBadgePrintingPDF(RHConfBadgeBase):
3688 """ This class is used to print the PDF from a badge template.
3689 There are 2 scenarios:
3690 -We are printing badges for all registrants (registrantList = 'all' or not set).
3691 -We are printing badges just for some registrants (registrantList = list of id's of registrants)
3694 def _checkParams(self, params):
3695 """ Default values (1.5, etc...) are CERN's defaults in cm.
3696 These default values also appear in ConfModifBadgePDFOptions.tpl
3697 marginTop: top margin
3698 marginBottom: bottom margin
3699 marginLeft: left margin
3700 marginRight: right margin
3701 marginColumns: margin between columns
3702 marginRows: margin between rows
3703 keepPDFOptions: tells if we should keep the other params for the next time
3704 by storing them in the database (in the conference object)
3706 RHConfBadgeBase._checkParams(self, params)
3708 self.__templateId = params.get("templateId",None)
3710 #we retrieve the present PDF options of the conference in order to use
3711 #its values in case of input error
3712 self.__PDFOptions = self._target.getBadgeTemplateManager().getPDFOptions()
3714 self.__keepPDFOptions = params.get("keepPDFOptions", False)
3715 #in case of input error, this will be set to False
3717 try:
3718 self.__marginTop = float(params.get("marginTop",''))
3719 except ValueError:
3720 self.__marginTop = self.__PDFOptions.getTopMargin()
3721 self.__keepPDFOptions = False
3723 try:
3724 self.__marginBottom = float(params.get("marginBottom",''))
3725 except ValueError:
3726 self.__marginBottom = self.__PDFOptions.getBottomMargin()
3727 self.__keepPDFOptions = False
3729 try:
3730 self.__marginLeft = float(params.get("marginLeft",''))
3731 except ValueError:
3732 self.__marginLeft = self.__PDFOptions.getLeftMargin()
3733 self.__keepPDFOptions = False
3735 try:
3736 self.__marginRight = float(params.get("marginRight",''))
3737 except ValueError:
3738 self.__marginRight = self.__PDFOptions.getRightMargin()
3739 self.__keepPDFOptions = False
3741 try:
3742 self.__marginColumns = float(params.get("marginColumns",''))
3743 except ValueError:
3744 self.__marginColumns = self.__PDFOptions.getMarginColumns()
3745 self.__keepPDFOptions = False
3747 try:
3748 self.__marginRows = float(params.get("marginRows",''))
3749 except ValueError:
3750 self.__marginRows = self.__PDFOptions.getMarginRows()
3751 self.__keepPDFOptions = False
3753 self.__pagesize = params.get("pagesize",'A4')
3755 self.__drawDashedRectangles = params.get("drawDashedRectangles", False) is not False
3756 self.__landscape = params.get('landscape') == '1'
3758 self.__registrantList = params.get("registrantList","all")
3759 if self.__registrantList != "all":
3760 self.__registrantList = self.__registrantList.split(',')
3763 def _process(self):
3764 if self._target.isClosed():
3765 p = conferences.WPConferenceModificationClosed( self, self._target )
3766 return p
3767 else:
3768 if self._conf.getRegistrantsList() == []:
3769 return _("There are no registrants, so no badges to print.")
3770 elif self.__templateId == None:
3771 return _("There is no badge template selected for this conference.")
3773 if self.__keepPDFOptions:
3774 #we store the pdf options into the conference
3775 self.__PDFOptions.setTopMargin(self.__marginTop)
3776 self.__PDFOptions.setBottomMargin(self.__marginBottom)
3777 self.__PDFOptions.setLeftMargin(self.__marginLeft)
3778 self.__PDFOptions.setRightMargin(self.__marginRight)
3779 self.__PDFOptions.setMarginColumns(self.__marginColumns)
3780 self.__PDFOptions.setMarginRows(self.__marginRows)
3781 self.__PDFOptions.setPagesize(self.__pagesize)
3782 self.__PDFOptions.setDrawDashedRectangles(self.__drawDashedRectangles)
3783 self.__PDFOptions.setLandscape(self.__landscape)
3786 pdf = RegistrantsListToBadgesPDF(self._conf,
3787 self._conf.getBadgeTemplateManager().getTemplateById(self.__templateId),
3788 self.__marginTop,
3789 self.__marginBottom,
3790 self.__marginLeft,
3791 self.__marginRight,
3792 self.__marginColumns,
3793 self.__marginRows,
3794 self.__pagesize,
3795 self.__drawDashedRectangles,
3796 self.__registrantList,
3797 self.__landscape)
3798 return send_file('Badges.pdf', StringIO(pdf.getPDFBin()), 'PDF')
3801 class RHConfBadgeSaveTempBackground(RHConfBadgeBase):
3802 """ This class is used to save a background as a temporary file,
3803 before it is archived. Temporary backgrounds are archived
3804 after pressing the "save" button.
3805 The temporary background filepath can be stored in the session
3806 object (if we are creating a new template and it has not been stored yet)
3807 or in the corresponding template if we are editing a template.
3810 def _getNewTempFile( self ):
3811 cfg = Config.getInstance()
3812 tempPath = cfg.getUploadedFilesSharedTempDir()
3813 tempFileName = tempfile.mkstemp( suffix="IndicoBadgeBG.tmp", dir = tempPath )[1]
3814 return tempFileName
3816 def _saveFileToTemp(self, fs):
3817 fileName = self._getNewTempFile()
3818 fs.save(fileName)
3819 return os.path.split(fileName)[-1]
3821 def _checkParams(self, params):
3822 RHConfBadgeBase._checkParams(self, params)
3823 self.__templateId = params.get("templateId",None)
3824 try:
3825 self._tempFilePath = self._saveFileToTemp(params["file"])
3826 except AttributeError:
3827 self._tempFilePath = None
3829 def _process(self):
3830 if self._target.isClosed():
3831 return json.dumps({'status': 'error'}, textarea=True)
3832 else:
3833 if self._tempFilePath is not None:
3834 if self._conf.getBadgeTemplateManager().hasTemplate(self.__templateId):
3835 backgroundId = self._conf.getBadgeTemplateManager().getTemplateById(self.__templateId).addTempBackgroundFilePath(self._tempFilePath)
3836 else:
3837 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3838 value = session.get(key)
3839 if value is None:
3840 tempFilePathList = PersistentList()
3841 tempFilePathList.append(self._tempFilePath)
3842 session[key] = tempFilePathList
3843 backgroundId = 0
3844 else:
3845 value.append(self._tempFilePath)
3846 backgroundId = len(value) - 1
3847 session.modified = True
3849 return json.dumps({
3850 'status': 'OK',
3851 'id': backgroundId,
3852 'url': str(urlHandlers.UHConfModifBadgeGetBackground.getURL(self._conf, self.__templateId, backgroundId))
3853 }, textarea=True)
3855 class RHConfBadgeGetBackground(RHConfBadgeBase):
3856 """ Class used to obtain a background in order to display it
3857 on the Badge Design screen.
3858 The background can be obtained from the archived files
3859 or from the temporary files.
3862 def _checkParams(self, params):
3863 RHConfBadgeBase._checkParams(self, params)
3864 self.__templateId = params.get("templateId",None)
3865 self.__backgroundId = int(params.get("backgroundId",None))
3866 self.__width = int(params.get("width","-1"))
3867 self.__height = int(params.get("height","-1"))
3869 def __imageBin(self, image):
3870 mimetype = image.getFileType() or 'application/octet-stream'
3871 return send_file(image.getFileName(), image.getFilePath(), mimetype)
3873 def __fileBin(self, filePath):
3874 return send_file('tempBackground', filePath, 'application/octet-stream')
3876 def _process(self):
3877 if self._target.isClosed():
3878 p = conferences.WPConferenceModificationClosed( self, self._target )
3879 return p
3880 else:
3881 cfg = Config.getInstance()
3882 tempPath = cfg.getUploadedFilesSharedTempDir()
3883 if self._conf.getBadgeTemplateManager().hasTemplate(self.__templateId):
3884 isArchived, image = self._conf.getBadgeTemplateManager().getTemplateById(self.__templateId).getBackground(self.__backgroundId)
3885 if image is not None:
3886 if isArchived:
3887 return self.__imageBin(image)
3888 else:
3889 image = os.path.join(tempPath,image)
3890 return self.__fileBin(image)
3892 else:
3893 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3894 filePath = os.path.join(tempPath, session[key][int(self.__backgroundId)])
3895 return self.__fileBin(filePath)
3898 # ============================================================================
3899 # === Posters related ========================================================
3900 # ============================================================================
3902 ##------------------------------------------------------------------------------------------------------------
3904 Poster Design and Printing classes
3906 class RHConfPosterPrinting(RHConferenceModifBase):
3907 """ This class corresponds to the screen where templates are
3908 listed and can be created, edited, deleted and tried.
3909 It always displays the list of templates; but we can
3910 arrive to this page in different scenarios:
3911 -A template has just been created (templateId = new template id, new = True). The template
3912 will be stored and the temporary backgrounds stored in the session object archived.
3913 -A template has been edited (templateId = existing template id, new = False or not set).
3914 The template will be updated and the temporary backgrounds stored in it, archived.
3915 -A template had been deleted (deleteTemplateId = id of the template to delete)
3916 -We were creating / editing a template but we pressed the "Cancel" button
3917 (templateId = id of the template that was being created / edited, Cancel = True).
3918 Temporary backgrounds (in the session object or in the template object) will be deleted.
3921 def _checkParams(self, params):
3922 RHConferenceModifBase._checkParams(self, params)
3923 self.__templateId = params.get("templateId",None)
3924 self.__templateData = params.get("templateData",None)
3925 self.__deleteTemplateId = params.get("deleteTemplateId",None)
3926 self.__copyTemplateId = params.get("copyTemplateId",None)
3927 self.__bgPosition = params.get("bgPosition",None)
3928 self.__new = params.get("new","False") == "True"
3929 self.__cancel = params.get("cancel","False") == "True"
3932 def _process(self):
3933 if self._target.isClosed():
3934 return conferences.WPConferenceModificationClosed(self, self._target).display()
3935 else:
3936 if self.__templateId and self.__templateData and not self.__deleteTemplateId:
3937 if self.__new:
3938 # template is new
3939 self._target.getPosterTemplateManager().storeTemplate(self.__templateId, self.__templateData)
3940 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3941 filePaths = session.get(key)
3942 if filePaths:
3943 for filePath in filePaths:
3944 self._target.getPosterTemplateManager().getTemplateById(self.__templateId).addTempBackgroundFilePath(filePath[0],filePath[1])
3945 self._target.getPosterTemplateManager().getTemplateById(self.__templateId).archiveTempBackgrounds(self._conf)
3946 else:
3947 # template already exists
3948 self._target.getPosterTemplateManager().storeTemplate(self.__templateId, self.__templateData)
3949 elif self.__deleteTemplateId:
3950 self._target.getPosterTemplateManager().deleteTemplate(self.__deleteTemplateId)
3951 elif self.__copyTemplateId:
3952 self._target.getPosterTemplateManager().copyTemplate(self.__copyTemplateId)
3953 elif self.__cancel:
3954 if self._target.getPosterTemplateManager().hasTemplate(self.__templateId):
3955 self._target.getPosterTemplateManager().getTemplateById(self.__templateId).deleteTempBackgrounds()
3956 else:
3957 fkey = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
3958 session.pop(fkey, None)
3960 if self._target.getId() == "default":
3961 p = admins.WPPosterTemplates(self)
3962 url = urlHandlers.UHPosterTemplates.getURL()
3963 else:
3964 p = conferences.WPConfModifPosterPrinting(self, self._target)
3965 url = urlHandlers.UHConfModifPosterPrinting.getURL(self._target)
3966 if request.method == 'POST':
3967 self._redirect(url)
3968 else:
3969 return p.display()
3972 class RHConfPosterDesign(RHConferenceModifBase):
3973 """ This class corresponds to the screen where templates are
3974 designed. We can arrive to this screen from different scenarios:
3975 -We are creating a new template (templateId = new template id, new = True)
3976 -We are editing an existing template (templateId = existing template id, new = False or not set)
3979 def _checkParams(self, params):
3980 RHConferenceModifBase._checkParams(self, params)
3981 self.__templateId = params.get("templateId",None)
3982 new = params.get("new",'False')
3983 if new == 'False':
3984 self.__new = False
3985 else:
3986 self.__new = True
3987 self.__baseTemplate = params.get("baseTemplate",'blank')
3989 def _process(self):
3990 if self._target.isClosed():
3991 p = conferences.WPConferenceModificationClosed( self, self._target )
3992 else:
3993 if (self._target.getId() == "default"):
3994 p = admins.WPPosterTemplateDesign(self, self._target, self.__templateId, self.__new)
3995 else:
3996 if self.__new == True and self.__baseTemplate != 'blank':
3997 dconf = conference.CategoryManager().getDefaultConference()
3998 templMan = self._target.getPosterTemplateManager()
3999 newId = self.__templateId
4000 dconf.getPosterTemplateManager().getTemplateById(self.__baseTemplate).clone(templMan, newId)
4001 url = urlHandlers.UHConfModifPosterPrinting().getURL(self._target)
4002 self._redirect(url)
4003 return
4004 else:
4005 p = conferences.WPConfModifPosterDesign(self, self._target, self.__templateId, self.__new, self.__baseTemplate)
4006 return p.display()
4008 class RHConfPosterPrintingPDF(RHConferenceModifBase):
4010 This class is used to print the PDF from a poster template.
4012 def _checkParams(self, params):
4013 RHConferenceModifBase._checkParams(self, params)
4014 self.__templateId = params.get("templateId",None)
4015 if self.__templateId == None:
4016 raise FormValuesError(_("Poster not selected"))
4017 if self.__templateId.find('global') != -1:
4018 self.__templateId = self.__templateId.replace('global','')
4019 self.__template = conference.CategoryManager().getDefaultConference().getPosterTemplateManager().getTemplateById(self.__templateId)
4020 else:
4021 self.__template = self._conf.getPosterTemplateManager().getTemplateById(self.__templateId)
4022 try:
4023 self.__marginH = int(params.get("marginH",'2'))
4024 except ValueError:
4025 self.__marginH = 2
4026 try:
4027 self.__marginV = int(params.get("marginV",'2'))
4028 except ValueError:
4029 self.__marginV = 2
4030 self.__pagesize = params.get("pagesize",'A4')
4033 def _process(self):
4034 if self._target.isClosed():
4035 p = conferences.WPConferenceModificationClosed( self, self._target )
4036 return p
4037 else:
4038 pdf = LectureToPosterPDF(self._conf,
4039 self.__template,
4040 self.__marginH,
4041 self.__marginV,
4042 self.__pagesize)
4044 return send_file('Poster.pdf', StringIO(pdf.getPDFBin()), 'PDF')
4047 class RHConfPosterSaveTempBackground(RHConferenceModifBase):
4048 """ This class is used to save a background as a temporary file,
4049 before it is archived. Temporary backgrounds are archived
4050 after pressing the "save" button.
4051 The temporary background filepath can be stored in the session
4052 object (if we are creating a new template and it has not been stored yet)
4053 or in the corresponding template if we are editing a template.
4056 def _getNewTempFile( self ):
4057 cfg = Config.getInstance()
4058 tempPath = cfg.getUploadedFilesSharedTempDir()
4059 tempFileName = tempfile.mkstemp( suffix="IndicoPosterBG.tmp", dir = tempPath )[1]
4060 return tempFileName
4062 def _saveFileToTemp(self, fs):
4063 fileName = self._getNewTempFile()
4064 fs.save(fileName)
4065 return os.path.split(fileName)[-1]
4067 def _checkParams(self, params):
4068 RHConferenceModifBase._checkParams(self, params)
4069 self.__templateId = params.get("templateId",None)
4071 self._bgPosition = params.get("bgPosition",None)
4073 try:
4074 self._tempFilePath = self._saveFileToTemp(params["file"])
4075 except AttributeError:
4076 self._tempFilePath = None
4078 def _process(self):
4079 if self._target.isClosed():
4080 return json.dumps({'status': 'error'}, textarea=True)
4081 else:
4082 if self._tempFilePath is not None:
4083 if self._conf.getPosterTemplateManager().hasTemplate(self.__templateId):
4084 # Save
4085 backgroundId = self._conf.getPosterTemplateManager().getTemplateById(self.__templateId).addTempBackgroundFilePath(self._tempFilePath,self._bgPosition)
4086 else:
4087 # New
4088 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
4089 value = session.get(key)
4090 if value is None:
4091 # First background
4092 tempFilePathList = PersistentList()
4093 tempFilePathList.append((self._tempFilePath,self._bgPosition))
4094 session[key] = tempFilePathList
4095 backgroundId = 0
4096 else:
4097 # We have more
4098 value.append((self._tempFilePath, self._bgPosition))
4099 backgroundId = len(value) - 1
4100 session.modified = True
4102 return json.dumps({
4103 'status': 'OK',
4104 'id': backgroundId,
4105 'url': str(urlHandlers.UHConfModifPosterGetBackground.getURL(self._conf, self.__templateId, backgroundId)),
4106 'pos': self._bgPosition
4107 }, textarea=True)
4110 class RHConfPosterGetBackground(RHConferenceModifBase):
4111 """ Class used to obtain a background in order to display it
4112 on the Poster Design screen.
4113 The background can be obtained from the archived files
4114 or from the temporary files.
4117 def _checkParams(self, params):
4118 RHConferenceModifBase._checkParams(self, params)
4119 self.__templateId = params.get("templateId",None)
4120 self.__backgroundId = int(params.get("backgroundId",None))
4121 self.__width = int(params.get("width","-1"))
4122 self.__height = int(params.get("height","-1"))
4124 def __imageBin(self, image):
4125 mimetype = image.getFileType() or 'application/octet-stream'
4126 return send_file(image.getFileName(), image.getFilePath(), mimetype)
4128 def __fileBin(self, filePath):
4129 return send_file('tempBackground', filePath, mimetype='application/octet-stream')
4131 def _process(self):
4133 if self._target.isClosed():
4134 p = conferences.WPConferenceModificationClosed( self, self._target )
4135 return p
4136 else:
4137 cfg = Config.getInstance()
4138 tempPath = cfg.getUploadedFilesSharedTempDir()
4140 if self._conf.getPosterTemplateManager().hasTemplate(self.__templateId):
4142 isArchived, image = self._conf.getPosterTemplateManager().getTemplateById(self.__templateId).getBackground(self.__backgroundId)
4144 if image is not None:
4145 if isArchived:
4146 return self.__imageBin(image)
4147 else:
4148 image = os.path.join(tempPath,image)
4149 return self.__fileBin(image)
4151 else:
4152 key = "tempBackground-%s-%s" % (self._conf.id, self.__templateId)
4153 filePath = os.path.join(tempPath, session[key][int(self.__backgroundId)][0])
4154 return self.__fileBin(filePath)