This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
glasnost/shared/web/VotesWeb.py

917 lines
35 KiB
Python

# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Votes Web Proxy"""
__version__ = '$Revision$'[11:-2]
import cgi
import copy
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.slots as slots
import glasnost.common.tools_new as commonTools
from glasnost.proxy.VotesProxy import *
from ObjectsWeb import register, AdminWithoutWritersMixin, ObjectWebMixin, \
ObjectsWebMixin
from tools import *
import widgets
class AdminVotes(AdminWithoutWritersMixin, AdminVotes):
pass
register(AdminVotes)
class MarksWidget(widgets.BaseWidget):
def getModelHiddenLayout(self, slot, fields):
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
objectIds = idsGetter(fields)
layout = X.array()
marks = slot.getValue()
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = ''
if marks and marks.has_key(objectId):
mark = str(marks[objectId])
layout += X.input(name = fieldName, type = 'hidden',
value = mark),
return layout
def submit(self, slot, fields):
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
objectIds = idsGetter(fields) or []
isBlank = isButtonSelected(
slot.getFieldOptionName('blankButton'), fields)
result = {}
if isBlank:
# why not returning an empty dictionary ?
for objectId in objectIds:
result[objectId] = 0
return result
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = self.submitOneMark(slot, objectId, fields)
result[objectId] = mark
return result
def submitOneMark(self, slot, objectId, fields):
mark = slot.getFieldOption(fields, objectId)
try:
return int(mark)
except ValueError:
return None
class VoteApprovalMarksWidget(MarksWidget):
def submitOneMark(self, slot, objectId, fields):
mark = slot.getFieldOption(fields, objectId)
if not mark:
mark = '0'
return int(mark)
def getHtmlFieldValue(self, slot, fields, **keywords):
marks = slot.getValue()
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
objectIds = idsGetter(fields)
if not self.isInForm():
if container.isAbstention():
return X.strong(_('Abstention'))
elif container.isBlank(objectIds):
return X.strong(_('Blank Vote'))
tdAttributes = {}
if self.colSpan:
tdAttributes['colspan'] = self.colSpan
layout = X.array()
if self.isReadOnly(slot):
layout += self.getModelHiddenLayout(slot, fields)
table = X.table(_class = 'vote')
layout += table
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = 0
if marks and marks.has_key(objectId) and marks[objectId]:
mark = marks[objectId]
if mark:
markSymbol = 'x'
else:
markSymbol = X.nbsp
tr = X.tr()
table += tr
if not self.isInForm() or self.isReadOnly(slot):
tr += X.td( '[', markSymbol, ']',)
else:
td = X.td()
tr += td
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
inputAttributes = {}
if mark:
inputAttributes['checked'] = 'checked'
td += X.input(name = fieldName, type = 'checkbox',
value = 1, **inputAttributes)
tr += X.td()(X.objectHypertextLabel(objectId))
return X.div(_class = 'cell')(layout)
widgets.register(VoteApprovalMarksWidget)
class VoteDistributionMarksWidget(MarksWidget):
def getHtmlFieldValue(self, slot, fields, **keywords):
marks = slot.getValue()
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
objectIds = idsGetter(fields)
if not self.isInForm():
if container.isAbstention():
return X.strong(_('Abstention'))
elif container.isBlank(objectIds):
return X.strong(_('Blank Vote'))
tdAttributes = {}
if self.colSpan:
tdAttributes['colspan'] = self.colSpan
layout = X.array()
if self.isReadOnly(slot):
layout += self.getModelHiddenLayout(slot, fields)
table = X.table(_class = 'vote')
layout += table
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = ''
if marks and marks.has_key(objectId) and marks[objectId]:
mark = '%.2f' % (marks[objectId]*100)
tr = X.tr()
table += tr
tr += X.td(X.objectHypertextLabel(objectId), X.asIs(_(':')))
if not self.isInForm() or self.isReadOnly(slot):
tr += X.td()( mark, X.nbsp, '%',)
else:
td = X.td()
tr += td
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
td += X.input(maxlength = 6, name = fieldName, size = 6,
type = 'text', value = mark)
td += X.nbsp
td += '%'
return X.div(_class = 'cell')(layout)
def submitOneMark(self, slot, objectId, fields):
mark = slot.getFieldOption(fields, objectId) or ''
if mark and mark.strip():
try:
mark = float(mark) / 100.
except ValueError:
raise faults.BadValue()
mark = 0
else:
mark = 0
return mark
widgets.register(VoteDistributionMarksWidget)
class VoteRankingMarksWidget(MarksWidget):
def getHtmlFieldValue(self, slot, fields, **keywords):
marks = slot.getValue()
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
objectIds = idsGetter(fields)
if not self.isInForm():
if container.isAbstention():
return X.strong(_('Abstention'))
elif container.isBlank(objectIds):
return X.strong(_('Blank Vote'))
layout = X.array()
if self.isReadOnly(slot):
layout += self.getModelHiddenLayout(slot, fields)
table = X.table(_class = 'vote')
layout += table
tdAttributes = {}
if self.colSpan:
tdAttributes['colspan'] = self.colSpan
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = ''
if marks and marks.has_key(objectId) and marks[objectId]:
mark = marks[objectId]
mark = str(mark)
tr = X.tr()
table += tr
if not self.isInForm() or self.isReadOnly(slot):
tr += X.td( '[', X.nbsp, mark, X.nbsp, ']',)
else:
td = X.td()
tr += td
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
maxLength = len(str(len(objectIds)))
td += X.input(
maxlength = maxLength, name = fieldName,
size = maxLength, type = 'text', value = mark)
tr += X.td(_class = 'field-label')(
X.objectHypertextLabel(objectId))
return X.div(_class = 'cell')(layout)
widgets.register(VoteRankingMarksWidget)
class VoteRatingMarksWidget(MarksWidget):
def getHtmlFieldValue(self, slot, fields, **keywords):
marks = slot.getValue()
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
objectIds = idsGetter(fields)
if not self.isInForm():
if container.isAbstention():
return X.strong(_('Abstention'))
elif container.isBlank(objectIds):
return X.strong(_('Blank Vote'))
tdAttributes = {}
if self.colSpan:
tdAttributes['colspan'] = self.colSpan
layout = X.array()
if self.isReadOnly(slot):
layout += self.getModelHiddenLayout(slot, fields)
table = X.table(_class = 'vote')
layout += table
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = ''
if marks and marks.has_key(objectId) and marks[objectId]:
mark = marks[objectId]
tr = X.tr()
table += tr
tr += X.td()(X.objectHypertextLabel(objectId), X.asIs(_(':')))
if not self.isInForm() or self.isReadOnly(slot):
tr += X.td()(mark)
else:
td = X.td()
tr += td
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
td += X.input(maxlength = 6, name = fieldName, size = 6,
type = 'text', value = mark)
return X.div(_class = 'cell')(layout)
widgets.register(VoteRatingMarksWidget)
class VoteMixin(ObjectWebMixin):
ballotKind_kind_widget_fieldLabel = N_('Kind of Ballot')
ballotKind_kind_widget_labels = {
'public': N_('Public Ballot'),
'secret': N_('Secret Ballot'),
}
ballotKind_kind_widgetName = 'Select'
comment_kind_widget_fieldLabel = N_('Comment')
comment_kind_widget_cols = 75
comment_kind_widget_colSpan = 2
comment_kind_widget_rows = 4
comment_kind_widgetName = 'TextArea'
#electionId_kind_hasToInitField = 0
#electionId_kind_hasToMakeFieldFromValue = 0
electionId_kind_hasToRepairField = 0
electionId_kind_hasToSubmitField = 0
electionId_kind_stateInEditMode = 'hidden'
electionId_kind_stateInViewMode = 'hidden'
electionId_kindName = 'Id'
electionId_kind_serverRoles = ['elections']
electionId_kind_widget_fieldLabel = N_('Election')
electionId_kind_widgetName = 'SelectId'
electionToken_kind_stateInEditMode = 'hidden'
electionToken_kind_stateInViewMode = 'hidden'
electionToken_kind_widget_fieldLabel = N_('Election Token')
electionToken_kind_widgetName = 'Token'
subject = None
subject_kind_isTranslatable = 0
subject_kind_stateInEditMode = 'read-only'
subject_kindName = 'String'
token_kind_stateInEditMode = 'read-only'
token_kind_widget_fieldLabel = N_('Vote Token')
token_kind_widgetName = 'Token'
#voterId_kind_hasToInitField = 0
#voterId_kind_hasToMakeFieldFromValue = 0
voterId_kind_hasToRepairField = 0
voterId_kind_hasToSubmitField = 0
voterId_kind_stateInEditMode = 'read-only'
voterId_kindName = 'Id'
voterId_kind_serverRoles = ['identities']
voterId_kind_widget_fieldLabel = N_('Voter')
voterId_kind_widgetName = 'SelectId'
voterToken_kind_stateInEditMode = 'read-only'
voterToken_kind_widget_fieldLabel = N_('Voter Token')
voterToken_kind_widgetName = 'Token'
def getElectionCandidateIds(self, fields):
return getObject(self.electionId).candidateIds
def getEditLayout(self, fields, parentSlot = None):
election = getObject(self.electionId)
slot = election.getSlot('subject')
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
subject, destinationLanguage, state = \
translationsProxy.getTranslationInfos(
election.subject, election.getId(), slot.getPath(),
election.getLanguage(), context.getVar('readLanguages'))
else:
subject = election.subject
self.subject = subject
self.subject_kind = copy.copy(election.subject_kind)
self.subject_kind.stateInEditMode = 'read-only'
self.subject_kind.isTranslatable = 0
self.subject_kind.widget = widgets.TextArea(
fieldLabel = N_('Subject'),
cols = 75,
colSpan = 2,
rows = 4)
layout = ObjectWebMixin.getEditLayout(
self, fields, parentSlot = parentSlot)
del self.subject
del self.subject_kind
return layout
def getEditLayoutHiddenSlotNames(self, fields, parentSlot = None):
hiddenSlotNames = ObjectWebMixin.getEditLayoutHiddenSlotNames(
self, fields, parentSlot = parentSlot)
hiddenSlotNames = hiddenSlotNames[:]
slot = self.getSlot('voterId')
if slot.getValue():
hiddenSlotNames.append('voterToken')
else:
hiddenSlotNames.append('voterId')
election = getObject(self.electionId)
if election.ballotKind != 'voterChoice':
hiddenSlotNames.append('ballotKind')
return hiddenSlotNames
def getViewLayout(self, fields, parentSlot = None):
election = getObject(self.electionId)
slot = election.getSlot('subject')
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
subject, destinationLanguage, state = \
translationsProxy.getTranslationInfos(
election.subject, election.getId(), slot.getPath(),
election.getLanguage(), context.getVar('readLanguages'))
else:
subject = election.subject
self.subject = subject
self.subject_kind = copy.copy(election.subject_kind)
self.subject_kind.isTranslatable = 0
self.subject_kind.widget = widgets.TextArea(
fieldLabel = N_('Subject'),
cols = 75,
colSpan = 2,
rows = 4)
layout = ObjectWebMixin.getViewLayout(
self, fields, parentSlot = parentSlot)
del self.subject
del self.subject_kind
return layout
def getViewLayoutHiddenSlotNames(self, fields, parentSlot = None):
hiddenSlotNames = ObjectWebMixin.getViewLayoutHiddenSlotNames(
self, fields, parentSlot = parentSlot)
hiddenSlotNames = hiddenSlotNames[:]
slot = self.getSlot('voterId')
if slot.getValue():
hiddenSlotNames.append('voterToken')
else:
hiddenSlotNames.append('voterId')
election = getObject(self.electionId)
if election.ballotKind != 'voterChoice':
hiddenSlotNames.append('ballotKind')
return hiddenSlotNames
class AbstractVote(VoteMixin, AbstractVote):
pass
register(AbstractVote)
class VoteApproval(VoteMixin, VoteApproval):
marks_kind_idsGetterName = 'getElectionCandidateIds'
marks_kindName = 'ApprovalMarks'
marks_kind_widget_fieldLabel = N_('Choice')
marks_kind_widgetName = 'VoteApprovalMarksWidget'
def getLabelLine(self, election):
if self.isAbstention():
line = '<i>%s</i>' % _('Abstention')
elif self.isBlank(election.candidateIds):
line = '<i>%s</i>' % _('Blank Vote')
else:
marks = self.getMarks(election.candidateIds)
candidates = [
getObjectLabelTranslated(
candidateId,
context.getVar('readLanguages'))
for candidateId in marks.keys()
if marks[candidateId]]
return ', '.join([cgi.escape(x) for x in candidates])
def getMarksRowLayout(self, candidateIds):
marks = self.getMarks(candidateIds)
layout = X.array()
for candidateId in candidateIds:
mark = marks[candidateId]
tdAttributes = {}
if mark:
red = 0
green = 255
cell = 'x'
else:
red = 255
green = 0
cell = X.nbsp
tdAttributes['style'] = 'background-color: #%(red)02x%(green)02x00' % {
'green': green,
'red': red,
}
layout += X.td(**tdAttributes)(cell)
return layout
register(VoteApproval)
class VoteDistribution(VoteMixin, VoteDistribution):
marks_kind_idsGetterName = 'getElectionCandidateIds'
marks_kindName = 'DistributionMarks'
marks_kind_widget_fieldLabel = N_('Choice')
marks_kind_widgetName = 'VoteDistributionMarksWidget'
def getLabelLine(self, election):
if self.isAbstention():
line = '<i>%s</i>' % _('Abstention')
elif self.isBlank(election.candidateIds):
line = '<i>%s</i>' % _('Blank Vote')
else:
line = ''
marks = self.getMarks(election.candidateIds)
candidateIds = marks.keys()[:]
def candidatesSorter(id1, id2, marks = marks):
return cmp(marks[id2], marks[id1])
candidateIds.sort(candidatesSorter)
for candidateId in candidateIds:
if line:
line = line + ', '
line = line + '%(candidate)s (%(mark)s)' % {
'candidate': cgi.escape(getObjectLabelTranslated(
candidateId, context.getVar('readLanguages'))),
'mark': marks[candidateId],
}
return line
def getMarksRowLayout(self, candidateIds):
marks = self.getMarks(candidateIds)
minMark = min(marks.values())
maxMark = max(marks.values())
if minMark < maxMark:
averageMark = (maxMark + minMark) / 2.0
coef = 255 / float(averageMark - minMark)
layout = X.array()
for candidateId in candidateIds:
mark = marks[candidateId]
tdAttributes = {}
if minMark < maxMark:
if mark <= averageMark:
red = 255
green = coef * (mark - minMark)
else:
red = coef * (maxMark - mark)
green = 255
tdAttributes['style'] = 'background-color: #%(red)02x%(green)02x00' % {
'green': green,
'red': red,
}
layout += X.td(**tdAttributes)(
'%.2f' % (mark * 100),
X.nbsp,
'%',
)
return layout
register(VoteDistribution)
class VoteRanking(VoteMixin, VoteRanking):
marks_kind_idsGetterName = 'getElectionCandidateIds'
marks_kindName = 'RankingMarks'
marks_kind_widget_fieldLabel = N_('Choice')
marks_kind_widgetName = 'VoteRankingMarksWidget'
def getLabelLine(self, election):
if self.isAbstention():
line = '<i>%s</i>' % _('Abstention')
elif self.isBlank(election.candidateIds):
line = '<i>%s</i>' % _('Blank Vote')
else:
line = ''
marks = self.getMarks(election.candidateIds)
candidateIds = marks.keys()[:]
def candidatesSorter(id1, id2, marks = marks):
return cmp(marks[id1], marks[id2])
candidateIds.sort(candidatesSorter)
for candidateId in candidateIds:
if line:
line = line + ', '
line = line + '(%(mark)s) %(candidate)s' % {
'candidate': cgi.escape(getObjectLabelTranslated(
candidateId, context.getVar('readLanguages'))),
'mark': marks[candidateId],
}
return line
def getMarksRowLayout(self, candidateIds):
marks = self.getMarks(candidateIds)
scores = self.getScores(candidateIds)
minScore = 0
maxScore = 1
if minScore < maxScore:
averageScore = (maxScore + minScore) / 2.0
coef = 255 / float(averageScore - minScore)
layout = X.array()
for candidateId in candidateIds:
mark = marks[candidateId]
tdAttributes = {}
if minScore < maxScore:
score = scores[candidateId]
if score <= averageScore:
red = 255
green = coef * (score - minScore)
else:
red = coef * (maxScore - score)
green = 255
tdAttributes['style'] = 'background-color: #%(red)02x%(green)02x00' % {
'green': green,
'red': red,
}
layout += X.td(**tdAttributes)(mark)
return layout
register(VoteRanking)
class VoteRating(VoteMixin, VoteRating):
marks_kind_idsGetterName = 'getElectionCandidateIds'
marks_kindName = 'RatingMarks'
marks_kind_widget_fieldLabel = N_('Choice')
marks_kind_widgetName = 'VoteRatingMarksWidget'
def getLabelLine(self, election):
if self.isAbstention():
line = '<i>%s</i>' % _('Abstention')
elif self.isBlank(election.candidateIds):
line = '<i>%s</i>' % _('Blank Vote')
else:
line = ''
marks = self.getMarks(election.candidateIds)
candidateIds = marks.keys()[:]
def candidatesSorter(id1, id2, marks = marks):
return cmp(marks[id2], marks[id1])
candidateIds.sort(candidatesSorter)
for candidateId in candidateIds:
if line:
line = line + ', '
line = line + '%(candidate)s (%(mark)s)' % {
'candidate': cgi.escape(getObjectLabelTranslated(
candidateId, context.getVar('readLanguages'))),
'mark': marks[candidateId],
}
return line
def getMarksRowLayout(self, candidateIds):
marks = self.getMarks(candidateIds)
minMark = 0
maxMark = 1
if minMark < maxMark:
averageMark = (maxMark + minMark) / 2.0
coef = 255 / float(averageMark - minMark)
layout = X.array()
for candidateId in candidateIds:
mark = marks[candidateId]
tdAttributes = {}
if minMark < maxMark:
if mark <= averageMark:
red = 255
green = coef * (mark - minMark)
else:
red = coef * (maxMark - mark)
green = 255
tdAttributes['style'] = 'background-color: #%(red)02x%(green)02x00' % {
'green': green,
'red': red,
}
layout += X.td(**tdAttributes)(
'%.2f' % (mark * 100))
return layout
register(VoteRating)
class VotesWeb(ObjectsWebMixin, VotesProxy):
def canAddObject(self, serverId = None):
return 0
def edit(self, id = '', electionId = ''):
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
identitiesWeb = getWebForServerRole('identities')
userId = context.getVar('userId', default = '')
userToken = context.getVar('userToken', default = '')
if not userToken:
return accessForbidden()
if id:
vote = ballotsWeb.getVote(id)
if vote == 'secret':
return accessForbidden()
rememberObject(id)
electionId = ballotsWeb.getElectionIdFromToken(
vote.electionToken, serverId = commonTools.extractServerId(id))
if not electionId \
or not electionsWeb.hasObject(electionId):
return pageNotFound()
if not electionsWeb.canVote(electionId):
return accessForbidden()
election = electionsWeb.getObject(electionId)
rememberObject(electionId)
else:
if not electionId \
or not electionsWeb.hasObject(electionId):
return pageNotFound()
if not electionsWeb.canVote(electionId):
return accessForbidden()
election = electionsWeb.getObject(electionId)
rememberObject(electionId)
voter = identitiesWeb.getObject(userId)
if voter.voteTokens is not None \
and voter.voteTokens.has_key(electionId):
voteToken = voter.voteTokens[electionId]
if voteToken == 'secret':
return accessForbidden()
try:
vote = ballotsWeb.getVoteFromToken(voteToken)
except faults.UnknownVoteToken:
vote = election.newVote()
vote.fillWithDefaultValues()
else:
id = vote.id
rememberObject(id)
else:
vote = election.newVote()
return self.editObject(vote, electionId)
edit.isPublicForWeb = 1
def editObject(self, vote, electionId = ''):
electionsWeb = getWebForServerRole('elections')
election = electionsWeb.getObject(electionId)
userId = context.getVar('userId', default = '')
vote.getSlot('electionId').setValue(electionId)
vote.getSlot('voterId').setValue(userId)
vote.getSlot('subject').setValue(election.subject)
if not vote.id:
headerTitle = _('New %s') % _(self.objectNameCapitalized)
else:
headerTitle = _('Editing %s - %s') % (
_(self.objectNameCapitalized), vote.getLabel())
context.push(_level = 'edit', layoutMode = 'edit')
try:
layout = X.array()
if context.getVar('error'):
layout += vote.getErrorLayout()
form = X.form(action = X.actionUrl('submit'),
enctype= 'multipart/form-data', method = 'post')
layout += form
slot = slots.Root(vote)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, None)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
actionButtonsBar = X.span(_class = 'action-buttons-bar')
buttonsBar += actionButtonsBar
actionButtonsBar += X.buttonInForm('abstain', 'abstainButton')
actionButtonsBar += X.buttonInForm(
'vote-blank',
vote.getSlot('marks').getFieldOptionName('blankButton'))
actionButtonsBar += X.buttonInForm('vote', 'voteButton')
return writePageLayout(layout, headerTitle)
finally:
context.pull(_level = 'edit')
def submit(self, id = '', electionId = '', **keywords):
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
if keywords is None:
keywords = {}
userId = context.getVar('userId', default = '')
userToken = context.getVar('userToken', default = '')
if not userToken:
return accessForbidden()
if not electionId \
or not electionsWeb.hasObject(electionId):
return pageNotFound()
if not electionsWeb.canVote(electionId):
return accessForbidden()
if isButtonSelected('applyButton', keywords):
context.setVar('again', 1)
context.setVar('hideErrors', 1)
elif isButtonSelected('abstainButton', keywords):
try:
ballotsWeb.abstainForVote(electionId)
except faults.Fault:
if context.getVar('debug'):
raise
return accessForbidden()
return redirect(X.actionUrl('view').add(
'electionId', electionId).add('voterId', userId))
election = electionsWeb.getObject(electionId)
vote = election.newVote()
vote.getSlot('electionId').setValue(electionId)
vote.submitFields(keywords)
if context.getVar('again'):
return self.editObject(vote, electionId)
try:
id = ballotsWeb.vote(electionId, vote)
except faults.WrongVersion:
context.setVar('error', 1)
vote.setError('version', 1)
return self.editObject(vote, electionId)
return redirect(X.idUrl(id))
submit.isPublicForWeb = 1
def view(self, id = '', electionId = '', voterId = ''):
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
identitiesWeb = getWebForServerRole('identities')
userId = context.getVar('userId', default = '')
if id:
vote = ballotsWeb.getVote(id)
if vote == 'secret':
return accessForbidden()
rememberObject(id)
electionId = ballotsWeb.getElectionIdFromToken(
vote.electionToken, serverId = commonTools.extractServerId(id))
if ballotsWeb.canGetVoteVoterId(id):
voterId = ballotsWeb.getVoteVoterId(id)
else:
voterId = ''
if not electionId \
or not electionsWeb.hasObject(electionId):
return pageNotFound()
if not electionsWeb.canGetObject(electionId):
return accessForbidden()
election = electionsWeb.getObject(electionId)
rememberObject(electionId)
else:
if not electionId \
or not electionsWeb.hasObject(electionId):
return pageNotFound()
if not voterId \
or not identitiesWeb.hasObject(voterId):
return pageNotFound()
if not electionsWeb.canGetObject(electionId):
return accessForbidden()
if not identitiesWeb.canGetObject(voterId):
return accessForbidden()
election = electionsWeb.getObject(electionId)
rememberObject(electionId)
voter = identitiesWeb.getObject(voterId)
if voter.voteTokens is not None \
and voter.voteTokens.has_key(electionId):
voteToken = voter.voteTokens[electionId]
if voteToken == 'secret':
return accessForbidden()
try:
vote = ballotsWeb.getVoteFromToken(voteToken)
except faults.UnknownVoteToken:
vote = election.newVote()
else:
id = vote.id
rememberObject(id)
else:
vote = election.newVote()
vote.getSlot('electionId').setValue(electionId)
vote.getSlot('voterId').setValue(userId)
vote.getSlot('subject').setValue(election.subject)
keywords = {}
label = election.getLabelTranslated(
context.getVar('readLanguages'))
layout = X.array()
slot = slots.Root(vote)
widget = slot.getWidget()
layout += widget.getModelPageBodyLayout(slot, None)
layout += X.br()
if voterId and voterId == userId and electionsWeb.canVote(electionId):
layout += X.buttonStandalone(
'edit',X.idUrl(id, 'edit').add('electionId', electionId))
layout += X.buttonStandalone(
_('Go to Election'), X.idUrl(electionId))
return writePageLayout(
layout, '%s - %s' % (_(self.objectNameCapitalized), label))
view.isPublicForWeb = 1
def viewAll(self):
context.push(_level = 'viewAll',
defaultDispatcherId = context.getVar('dispatcherId'))
try:
if not self.canGetObjects():
return accessForbidden()
layout = X.array()
if self.canGetAdmin():
layout += X.div(_class = 'buttons-bar')(
X.buttonStandalone('settings', X.actionUrl('admin')))
finally:
context.pull(_level = 'viewAll')
return writePageLayout(layout, _('Votes'))
viewAll.isPublicForWeb = 1