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 from persistent
import Persistent
18 from MaKaC
.common
.Counter
import Counter
19 from MaKaC
.paperReviewing
import Question
20 from MaKaC
.errors
import MaKaCError
23 class ConferenceAbstractReview(Persistent
):
25 This class manages the parameters of the abstract reviewing.
28 def __init__(self
, conference
):
30 conference must be a Conference object (not an id).
32 self
._conference
= conference
33 self
._reviewingQuestions
= []
36 self
._numberOfAnswers
= 7
38 self
._scaleHigher
= 10
39 self
._rbLabels
= ["0", "", "", "5", "", "", "10"]
40 self
._rbTitles
= ["0", "1.7", "3.3", "5", "6.7", "8.3", "10"]
41 self
._questionCounter
= Counter(1)
42 self
._answerCounter
= Counter(1)
43 self
._canReviewerAccept
= False # shows if the reviewers have rights to accept/reject abstracts
44 self
.notifyModification()
46 def getConference(self
):
47 """ Returns the parent conference of the ConferencePaperReview object
49 return self
._conference
51 def addReviewingQuestion(self
, text
):
52 """ Adds this question at the end of the list of questions
54 newId
= self
._getNewQuestionId
()
55 question
= Question(newId
, text
)
56 self
._reviewingQuestions
.append(question
)
57 self
.notifyModification()
59 def getReviewingQuestions(self
):
60 """ Returns the list of questions
62 return self
._reviewingQuestions
64 def removeReviewingQuestion(self
, questionId
, keepJud
):
65 """ Removes a question from the list
67 question
= self
.getQuestionById(questionId
)
70 self
._reviewingQuestions
.remove(question
)
71 self
.notifyModification()
73 raise MaKaCError("Cannot remove a question which doesn't exist")
75 def editReviewingQuestion(self
, questionId
, text
):
76 """ Edit the text of a question """
77 question
= self
.getQuestionById(questionId
)
80 question
.setText(text
)
81 self
.notifyModification()
83 raise MaKaCError("Cannot edit a question which doesn't exist")
85 def getQuestionNames(self
):
86 """ Return the names of the questions which are shown in the webpage """
88 for question
in self
._reviewingQuestions
:
89 names
.append(question
.getName())
92 def getQuestionById(self
, questionId
):
93 """ Return the question with the especified id """
94 for question
in self
._reviewingQuestions
:
95 if (questionId
== question
.getId()):
98 def setNumberOfAnswers(self
, num
):
99 """ Set the number of possible answers (radio buttons) """
100 self
._numberOfAnswers
= num
102 def getNumberOfAnswers(self
):
103 """ Returns the number of possible answers """
104 return self
._numberOfAnswers
106 def canReviewerAccept(self
):
107 if not hasattr(self
, "_canReviewerAccept"):
108 self
._canReviewerAccept
= False
109 return self
._canReviewerAccept
111 def setCanReviewerAccept(self
, canReviewerAccept
):
112 self
._canReviewerAccept
= canReviewerAccept
114 def recalculateRBLabelsAndTitles(self
):
115 """ Recalculate the labels for the radio buttons """
119 while i
< self
.getNumberOfAnswers():
123 self
._rbLabels
.append(str(self
.getScaleLower()))
125 elif i
== self
._numberOfAnswers
- 1:
126 self
._rbLabels
.append(str(self
.getScaleHigher()))
127 # if there is a middle value (odd number of values) and we are there
128 elif (self
.getNumberOfAnswers() % 2 == 1) and (i
== (self
.getNumberOfAnswers() - 1) / 2):
129 # check if we need float division
130 if ((self
.getScaleLower() + self
.getScaleHigher()) % 2 == 0):
131 label
= str((self
.getScaleLower() + self
.getScaleHigher()) / 2)
132 self
._rbLabels
.append(label
)
134 label
= str((self
.getScaleLower() + self
.getScaleHigher()) / float(2))
135 self
._rbLabels
.append(label
)
137 self
._rbLabels
.append("")
139 # check if we need float division
140 if ((i
* self
.getScaleHigher()) % (self
.getNumberOfAnswers() - 1) == 0):
141 title
= "%.0f" % (((self
.getScaleHigher() - self
.getScaleLower()) / float(self
.getNumberOfAnswers()-1)) * i
+ self
.getScaleLower())
142 self
._rbTitles
.append(title
)
144 title
= "%.1f" % (((self
.getScaleHigher() - self
.getScaleLower()) / float(self
.getNumberOfAnswers()-1)) * i
+ self
.getScaleLower())
145 self
._rbTitles
.append(title
)
147 self
.notifyModification()
149 def getRBTitles(self
):
150 """ Get the titles for the radio buttons """
151 return self
._rbTitles
153 def getRBLabels(self
):
154 """ Get the labels for the radio buttons """
155 return self
._rbLabels
157 def getScaleLower(self
):
158 return self
._scaleLower
160 def getScaleHigher(self
):
161 return self
._scaleHigher
163 def setScale(self
, min, max):
164 """ Set the scale for the rating and labels """
165 self
._scaleLower
= min
166 self
._scaleHigher
= max
168 def _getNewQuestionId(self
):
169 """ Returns a new an unused questionId
170 Increments the questionId counter
172 return self
._questionCounter
.newCount()
174 def getNewAnswerId(self
):
175 """ Returns a new an unused answerId
176 Increments the answerId counter
178 return self
._answerCounter
.newCount()
180 def notifyModification(self
):
181 """ Notifies the DB that a list or dictionary attribute of this object has changed