source: indico/indico/MaKaC/services/implementation/reviewing.py @ f16f89

burotelhello-world-walkthroughipv6v0.98-seriesv0.98.2v0.98.3v0.98b1v0.98b2v0.99v1.0v1.1
Last change on this file since f16f89 was f16f89, checked in by Jose Benito <jose.benito.gonzalez@…>, 2 years ago

[FTR] Abstract reviewing

Implemented several functionalities in abstract reviewing

  • Created inline component to configurate number of possible answers
  • Created inline component to configurate the scale for the rating
  • Recalculate the rating when the scale is changed
  • Created a preview of question in the configuration page
  • Changed the order between Paper Reviewing and Abstracts Reviewing tabs
  • Included the radio buttons titles with the value of each radio button with the mouse over event
  • Separate in two subtabs the Track judgement tab, 'Judgement details' and 'Rating per question'
  • Judgement details where is included a popup with the value of each answer per judgement, the judgement average and the total score. And a new column with the average rating of each judgement
  • Rating per question subtab: Created a new template, request handler...
  • Created in the abstract list a new column with the rating average of each abstract. It is possible to sort by rating. Included a popup that shows you the average per question
  • Modified the judgement running, it is possible to have just a judgement per author
  • Changed some styles in propose to accept/reject pages
  • Property mode set to 100644
File size: 42.7 KB
Line 
1# -*- coding: utf-8 -*-
2##
3##
4## This file is part of CDS Indico.
5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
6##
7## CDS Indico is free software; you can redistribute it and/or
8## modify it under the terms of the GNU General Public License as
9## published by the Free Software Foundation; either version 2 of the
10## License, or (at your option) any later version.
11##
12## CDS Indico is distributed in the hope that it will be useful, but
13## WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15## General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with CDS Indico; if not, write to the Free Software Foundation, Inc.,
19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20from MaKaC.reviewing import ConferencePaperReview
21from MaKaC.reviewing import ConferenceReviewingNotification
22from MaKaC.services.implementation.base import ProtectedModificationService,\
23    TwoListModificationBase, ParameterManager
24from MaKaC.services.implementation.contribution import ContributionBase
25from MaKaC.services.implementation.base import TextModificationBase
26from MaKaC.services.implementation.base import HTMLModificationBase
27from MaKaC.webinterface.rh.reviewingModif import RCPaperReviewManager,\
28    RCAbstractManager, RCReferee
29from MaKaC.services.implementation.conference import ConferenceModifBase
30from MaKaC.services.implementation.base import DateTimeModificationBase
31from MaKaC.webinterface.rh.contribMod import RCContributionReferee
32from MaKaC.webinterface.rh.contribMod import RCContributionEditor
33from MaKaC.webinterface.rh.contribMod import RCContributionReviewer
34from MaKaC.webinterface.user import UserModificationBase, UserListModificationBase
35from MaKaC.services.implementation.base import ListModificationBase
36from MaKaC import user
37from MaKaC.services.interface.rpc.common import ServiceError
38from MaKaC.i18n import _
39from MaKaC.errors import MaKaCError
40import datetime
41from MaKaC.common.mail import GenericMailer
42from MaKaC.contributionReviewing import ReviewManager
43
44
45"""
46Asynchronous request handlers for conference and contribution reviewing related data
47"""
48
49#####################################
50###  Conference reviewing classes
51#####################################
52
53class ConferenceReviewingBase(ConferenceModifBase):
54    """ This base class stores the _confPaperReview attribute
55        so that inheriting classes can use it.
56    """
57    def _checkProtection(self):
58        if self._target.getConference().hasEnabledSection("paperReviewing"):
59            ConferenceModifBase._checkProtection(self)
60        else:
61            raise ServiceError("ERR-REV1a",_("Paper Reviewing is not active for this conference"))
62
63    def _checkParams(self):
64        ConferenceModifBase._checkParams(self)
65        self._confPaperReview = self._conf.getConfPaperReview()
66        self._confAbstractReview = self._conf.getConfAbstractReview()
67
68class ConferenceReviewingPRMBase(ConferenceReviewingBase):
69    """ This base class verifies that the user is a PRM
70    """
71    def _checkProtection(self):
72        if not RCPaperReviewManager.hasRights(self):
73            ConferenceReviewingBase._checkProtection(self)
74
75class ConferenceReviewingAMBase(ConferenceReviewingBase):
76    """ This base class verifies that the user is an AM
77    """
78    def _checkProtection(self):
79        if not RCAbstractManager.hasRights(self):
80            ConferenceReviewingBase._checkProtection(self)
81
82class ConferenceReviewingPRMAMBase(ConferenceReviewingBase):
83    """ This base class verifies that the user is a PRM or an AM
84    """
85    def _checkProtection(self):
86        if not RCPaperReviewManager.hasRights(self) and not RCAbstractManager.hasRights(self):
87            ConferenceReviewingBase._checkProtection(self)
88
89
90class ConferenceReviewingPRMRefereeBase(ConferenceReviewingBase):
91    """ This base class verifies that the user is a PRM or a Referee of the Conference
92    """
93    def _checkProtection(self):
94        if not RCPaperReviewManager.hasRights(self) and not RCReferee.hasRights(self):
95            ConferenceReviewingBase._checkProtection(self)
96
97
98class ConferenceReviewingAssignStaffBase(UserModificationBase, ConferenceReviewingBase):
99    """ Base class for assigning referees, editors, etc. to contributions.
100        It will store a list of Contribution objects in self._contributions.
101        The referee, editor, etc. will be added to those contributions.
102    """
103    def _checkParams(self):
104        UserModificationBase._checkParams(self)
105        ConferenceReviewingBase._checkParams(self)
106        if self._params.has_key('contributions'):
107            pm = ParameterManager(self._params)
108            contributionsIds = pm.extract("contributions", pType=list, allowEmpty=False)
109            self._contributions = [self._conf.getContributionById(contributionId) for contributionId in contributionsIds]
110        else:
111            raise ServiceError("ERR-REV2",_("List of contribution ids not set"))
112
113class ConferenceReviewingAssignStaffBasePRM(ConferenceReviewingAssignStaffBase):
114    """ Base class that inherits from ConferenceReviewingAssignStaffBase,
115        and gives modification rights only to PRMs or Managers.
116    """
117
118    def _checkProtection(self):
119        if not RCPaperReviewManager.hasRights(self):
120            ProtectedModificationService._checkProtection(self)
121
122class ConferenceReviewingAssignStaffBasePRMReferee(ConferenceReviewingAssignStaffBase):
123    """ Base class that inherits from ConferenceReviewingAssignStaffBase,
124        and gives modification rights only to PRMs or Managers or Referees (but in the last
125        case, only to referees of contributions in self._contributions).
126    """
127
128    def _checkProtection(self):
129        hasRights = False;
130        if RCPaperReviewManager.hasRights(self):
131            hasRights = True
132        elif RCReferee.hasRights(self):
133            isRefereeOfAllContributions = True
134            for contribution in self._contributions:
135                if not contribution.getReviewManager().isReferee(self.getAW().getUser()):
136                    isRefereeOfAllContributions = False
137                    break
138            hasRights = isRefereeOfAllContributions
139
140        if not hasRights:
141            ProtectedModificationService._checkProtection(self)
142
143
144
145class ConferenceReviewingSetupTextModificationBase(TextModificationBase, ConferenceReviewingPRMBase):
146    #Note: don't change the order of the inheritance here!
147    pass
148
149class ConferenceReviewingListModificationBase (ListModificationBase, ConferenceReviewingPRMBase):
150    #Note: don't change the order of the inheritance here!
151    pass
152
153class ConferenceReviewingDateTimeModificationBase (DateTimeModificationBase, ConferenceReviewingPRMBase):
154    #Note: don't change the order of the inheritance here!
155    pass
156
157class ConferenceAbstractReviewingDateTimeModificationBase (DateTimeModificationBase, ConferenceReviewingAMBase):
158    #Note: don't change the order of the inheritance here!
159    pass
160
161
162class ConferenceReviewingModeModification(ConferenceReviewingSetupTextModificationBase ):
163
164    def _handleSet(self):
165        self._confPaperReview.setReviewingMode( self._value )
166
167    def _handleGet(self):
168        return self._confPaperReview.getReviewingMode()
169
170class ConferenceReviewingStatesModification(ConferenceReviewingListModificationBase):
171
172    def _handleGet(self):
173        return self._confPaperReview.getStates()
174
175    def _handleSet(self):
176        self._confPaperReview.setStates(self._value)
177
178class ConferenceReviewingQuestionsModification(ConferenceReviewingListModificationBase):
179
180    def _handleGet(self):
181        return self._confPaperReview.getReviewingQuestions()
182
183    def _handleSet(self):
184        self._confPaperReview.setReviewingQuestions(self._value)
185
186class ConferenceAbstractReviewingQuestionsModification(ConferenceReviewingListModificationBase):
187
188    def _handleGet(self):
189        return self._confAbstractReview.getReviewingQuestions()
190
191    def _handleSet(self):
192        self._confAbstractReview.setReviewingQuestions(self._value)
193
194
195class ConferenceReviewingCriteriaModification(ConferenceReviewingListModificationBase):
196
197    def _handleGet(self):
198        return self._confPaperReview.getLayoutCriteria()
199
200    def _handleSet(self):
201        self._confPaperReview.setLayoutCriteria(self._value)
202
203class ConferenceReviewingDeleteTemplate(ConferenceReviewingBase):
204
205    def _getAnswer(self):
206            templateId = self._params.get("templateId")
207            self._confPaperReview.deleteTemplate(templateId)
208            return True
209
210class ConferenceReviewingDefaultDueDateModification(ConferenceReviewingDateTimeModificationBase):
211
212    def _checkParams(self):
213        ConferenceReviewingDateTimeModificationBase._checkParams(self)
214        self._dueDateToChange = self._params.get("dueDateToChange")
215
216    def _setParam(self):
217        if self._dueDateToChange == "Referee":
218            self._conf.getConfPaperReview().setDefaultRefereeDueDate(self._pTime)
219        elif self._dueDateToChange == "Editor":
220            self._conf.getConfPaperReview().setDefaultEditorDueDate(self._pTime)
221        elif self._dueDateToChange == "Reviewer":
222            self._conf.getConfPaperReview().setDefaultReviewerDueDate(self._pTime)
223        else:
224            raise ServiceError("ERR-REV3a",_("Kind of deadline to change not set"))
225
226    def _handleGet(self):
227        if self._dueDateToChange == "Referee":
228            date = self._conf.getConfPaperReview().getAdjustedDefaultRefereeDueDate()
229        elif self._dueDateToChange == "Editor":
230            date = self._conf.getConfPaperReview().getAdjustedDefaultEditorDueDate()
231        elif self._dueDateToChange == "Reviewer":
232            date = self._conf.getConfPaperReview().getAdjustedDefaultReviewerDueDate()
233        else:
234            raise ServiceError("ERR-REV3b",_("Kind of deadline to change not set"))
235
236        if date:
237            return datetime.datetime.strftime(date,'%d/%m/%Y %H:%M')
238
239class ConferenceAbstractReviewingDefaultDueDateModification(ConferenceAbstractReviewingDateTimeModificationBase):
240
241    def _setParam(self):
242        self._conf.getConfAbstractReview().setDefaultAbstractReviewerDueDate(self._pTime)
243
244    def _handleGet(self):
245        date = self._conf.getConfAbstractReview().getAdjustedDefaultAbstractReviewerDueDate()
246        if date:
247            return datetime.datetime.strftime(date,'%d/%m/%Y %H:%M')
248
249class ConferenceReviewingAutoEmailsModificationPRM(ConferenceReviewingSetupTextModificationBase ):
250
251    def _handleSet(self):
252        if self._value:
253            self._confPaperReview.enablePRMEmailNotif()
254        else:
255            self._confPaperReview.disablePRMEmailNotif()
256
257    def _handleGet(self):
258        return self._confPaperReview.getEnablePRMEmailNotif()
259
260class ConferenceReviewingAutoEmailsModificationReferee(ConferenceReviewingSetupTextModificationBase ):
261
262    def _handleSet(self):
263        if self._value:
264            self._confPaperReview.enableRefereeEmailNotif()
265        else:
266            self._confPaperReview.disableRefereeEmailNotif()
267
268    def _handleGet(self):
269        return self._confPaperReview.getEnableRefereeEmailNotif()
270
271class ConferenceReviewingAutoEmailsModificationEditor(ConferenceReviewingSetupTextModificationBase ):
272
273    def _handleSet(self):
274        if self._value:
275            self._confPaperReview.enableEditorEmailNotif()
276        else:
277            self._confPaperReview.disableEditorEmailNotif()
278
279    def _handleGet(self):
280        return self._confPaperReview.getEnableEditorEmailNotif()
281
282class ConferenceReviewingAutoEmailsModificationReviewer(ConferenceReviewingSetupTextModificationBase ):
283
284    def _handleSet(self):
285        if self._value:
286            self._confPaperReview.enableReviewerEmailNotif()
287        else:
288            self._confPaperReview.disableReviewerEmailNotif()
289
290    def _handleGet(self):
291        return self._confPaperReview.getEnableReviewerEmailNotif()
292
293class ConferenceReviewingAutoEmailsModificationRefereeForContribution(ConferenceReviewingSetupTextModificationBase):
294
295    def _handleSet(self):
296        if self._value:
297            self._confPaperReview.enableRefereeEmailNotifForContribution()
298        else:
299            self._confPaperReview.disableRefereeEmailNotifForContribution()
300
301    def _handleGet(self):
302        return self._confPaperReview.getEnableRefereeEmailNotifForContribution()
303
304class ConferenceReviewingAutoEmailsModificationEditorForContribution(ConferenceReviewingSetupTextModificationBase):
305
306    def _handleSet(self):
307        if self._value:
308            self._confPaperReview.enableEditorEmailNotifForContribution()
309        else:
310            self._confPaperReview.disableEditorEmailNotifForContribution()
311
312    def _handleGet(self):
313        return self._confPaperReview.getEnableEditorEmailNotifForContribution()
314
315class ConferenceReviewingAutoEmailsModificationReviewerForContribution(ConferenceReviewingSetupTextModificationBase):
316
317    def _handleSet(self):
318        if self._value:
319            self._confPaperReview.enableReviewerEmailNotifForContribution()
320        else:
321            self._confPaperReview.disableReviewerEmailNotifForContribution()
322
323    def _handleGet(self):
324        return self._confPaperReview.getEnableReviewerEmailNotifForContribution()
325
326class ConferenceReviewingAutoEmailsModificationRefereeJudgement(ConferenceReviewingSetupTextModificationBase):
327
328    def _handleSet(self):
329        if self._value:
330            self._confPaperReview.enableRefereeJudgementEmailNotif()
331        else:
332            self._confPaperReview.disableRefereeJudgementEmailNotif()
333
334    def _handleGet(self):
335        return self._confPaperReview.getEnableRefereeJudgementEmailNotif()
336
337class ConferenceReviewingAutoEmailsModificationEditorJudgement(ConferenceReviewingSetupTextModificationBase):
338
339    def _handleSet(self):
340        if self._value:
341            self._confPaperReview.enableEditorJudgementEmailNotif()
342        else:
343            self._confPaperReview.disableEditorJudgementEmailNotif()
344
345    def _handleGet(self):
346        return self._confPaperReview.getEnableEditorJudgementEmailNotif()
347
348class ConferenceReviewingAutoEmailsModificationReviewerJudgement(ConferenceReviewingSetupTextModificationBase):
349
350    def _handleSet(self):
351        if self._value:
352            self._confPaperReview.enableReviewerJudgementEmailNotif()
353        else:
354            self._confPaperReview.disableReviewerJudgementEmailNotif()
355
356    def _handleGet(self):
357        return self._confPaperReview.getEnableReviewerJudgementEmailNotif()
358
359class ConferenceReviewingAutoEmailsModificationAuthorSubmittedMatReferee(ConferenceReviewingSetupTextModificationBase):
360
361    def _handleSet(self):
362        if self._value:
363            self._confPaperReview.enableAuthorSubmittedMatRefereeEmailNotif()
364        else:
365            self._confPaperReview.disableAuthorSubmittedMatRefereeEmailNotif()
366
367    def _handleGet(self):
368        return self._confPaperReview.getEnableAuthorSubmittedMatRefereeEmailNotif()
369
370class ConferenceReviewingAutoEmailsModificationAuthorSubmittedMatEditor(ConferenceReviewingSetupTextModificationBase):
371
372    def _handleSet(self):
373        if self._value:
374            self._confPaperReview.enableAuthorSubmittedMatEditorEmailNotif()
375        else:
376            self._confPaperReview.disableAuthorSubmittedMatEditorEmailNotif()
377
378    def _handleGet(self):
379        return self._confPaperReview.getEnableAuthorSubmittedMatEditorEmailNotif()
380
381class ConferenceReviewingAutoEmailsModificationAuthorSubmittedMatReviewer(ConferenceReviewingSetupTextModificationBase):
382
383    def _handleSet(self):
384        if self._value:
385            self._confPaperReview.enableAuthorSubmittedMatReviewerEmailNotif()
386        else:
387            self._confPaperReview.disableAuthorSubmittedMatReviewerEmailNotif()
388
389    def _handleGet(self):
390        return self._confPaperReview.getEnableAuthorSubmittedMatReviewerEmailNotif()
391
392
393class ConferenceReviewingCompetenceModification(ListModificationBase, ConferenceReviewingPRMAMBase):
394    #Note: don't change the order of the inheritance here!
395    """ Class to change competences of users.
396        Both PRMs and AMs can do this so this class inherits from ConferenceReviewingPRMAMBase.
397        Note: don't change the order of the inheritance!
398    """
399
400    def _checkParams(self):
401        ConferenceReviewingPRMAMBase._checkParams(self)
402        userId = self._params.get("user", None)
403        if userId:
404            ph = user.PrincipalHolder()
405            self._user =  ph.getById( userId )
406        else:
407            raise ServiceError("ERR-REV4",_("No user id specified"))
408
409    def _handleGet(self):
410        return self._confPaperReview.getCompetencesByUser(self._user)
411
412    def _handleSet(self):
413        self._confPaperReview.setUserCompetences(self._user, self._value)
414
415class ConferenceReviewingContributionsAttributeList(ListModificationBase, ConferenceReviewingPRMRefereeBase):
416    #Note: don't change the order of the inheritance here!
417    """ Class to return all the tracks or sessions or types of the conference
418    """
419    def _checkParams(self):
420        ConferenceReviewingPRMRefereeBase._checkParams(self)
421        self._attribute = self._params.get("attribute", None)
422        if self._attribute is None:
423            raise ServiceError("ERR-REV5",_("No type/session/track specified"))
424
425    def _handleGet(self):
426        attributes = []
427        for c in self._conf.getContributionList():
428            if self._attribute == 'type':
429                if c.getType() is not None and c.getType() not in attributes:
430                    attributes.append(c.getType())
431            elif self._attribute == 'track':
432                if c.getTrack() is not None and c.getTrack() not in attributes:
433                    attributes.append(c.getTrack())
434            elif self._attribute == 'session':
435                if c.getSession() is not None and c.getSession() not in attributes:
436                    attributes.append(c.getSession())
437            else:
438                raise ServiceError("ERR-REV5",_("No attribute specified"))
439
440        if self._attribute == 'type':
441            return [{"id": attribute.getId(), "title": attribute.getName()}
442                for attribute in attributes]
443        else:
444            return [{"id": attribute.getId(), "title": attribute.getTitle()}
445                for attribute in attributes]
446
447class ConferenceReviewingContributionsPerSelectedAttributeList(ListModificationBase, ConferenceReviewingPRMRefereeBase):
448    #Note: don't change the order of the inheritance here!
449    """ Class to return all the contributions ids for the selected track/session/type of the conference
450    """
451    def _checkParams(self):
452        ConferenceReviewingPRMRefereeBase._checkParams(self)
453        self._attribute = self._params.get("attribute", None)
454        if self._attribute is None:
455            raise ServiceError("ERR-REV5",_("No type/session/track specified"))
456        self._selectedAttribute = self._params.get("selectedAttributes", None)
457        if self._selectedAttribute is None:
458            raise ServiceError("ERR-REV5",_("No attribute specified"))
459
460    def _handleGet(self):
461        contributionsPerSelectedAttribute = []
462        for c in self._conf.getContributionList():
463            for att in self._selectedAttribute:
464                if self._attribute == 'type':
465                    if c.getType() is not None and c.getId() not in contributionsPerSelectedAttribute:
466                        if c.getType().getId() == att:
467                            contributionsPerSelectedAttribute.append(c.getId())
468                elif self._attribute == 'track':
469                    if c.getTrack() is not None and c.getId() not in contributionsPerSelectedAttribute:
470                        if c.getTrack().getId() == att:
471                            contributionsPerSelectedAttribute.append(c.getId())
472                elif self._attribute == 'session':
473                    if c.getSession() is not None and c.getId() not in contributionsPerSelectedAttribute:
474                        if c.getSession().getId() == att:
475                            contributionsPerSelectedAttribute.append(c.getId())
476                else:
477                    raise ServiceError("ERR-REV5",_("No attribute specified"))
478
479
480        return contributionsPerSelectedAttribute
481
482
483class ConferenceReviewingUserCompetenceList(ListModificationBase, ConferenceReviewingPRMRefereeBase):
484    #Note: don't change the order of the inheritance here!
485    """ Class to return all the referees / editors / reviewers of the conference,
486        plus their competences.
487    """
488    def _checkParams(self):
489        ConferenceReviewingPRMRefereeBase._checkParams(self)
490        self._role = self._params.get("role", None)
491        if self._role is None:
492            raise ServiceError("ERR-REV5",_("No role specified"))
493
494    def _handleGet(self):
495        return [{"id": user.getId(), "name": user.getStraightFullName(), "competences": c}
496                for user, c in self._confPaperReview.getAllUserCompetences(True, self._role)]
497
498class ConferenceReviewingAssignReferee(ConferenceReviewingAssignStaffBasePRM):
499    """ Assigns a referee to a list of contributions
500    """
501    def _getAnswer(self):
502        if self._confPaperReview.getChoice() == 1 or self._confPaperReview.getChoice() == 3:
503            raise ServiceError("ERR-REV6aa",_("can't assign referee"))
504        if not self._targetUser:
505            raise ServiceError("ERR-REV6a",_("user id not set"))
506
507        for contribution in self._contributions:
508            rm = contribution.getReviewManager()
509            if not rm.isReferee(self._targetUser):
510                if rm.hasReferee():
511                    rm.removeReferee()
512                rm.setReferee(self._targetUser)
513        return True
514
515class ConferenceReviewingRemoveReferee(ConferenceReviewingAssignStaffBasePRM):
516    """ Removes the referee from a list of contributions
517    """
518    def _getAnswer(self):
519        for contribution in self._contributions:
520            rm = contribution.getReviewManager()
521            if rm.hasReferee():
522                rm.removeReferee()
523        return True
524
525
526class ConferenceReviewingAssignEditor(ConferenceReviewingAssignStaffBasePRMReferee):
527    """ Assigns an editor to a list of contributions
528    """
529    def _getAnswer(self):
530        if self._confPaperReview.getChoice() == 1 or self._confPaperReview.getChoice() == 2:
531            raise ServiceError("ERR-REV6bb",_("can't assign layout reviewer"))
532        if not self._targetUser:
533            raise ServiceError("ERR-REV6b",_("user id not set"))
534
535        for contribution in self._contributions:
536            rm = contribution.getReviewManager()
537            if rm.hasReferee() or self._confPaperReview.getChoice() == 3:
538                if not rm.isEditor(self._targetUser):
539                    if rm.hasEditor():
540                        rm.removeEditor()
541                    rm.setEditor(self._targetUser)
542            else:
543                raise ServiceError("ERR-REV9a",_("This contribution has no Referee yet"))
544        return True
545
546class ConferenceReviewingRemoveEditor(ConferenceReviewingAssignStaffBasePRMReferee):
547    """ Removes the editor from a list of contributions
548    """
549    def _getAnswer(self):
550        for contribution in self._contributions:
551            rm = contribution.getReviewManager()
552            if rm.hasEditor():
553                rm.removeEditor()
554        return True
555
556
557class ConferenceReviewingAddReviewer(ConferenceReviewingAssignStaffBasePRMReferee):
558    """ Adds a reviewer to a list of contributions
559    """
560    def _getAnswer(self):
561        if self._confPaperReview.getChoice() == 1 or self._confPaperReview.getChoice() == 3:
562            raise ServiceError("ERR-REV6cc",_("can't assign content reviewer"))
563        if not self._targetUser:
564            raise ServiceError("ERR-REV6c",_("user id not set"))
565
566        for contribution in self._contributions:
567            rm = contribution.getReviewManager()
568            if rm.hasReferee():
569                if not rm.isReviewer(self._targetUser):
570                    rm.addReviewer(self._targetUser)
571            else:
572                raise ServiceError("ERR-REV9b",_("This contribution has no Referee yet"))
573        return True
574
575class ConferenceReviewingRemoveReviewer(ConferenceReviewingAssignStaffBasePRMReferee):
576    """ Removes a given reviewer from a list of contributions
577    """
578    def _getAnswer(self):
579        if not self._targetUser:
580            raise ServiceError("ERR-REV6d",_("user id not set"))
581
582        for contribution in self._contributions:
583            rm = contribution.getReviewManager()
584            rm.removeReviewer(self._targetUser)
585        return True
586
587
588class ConferenceReviewingRemoveAllReviewers(ConferenceReviewingAssignStaffBasePRMReferee):
589    """ Removes all the reviewers from a list of contributions
590    """
591    def _getAnswer(self):
592        for contribution in self._contributions:
593            contribution.getReviewManager().removeAllReviewers()
594        return True
595
596
597######################################################
598###  Assign/Remove Team classes ###
599######################################################
600
601class ConferenceReviewingAssignTeamPRM(UserListModificationBase, ConferenceReviewingPRMAMBase):
602    """ Adds paper review managers to reviewers team for the conference
603    """
604    def _checkParams(self):
605        UserListModificationBase._checkParams(self)
606        ConferenceReviewingPRMAMBase._checkParams(self)
607
608    def _checkProtection(self):
609        ConferenceReviewingPRMAMBase._checkProtection(self)
610
611    def _getAnswer(self):
612        for user in self._avatars:
613            if not user in self._confPaperReview._paperReviewManagersList:
614                self._confPaperReview.addPaperReviewManager(user)
615
616        return True
617
618class ConferenceReviewingRemoveTeamPRM(UserModificationBase, ConferenceReviewingPRMAMBase):
619    """ Removes paper review manager from reviewers team for the conference
620    """
621    def _checkParams(self):
622        UserModificationBase._checkParams(self)
623        ConferenceReviewingPRMAMBase._checkParams(self)
624
625    def _checkProtection(self):
626        ConferenceReviewingPRMAMBase._checkProtection(self)
627
628    def _getAnswer(self):
629        self._confPaperReview.removePaperReviewManager(self._targetUser)
630
631        return True
632
633class ConferenceReviewingAssignTeamReferee(UserListModificationBase, ConferenceReviewingPRMAMBase):
634    """ Adds referee to reviewers team for the conference
635    """
636    def _checkParams(self):
637        UserListModificationBase._checkParams(self)
638        ConferenceReviewingPRMAMBase._checkParams(self)
639
640    def _checkProtection(self):
641        ConferenceReviewingPRMAMBase._checkProtection(self)
642
643    def _getAnswer(self):
644        for user in self._avatars:
645            if not user in self._confPaperReview._refereesList:
646                self._confPaperReview.addReferee(user)
647
648        return True
649
650class ConferenceReviewingRemoveTeamReferee(UserModificationBase, ConferenceReviewingPRMAMBase):
651    """ Removes referee from reviewers team for the conference
652    """
653    def _checkParams(self):
654        UserModificationBase._checkParams(self)
655        ConferenceReviewingPRMAMBase._checkParams(self)
656
657    def _checkProtection(self):
658        ConferenceReviewingPRMAMBase._checkProtection(self)
659
660    def _getAnswer(self):
661        judgedContribs = self._confPaperReview.getJudgedContributions(self._targetUser)[:]
662        for contribution in judgedContribs:
663            rm = contribution.getReviewManager()
664            if rm.hasReferee():
665                rm.removeReferee()
666        self._confPaperReview.removeReferee(self._targetUser)
667
668        return True
669
670
671class ConferenceReviewingAssignTeamEditor(UserListModificationBase, ConferenceReviewingPRMAMBase):
672    """ Adds editor to reviewers team for the conference
673    """
674    def _checkParams(self):
675        UserListModificationBase._checkParams(self)
676        ConferenceReviewingPRMAMBase._checkParams(self)
677
678    def _checkProtection(self):
679        ConferenceReviewingPRMAMBase._checkProtection(self)
680
681    def _getAnswer(self):
682        for user in self._avatars:
683            if not user in self._confPaperReview._editorsList:
684                self._confPaperReview.addEditor(user)
685
686        return True
687
688class ConferenceReviewingRemoveTeamEditor(UserModificationBase, ConferenceReviewingPRMAMBase):
689    """ Removes editor from reviewers team for the conference
690    """
691    def _checkParams(self):
692        UserModificationBase._checkParams(self)
693        ConferenceReviewingPRMAMBase._checkParams(self)
694
695    def _checkProtection(self):
696        ConferenceReviewingPRMAMBase._checkProtection(self)
697
698    def _getAnswer(self):
699        editedContribs = self._confPaperReview.getEditedContributions(self._targetUser)[:]
700        for contribution in editedContribs:
701            rm = contribution.getReviewManager()
702            if rm.hasEditor():
703                rm.removeEditor()
704        self._confPaperReview.removeEditor(self._targetUser)
705
706        return True
707
708
709class ConferenceReviewingAssignTeamReviewer(UserListModificationBase, ConferenceReviewingPRMAMBase):
710    """ Adds editor to reviewers team for the conference
711    """
712    def _checkParams(self):
713        UserListModificationBase._checkParams(self)
714        ConferenceReviewingPRMAMBase._checkParams(self)
715
716    def _checkProtection(self):
717        ConferenceReviewingPRMAMBase._checkProtection(self)
718
719    def _getAnswer(self):
720        for user in self._avatars:
721            if not user in self._confPaperReview._reviewersList:
722                self._confPaperReview.addReviewer(user)
723
724        return True
725
726class ConferenceReviewingRemoveTeamReviewer(UserModificationBase, ConferenceReviewingPRMAMBase):
727    """ Removes editor from reviewers team for the conference
728    """
729    def _checkParams(self):
730        UserModificationBase._checkParams(self)
731        ConferenceReviewingPRMAMBase._checkParams(self)
732
733    def _checkProtection(self):
734        ConferenceReviewingPRMAMBase._checkProtection(self)
735
736    def _getAnswer(self):
737        if not self._targetUser:
738            raise ServiceError("ERR-REV6d",_("user id not set"))
739
740        reviewedContribs = self._confPaperReview.getReviewedContributions(self._targetUser)[:]
741        for contribution in reviewedContribs:
742            rm = contribution.getReviewManager()
743            rm.removeReviewer(self._targetUser)
744        self._confPaperReview.removeReviewer(self._targetUser)
745
746        return True
747#####################################
748###  Contribution reviewing classes
749#####################################
750class ContributionReviewingBase(ProtectedModificationService, ContributionBase):
751
752    def _checkParams(self):
753        ContributionBase._checkParams(self)
754        self._current = self._params.get("current", None)
755
756    def _checkProtection(self):
757        if self._target.getConference().hasEnabledSection("paperReviewing"):
758            hasRights = False
759            if self._current == 'refereeJudgement':
760                hasRights =  RCContributionReferee.hasRights(self)
761            elif self._current == 'editorJudgement':
762                hasRights =  RCContributionEditor.hasRights(self)
763            elif self._current == 'reviewerJudgement':
764                hasRights = RCContributionReviewer.hasRights(self)
765
766            if not hasRights and not RCPaperReviewManager.hasRights(self):
767                ProtectedModificationService._checkProtection(self)
768        else:
769            raise ServiceError("ERR-REV1b",_("Paper Reviewing is not active for this conference"))
770
771
772    def getJudgementObject(self):
773        lastReview = self._target.getReviewManager().getLastReview()
774        if self._current == 'refereeJudgement':
775            return lastReview.getRefereeJudgement()
776        elif self._current == 'editorJudgement':
777            return lastReview.getEditorJudgement()
778        elif self._current == 'reviewerJudgement':
779            return lastReview.getReviewerJudgement(self._getUser())
780        else:
781            raise ServiceError("ERR-REV7",_("Current kind of judgement not specified"))
782
783class ContributionReviewingTextModificationBase (TextModificationBase, ContributionReviewingBase):
784    #Note: don't change the order of the inheritance here!
785    pass
786
787class ContributionReviewingHTMLModificationBase (HTMLModificationBase, ContributionReviewingBase):
788    #Note: don't change the order of the inheritance here!
789    pass
790
791class ContributionReviewingDateTimeModificationBase (DateTimeModificationBase, ContributionReviewingBase):
792    #Note: don't change the order of the inheritance here!
793    pass
794
795class ContributionReviewingDueDateModification(ContributionReviewingDateTimeModificationBase):
796
797    def _checkParams(self):
798        ContributionReviewingDateTimeModificationBase._checkParams(self)
799        self._dueDateToChange = self._params.get("dueDateToChange")
800
801
802    def _setParam(self):
803        lastReview = self._target.getReviewManager().getLastReview()
804        if self._dueDateToChange == "Referee":
805            lastReview.setRefereeDueDate(self._pTime)
806        elif self._dueDateToChange == "Editor":
807            lastReview.setEditorDueDate(self._pTime)
808        elif self._dueDateToChange == "Reviewer":
809            lastReview.setReviewerDueDate(self._pTime)
810        else:
811            raise ServiceError("ERR-REV3c",_("Kind of deadline to change not set"))
812
813    def _handleGet(self):
814        lastReview = self._target.getReviewManager().getLastReview()
815        if self._dueDateToChange == "Referee":
816            date = lastReview.getAdjustedRefereeDueDate()
817        elif self._dueDateToChange == "Editor":
818            date = lastReview.getAdjustedEditorDueDate()
819        elif self._dueDateToChange == "Reviewer":
820            date = lastReview.getAdjustedReviewerDueDate()
821        else:
822            raise ServiceError("ERR-REV3d",_("Kind of deadline to change not set"))
823
824        if date:
825            return datetime.datetime.strftime(date,'%d/%m/%Y %H:%M')
826
827class ContributionReviewingJudgementModification(ContributionReviewingTextModificationBase):
828
829    def _handleSet(self):
830        if self.getJudgementObject().isSubmitted():
831            raise ServiceError("ERR-REV8a",_("You cannot modify a judgement marked as submitted"))
832        self.getJudgementObject().setJudgement(self._value)
833
834    def _handleGet(self):
835        judgement = self.getJudgementObject().getJudgement()
836        if judgement is None:
837            return 'None'
838        else:
839            return judgement
840
841class ContributionReviewingCommentsModification(ContributionReviewingHTMLModificationBase):
842
843    def _handleSet(self):
844        if self.getJudgementObject().isSubmitted():
845            raise ServiceError("ERR-REV8b",_("You cannot modify a judgement marked as submitted"))
846        self.getJudgementObject().setComments(self._value)
847
848    def _handleGet(self):
849        return self.getJudgementObject().getComments()
850
851class ContributionReviewingCriteriaModification(ContributionReviewingTextModificationBase):
852
853    def _checkParams(self):
854        ContributionReviewingTextModificationBase._checkParams(self)
855        self._criterion = self._params.get("criterion")
856
857    def _handleSet(self):
858        if self.getJudgementObject().isSubmitted():
859            raise ServiceError("ERR-REV8c",_("You cannot modify a judgement marked as submitted"))
860        self.getJudgementObject().setAnswer(self._criterion, int(self._value))
861
862    def _handleGet(self):
863        return self.getJudgementObject().getAnswer(self._criterion)
864
865
866class ContributionReviewingSetSubmitted(ContributionReviewingBase):
867
868    def _getAnswer( self ):
869
870        if self._params.has_key('value'):
871            judgementObject = self.getJudgementObject()
872            try:
873                judgementObject.setSubmitted(not self.getJudgementObject().isSubmitted())
874            except MaKaCError, e:
875                raise ServiceError("ERR-REV9", e.getMsg())
876
877            judgementObject.setAuthor(self._getUser())
878            judgementObject.sendNotificationEmail(widthdrawn = not self.getJudgementObject().isSubmitted())
879        return self.getJudgementObject().isSubmitted()
880
881class ContributionReviewingCriteriaDisplay(ContributionReviewingBase):
882
883    def _getAnswer( self ):
884        return [str(q) + " : " + ConferencePaperReview.reviewingQuestionsAnswers[int(a)]
885                for q,a in self.getJudgementObject().getAnswers()]
886
887#####################################
888###  Abstract reviewing classes
889#####################################
890class AbstractReviewingBase(ConferenceModifBase):
891
892    ''' Base Clase for Abstract Reviewing'''
893
894    def _checkParams(self):
895        ConferenceModifBase._checkParams(self)
896        self._confAbstractReview = self._conf.getConfAbstractReview()
897
898
899class AbstractReviewingChangeNumAnswers(AbstractReviewingBase):
900
901    ''' Change the number of answers per question '''
902
903    def _checkParams(self):
904        AbstractReviewingBase._checkParams(self)
905        self._value = int(self._params.get("value"))
906
907    def _getAnswer(self):
908        self._confAbstractReview.setNumberOfAnswers(self._value)
909        # update the labels
910        self._confAbstractReview.setRadioButtonsLabels()
911        self._confAbstractReview.setRadioButtonsTitles()
912        return self._value
913
914
915class AbstractReviewingChangeScale(AbstractReviewingBase):
916
917    ''' Change the limits for the ratings '''
918
919    def _checkParams(self):
920        AbstractReviewingBase._checkParams(self)
921        self._value = self._params.get("value")
922        self._min = int(self._value["min"])
923        self._max = int(self._value["max"])
924
925    def _getAnswer(self):
926        self._confAbstractReview.setScale(self._min, self._max)
927        # recalculate the current values for the judgements
928        self._conf.getAbstractMgr().recalculateAbstractsRating(self._min, self._max)
929        # update the labels and titles again
930        self._confAbstractReview.setRadioButtonsLabels()
931        self._confAbstractReview.setRadioButtonsTitles()
932        return self._value
933
934class AbstractReviewingUpdateExampleQuestion(AbstractReviewingBase):
935
936    ''' Get the required data for the example question '''
937
938    def _getAnswer(self):
939        # get the necessary values
940        numAnswers = range(self._confAbstractReview.getNumberOfAnswers())
941        labels = self._confAbstractReview.getRadioButtonsLabels()
942        rbValues = self._confAbstractReview.getRadioButtonsTitles()
943
944        return {"numberAnswers": numAnswers, "labels": labels, "rbValues": rbValues}
945
946
947#class AbstractReviewingBase(ConferenceModifBase, ProtectedModificationService):
948#
949#    def getJudgementObject(self):
950#        self._abstractId = self._params.get("Abstract","")
951#        abstractReview = self._target.getAbstractMgr().getAbstractById(self._abstractId).getAbstractReview()
952#        return abstractReview.getTrackCoordinatorJudgement(self._getUser())
953#
954#
955#class AbstractReviewingTextModificationBase (TextModificationBase, AbstractReviewingBase):
956#    #Note: don't change the order of the inheritance here!
957#    pass
958#
959#
960#class AbstractReviewingCriteriaModification(AbstractReviewingTextModificationBase):
961#
962#    def _checkParams(self):
963#        # question
964#        import pydevd; pydevd.settrace(stdoutToServer = True, stderrToServer = True)
965#        AbstractReviewingTextModificationBase._checkParams(self)
966#        self._question = self._params.get("question","")
967#
968#    def _handleSet(self):
969#        import pydevd; pydevd.settrace(stdoutToServer = True, stderrToServer = True)
970#        self.getJudgementObject().setAnswer(self._question, int(self._value))
971#
972#    def _handleGet(self):
973#        return self.getJudgementObject().getAnswer(self._question)
974
975methodMap = {
976    "conference.changeReviewingMode": ConferenceReviewingModeModification,
977    "conference.changeStates": ConferenceReviewingStatesModification,
978    "conference.changeQuestions": ConferenceReviewingQuestionsModification,
979    "conference.changeAbstractQuestions": ConferenceAbstractReviewingQuestionsModification,
980    "conference.changeCriteria": ConferenceReviewingCriteriaModification,
981    "conference.deleteTemplate" : ConferenceReviewingDeleteTemplate,
982    "conference.changeCompetences": ConferenceReviewingCompetenceModification,
983    "conference.changeDefaultDueDate" : ConferenceReviewingDefaultDueDateModification,
984    "conference.changeAbstractReviewerDefaultDueDate" : ConferenceAbstractReviewingDefaultDueDateModification,
985    "conference.attributeList" : ConferenceReviewingContributionsAttributeList,
986    "conference.contributionsIdPerSelectedAttribute" : ConferenceReviewingContributionsPerSelectedAttributeList,
987    "conference.userCompetencesList": ConferenceReviewingUserCompetenceList,
988
989    "conference.assignReferee" : ConferenceReviewingAssignReferee,
990    "conference.removeReferee" : ConferenceReviewingRemoveReferee,
991    "conference.assignEditor" : ConferenceReviewingAssignEditor,
992    "conference.removeEditor" : ConferenceReviewingRemoveEditor,
993    "conference.addReviewer" : ConferenceReviewingAddReviewer,
994    "conference.removeReviewer" : ConferenceReviewingRemoveReviewer,
995    "conference.removeAllReviewers" : ConferenceReviewingRemoveAllReviewers,
996
997    "conference.PRMEmailNotif" : ConferenceReviewingAutoEmailsModificationPRM,
998    "conference.RefereeEmailNotif" : ConferenceReviewingAutoEmailsModificationReferee,
999    "conference.EditorEmailNotif" : ConferenceReviewingAutoEmailsModificationEditor,
1000    "conference.ReviewerEmailNotif" : ConferenceReviewingAutoEmailsModificationReviewer,
1001    "conference.RefereeEmailNotifForContribution" : ConferenceReviewingAutoEmailsModificationRefereeForContribution,
1002    "conference.EditorEmailNotifForContribution" : ConferenceReviewingAutoEmailsModificationEditorForContribution,
1003    "conference.ReviewerEmailNotifForContribution" : ConferenceReviewingAutoEmailsModificationReviewerForContribution,
1004    "conference.RefereeEmailJudgementNotif" : ConferenceReviewingAutoEmailsModificationRefereeJudgement,
1005    "conference.EditorEmailJudgementNotif" : ConferenceReviewingAutoEmailsModificationEditorJudgement,
1006    "conference.ReviewerEmailJudgementNotif" : ConferenceReviewingAutoEmailsModificationReviewerJudgement,
1007    "conference.AuthorSubmittedMatRefereeNotif" : ConferenceReviewingAutoEmailsModificationAuthorSubmittedMatReferee,
1008    "conference.AuthorSubmittedMatEditorNotif" : ConferenceReviewingAutoEmailsModificationAuthorSubmittedMatEditor,
1009    "conference.AuthorSubmittedMatReviewerNotif" : ConferenceReviewingAutoEmailsModificationAuthorSubmittedMatReviewer,
1010
1011
1012    "conference.assignTeamPRM" : ConferenceReviewingAssignTeamPRM,
1013    "conference.removeTeamPRM" : ConferenceReviewingRemoveTeamPRM,
1014    "conference.assignTeamReferee" : ConferenceReviewingAssignTeamReferee,
1015    "conference.removeTeamReferee" : ConferenceReviewingRemoveTeamReferee,
1016    "conference.assignTeamEditor" : ConferenceReviewingAssignTeamEditor,
1017    "conference.removeTeamEditor" : ConferenceReviewingRemoveTeamEditor,
1018    "conference.assignTeamReviewer" : ConferenceReviewingAssignTeamReviewer,
1019    "conference.removeTeamReviewer" : ConferenceReviewingRemoveTeamReviewer,
1020
1021    "contribution.changeDueDate": ContributionReviewingDueDateModification,
1022    "contribution.changeComments": ContributionReviewingCommentsModification,
1023    "contribution.changeJudgement": ContributionReviewingJudgementModification,
1024    "contribution.changeCriteria": ContributionReviewingCriteriaModification,
1025    "contribution.getCriteria": ContributionReviewingCriteriaDisplay,
1026    "contribution.setSubmitted": ContributionReviewingSetSubmitted,
1027
1028    "abstractReviewing.changeNumberofAnswers": AbstractReviewingChangeNumAnswers,
1029    "abstractReviewing.changeScale": AbstractReviewingChangeScale,
1030    "abstractReviewing.updateExampleQuestion": AbstractReviewingUpdateExampleQuestion
1031
1032    }
1033#    "abstract.changeCriteria": AbstractReviewingCriteriaModification
Note: See TracBrowser for help on using the repository browser.