Author: nigelj
Date: 2008-05-31 06:16:24 +0000 (Sat, 31 May 2008)
New Revision: 41
Added:
branches/0.1.0-STABLE/elections/templates/index.html
branches/0.1.0-STABLE/elections/templates/vote.html
Removed:
branches/0.1.0-STABLE/elections/templates/ballot.html
branches/0.1.0-STABLE/elections/templates/confirm.html
branches/0.1.0-STABLE/elections/templates/list.html
Modified:
branches/0.1.0-STABLE/elections.sql
branches/0.1.0-STABLE/elections/controllers.py
branches/0.1.0-STABLE/elections/model.py
branches/0.1.0-STABLE/elections/templates/about.html
branches/0.1.0-STABLE/elections/templates/login.html
Log:
Merge bugfixes (r39 & r40) from trunk
Modified: branches/0.1.0-STABLE/elections/controllers.py
===================================================================
--- branches/0.1.0-STABLE/elections/controllers.py 2008-05-31 06:01:16 UTC (rev 40)
+++ branches/0.1.0-STABLE/elections/controllers.py 2008-05-31 06:16:24 UTC (rev 41)
@@ -41,10 +41,10 @@
appTitle = 'Fedora Elections'
admin = Admin(appTitle)
- @expose(template="elections.templates.list")
+ @expose(template="elections.templates.index")
def index(self):
electlist =
Elections.query.order_by(ElectionsTable.c.start_date).filter('id>0').all()
- return dict(elections=electlist, curtime=datetime.utcnow())
+ return dict(elections=electlist, curtime=datetime.utcnow(),
appTitle=self.appTitle)
@expose(template="elections.templates.about")
def about(self,eid=None):
@@ -54,23 +54,36 @@
except ValueError:
election = Elections.query.filter_by(shortname=eid).all()[0]
eid = election.id
+ except TypeError:
+ turbogears.flash("This election does not exist, check if you have used
the correct URL.")
+ raise turbogears.redirect("/")
+ except IndexError:
+ turbogears.flash("This election does not exist, check if you have used
the correct URL.")
+ raise turbogears.redirect("/")
votergroups = LegalVoters.query.filter_by(election_id=eid).all()
candidates =
Candidates.query.filter_by(election_id=eid).order_by(Candidates.name).all()
+ votergroups = LegalVoters.query.filter_by(election_id=eid).all()
curtime = datetime.utcnow()
- return dict(eid=eid, candidates=candidates, election=election, curtime=curtime)
+ return dict(eid=eid, candidates=candidates, election=election, curtime=curtime,
votergroups=votergroups, appTitle=self.appTitle)
@identity.require(identity.not_anonymous())
- @expose(template="elections.templates.ballot")
- def ballot(self,eid=None):
+ @expose(template="elections.templates.vote")
+ def vote(self,eid=None, **kw):
try:
eid = int(eid)
election = Elections.query.filter_by(id=eid).all()[0]
except ValueError:
election = Elections.query.filter_by(shortname=eid).all()[0]
eid = election.id
+ except TypeError:
+ turbogears.flash("This election does not exist, check if you have used
the correct URL.")
+ raise turbogears.redirect("/")
+ except IndexError:
+ turbogears.flash("This election does not exist, check if you have used
the correct URL.")
+ raise turbogears.redirect("/")
votergroups = LegalVoters.query.filter_by(election_id=eid).all()
@@ -81,54 +94,25 @@
if match == 0:
turbogears.flash("You are not in a FAS group that can vote in this
election, more information can be found here.")
raise turbogears.redirect("/about/" + str(eid))
-
- curtime = datetime.utcnow()
- if election.end_date < curtime:
- turbogears.flash("You cannot vote in this election because the end date
has passed. You have been redirected to the election results")
- raise turbogears.redirect("/results/" + str(eid))
- elif election.start_date > curtime:
- election_started=False
- else:
- election_started=True
- candidates =
Candidates.query.filter_by(election_id=eid).order_by(Candidates.name).all()
- return dict(eid=eid, candidates=candidates, election=election,
election_started=election_started)
-
- @identity.require(identity.not_anonymous())
- @expose(template="elections.templates.confirm")
- def vote(self, eid, **kw):
- try:
- election = Elections.query.filter_by(id=eid).all()[0]
- except IndexError:
- turbogears.flash("Sorry, that election does not exist")
- raise turbogears.redirect("/")
-
- votergroups = LegalVoters.query.filter_by(election_id=eid).all()
- match = 0
- for group in votergroups:
- if identity.in_group(group.group_name):
- match = 1
- if match == 0:
- turbogears.flash("You are not in a FAS group that can vote in this
election, more information can be found here.")
- raise turbogears.redirect("/about/" + str(election.name))
-
candidates =
Candidates.query.filter_by(election_id=eid).order_by(Candidates.name).all()
uservote = UserVoteCount.query.filter_by(election_id=eid,
voter=turbogears.identity.current.user_name).all()
+ uvotes = {}
+ next_action = ""
- #Before we do *ANYTHING* check if voting hasn't begun/has ended
curtime = datetime.utcnow()
if election.start_date > curtime:
- turbogears.flash("Voting has not yet begun.")
+ turbogears.flash("Voting as not yet started, sorry.")
raise turbogears.redirect("/")
elif election.end_date < curtime:
- turbogears.flash("We are sorry, voting has now ended.")
- raise turbogears.redirect("/")
+ turbogears.flash("You cannot vote in this election because the end date
has passed. You have been redirected to the election results")
+ raise turbogears.redirect("/results/" + election.shortname)
elif len(uservote) != 0:
- turbogears.flash("You've voted too many times!")
+ turbogears.flash("You have already voted in this election!")
raise turbogears.redirect("/")
-
+
+ # Lets do this in reverse order
if "confirm" in kw:
- uvotes = {}
for c in candidates:
if str(c.id) in kw:
try:
@@ -143,32 +127,40 @@
raise turbogears.redirect("/")
for uvote in uvotes:
Votes(voter=turbogears.identity.current.user_name, candidate_id=uvote,
weight=uvotes[uvote], election_id=eid)
- turbogears.flash("Saved!")
- raise turbogears.redirect("/")
- else:
+ turbogears.flash("You vote has been recorded, thank you!")
+ raise turbogears.redirect("/")
+ elif "vote" in kw:
turbogears.flash("Please confirm your vote!")
- uvotes = {}
for c in candidates:
if str(c.id) in kw:
try:
range = int(kw[str(c.id)])
if range > len(candidates):
- turbogears.flash("One or more votes had incorrect data,
please verify your ballot carefully!")
- uvotes[c.id] = len(candidates)
+ turbogears.flash("Invalid data was detected for one or
more candidates and was changed to zeros! Please correct and resubmit your
ballot.")
+ uvotes[c.id] = 0
+ next_action = "vote"
elif range >= 0:
uvotes[c.id] = range
else:
- turbogears.flash("One or more votes had incorrect data,
please verify your ballot carefully!")
+ turbogears.flash("Invalid data was detected for one or
more candidates and was changed to zeros! Please correct and resubmit your
ballot.")
uvotes[c.id] = 0
+ next_action = "vote"
except ValueError:
- turbogears.flash("Invalid data was detected and changed to
zeros!")
+ turbogears.flash("Invalid data was detected for one or more
candidates and was changed to zeros! Please correct and resubmit your ballot.")
uvotes[c.id] = 0
+ next_action = "vote"
else:
turbogears.flash("Invalid Ballot!")
raise turbogears.redirect("/")
-
- return dict(voteinfo=uvotes, candidates=candidates, election=election)
+ if next_action != "vote":
+ next_action = "confirm"
+ else:
+ for c in candidates:
+ uvotes[c.id] = ""
+ next_action = "vote"
+ return dict(eid=eid, candidates=candidates, election=election,
nextaction=next_action, voteinfo=uvotes, appTitle=self.appTitle)
+
@expose(template="elections.templates.results")
def results(self,eid=None):
try:
@@ -177,6 +169,13 @@
except ValueError:
election = Elections.query.filter_by(shortname=eid).all()[0]
eid = election.id
+ except TypeError:
+ turbogears.flash("This election does not exist, check if you have used
the correct URL.")
+ raise turbogears.redirect("/")
+ except IndexError:
+ turbogears.flash("This election does not exist, check if you have used
the correct URL.")
+ raise turbogears.redirect("/")
+
curtime = datetime.utcnow()
if election.public_results == 0 and election.end_date > curtime:
turbogears.flash("We are sorry, the results for this election cannot be
viewed at this time because the election is still in progress.")
@@ -185,7 +184,7 @@
turbogears.flash("We are sorry, the results for this election cannot be
viewed at this time because the election has not started.")
raise turbogears.redirect("/")
votecount =
VoteTally.query.filter_by(election_id=eid).order_by(VoteTally.novotes.desc()).all()
- return dict(votecount=votecount, election=election)
+ return dict(votecount=votecount, election=election, appTitle=self.appTitle)
@expose(template="elections.templates.login", allow_json=True)
def login(self, forward_url=None, previous_url=None, *args, **kw):
@@ -216,7 +215,7 @@
response.status=403
return dict(message=msg, previous_url=previous_url, logging_in=True,
original_parameters=request.params,
- forward_url=forward_url, title='Fedora Account System
Login')
+ forward_url=forward_url, title=self.appTitle + ' -- Fedora
Account System Login')
@expose()
def logout(self):
Modified: branches/0.1.0-STABLE/elections/model.py
===================================================================
--- branches/0.1.0-STABLE/elections/model.py 2008-05-31 06:01:16 UTC (rev 40)
+++ branches/0.1.0-STABLE/elections/model.py 2008-05-31 06:16:24 UTC (rev 41)
@@ -27,7 +27,11 @@
ElectionsTable = Table('elections', metadata, autoload=True)
VotesTable = Table('votes', metadata, autoload=True)
CandidatesTable = Table('candidates', metadata, autoload=True)
-LegalVotersTable = Table('legalvoters', metadata, autoload=True)
+LegalVotersTable = Table('legalvoters', metadata,
+ Column('election_id', Integer,
+ ForeignKey('elections.id'), primary_key=True),
+ Column('group_name', String, nullable=False)
+)
# View in the DB. Needs to have the column keys defined
VoteTallyTable = Table('votecount', metadata,
Modified: branches/0.1.0-STABLE/elections/templates/about.html
===================================================================
--- branches/0.1.0-STABLE/elections/templates/about.html 2008-05-31 06:01:16 UTC (rev 40)
+++ branches/0.1.0-STABLE/elections/templates/about.html 2008-05-31 06:16:24 UTC (rev 41)
@@ -4,10 +4,9 @@
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" />
<head>
- <title>Welcome to TurboGears</title>
+ <title>${appTitle} -- Election Information</title>
</head>
- <body>
-<!-- Also need to list eligable voting groups... -->
+ <body>
<h1>${election.name}</h1>
<p>${election.info}</p>
<p py:if="election.url"><a
href="${election.url}">[More Information]</a></p>
@@ -15,10 +14,14 @@
<tr py:for="candidate in candidates">
<td>${candidate.name} <small py:if="candidate.url"><a
href="${candidate.url}">[info]</a></small></td>
</tr>
-<!-- This link is okay, but one should appear if the election has public results
-->
+<!-- !This link is okay, but one should appear if the election has public results
-->
<tr>
- <td><a href="${tg.url('/ballot/' +
election.shortname)}">Vote Now!</a></td>
+ <td><a href="${tg.url('/vote/' +
election.shortname)}">Vote Now!</a></td>
</tr>
- </table>
+ </table>
+ <p>To vote in this election you must be a member of any one of the following
groups:</p>
+ <ul>
+ <li py:for="g in votergroups">${g.group_name}</li>
+ </ul>
</body>
</html>
Deleted: branches/0.1.0-STABLE/elections/templates/ballot.html
===================================================================
--- branches/0.1.0-STABLE/elections/templates/ballot.html 2008-05-31 06:01:16 UTC (rev
40)
+++ branches/0.1.0-STABLE/elections/templates/ballot.html 2008-05-31 06:16:24 UTC (rev
41)
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html
xmlns="http://www.w3.org/1999/xhtml"
-
xmlns:py="http://genshi.edgewall.org/"
-
xmlns:xi="http://www.w3.org/2001/XInclude">
- <xi:include href="master.html" />
- <head>
- <title>Welcome to TurboGears</title>
- </head>
- <body>
- <h1>${election.name}</h1>
- <p>${election.info}</p>
- <p py:if="election.url"><a
href="${election.url}">[More Information]</a></p>
- <form action="${tg.url('/vote/' + str(election.id))}"
method="post">
- <table border="1" cellpadding="1">
- <tr py:for="candidate in candidates">
- <td>${candidate.name} <small py:if="candidate.url"><a
href="${candidate.url}">[info]</a></small></td>
- <td><input type="text" name="${candidate.id}"
value="" /></td>
- </tr>
- <tr>
- <td></td>
- <td><input type="submit" value="Submit"
/></td>
- </tr>
- </table>
- </form>
- </body>
-</html>
Deleted: branches/0.1.0-STABLE/elections/templates/confirm.html
===================================================================
--- branches/0.1.0-STABLE/elections/templates/confirm.html 2008-05-31 06:01:16 UTC (rev
40)
+++ branches/0.1.0-STABLE/elections/templates/confirm.html 2008-05-31 06:16:24 UTC (rev
41)
@@ -1,26 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html
xmlns="http://www.w3.org/1999/xhtml"
-
xmlns:py="http://genshi.edgewall.org/"
-
xmlns:xi="http://www.w3.org/2001/XInclude">
- <xi:include href="master.html" />
- <head>
- <title>Welcome to TurboGears</title>
- </head>
- <body>
- <h1>Confirm Vote in ${election.name}</h1>
- <p>${election.info}</p>
- <p py:if="election.url"><a
href="${election.url}">[More Information]</a></p>
- <form action="${tg.url('/vote/' + str(election.id))}"
method="post">
- <table border="1" cellpadding="1">
- <tr py:for="candidate in candidates">
- <td>${candidate.name} <small py:if="candidate.url"><a
href="${candidate.url}">[info]</a></small></td>
- <td><input type="text" name="${candidate.id}"
value="${voteinfo[candidate.id]}" readonly="readonly"
/></td>
- </tr>
- <tr>
- <td></td>
- <td><input type="submit" name="confirm"
value="Confirm Vote!" /></td>
- </tr>
- </table>
- </form>
- </body>
-</html>
Copied: branches/0.1.0-STABLE/elections/templates/index.html (from rev 40,
trunk/elections/templates/index.html)
===================================================================
--- branches/0.1.0-STABLE/elections/templates/index.html (rev 0)
+++ branches/0.1.0-STABLE/elections/templates/index.html 2008-05-31 06:16:24 UTC (rev 41)
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:py="http://genshi.edgewall.org/"
+
xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="master.html" />
+ <head>
+ <title>${appTitle}</title>
+ </head>
+ <body>
+ <ul>
+<!-- !Maybe change this link depending if they are logged in or not -->
+ <li py:for="election in elections"><a
href="${tg.url('/about/' +
election.shortname)}">${election.name}</a></li>
+<!-- !Would be nice features also include voting dates -->
+ </ul>
+ </body>
+</html>
Deleted: branches/0.1.0-STABLE/elections/templates/list.html
===================================================================
--- branches/0.1.0-STABLE/elections/templates/list.html 2008-05-31 06:01:16 UTC (rev 40)
+++ branches/0.1.0-STABLE/elections/templates/list.html 2008-05-31 06:16:24 UTC (rev 41)
@@ -1,16 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html
xmlns="http://www.w3.org/1999/xhtml"
-
xmlns:py="http://genshi.edgewall.org/"
-
xmlns:xi="http://www.w3.org/2001/XInclude">
- <xi:include href="master.html" />
- <head>
- <title>Welcome to TurboGears</title>
- </head>
- <body>
- <ul>
-<!-- Maybe change this link depending if they are logged in or not -->
- <li py:for="election in elections"><a
href="${tg.url('/about/' +
election.shortname)}">${election.name}</a></li>
-<!-- Would be nice features also include voting dates -->
- </ul>
- </body>
-</html>
Modified: branches/0.1.0-STABLE/elections/templates/login.html
===================================================================
--- branches/0.1.0-STABLE/elections/templates/login.html 2008-05-31 06:01:16 UTC (rev 40)
+++ branches/0.1.0-STABLE/elections/templates/login.html 2008-05-31 06:16:24 UTC (rev 41)
@@ -4,7 +4,7 @@
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" />
<head>
- <title>Login</title>
+ <title>${appTitle}</title>
</head>
<body>
<div id="loginBox">
Copied: branches/0.1.0-STABLE/elections/templates/vote.html (from rev 40,
trunk/elections/templates/vote.html)
===================================================================
--- branches/0.1.0-STABLE/elections/templates/vote.html (rev 0)
+++ branches/0.1.0-STABLE/elections/templates/vote.html 2008-05-31 06:16:24 UTC (rev 41)
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:py="http://genshi.edgewall.org/"
+
xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="master.html" />
+ <head>
+ <title>${appTitle} -- Cast Your Vote</title>
+ </head>
+ <body>
+ <h1>${election.name}</h1>
+ <p>${election.info}</p>
+ <p py:if="election.url"><a
href="${election.url}">[More Information]</a></p>
+ <form action="${tg.url('/vote/' + str(election.id))}"
method="post">
+ <table border="1" cellpadding="1">
+ <tr py:for="candidate in candidates">
+ <td>${candidate.name} <small py:if="candidate.url"><a
href="${candidate.url}">[info]</a></small></td>
+ <py:if test="nextaction=='vote'">
+ <td><select name="${candidate.id}">
+ <option py:for="option in range(0,len(candidates)+1)"
value="$option">$option</option>
+ </select></td>
+ </py:if>
+ <py:if test="nextaction=='confirm'">
+ <td><input type="hidden" name="${candidate.id}"
value="${voteinfo[candidate.id]}" />${voteinfo[candidate.id]}</td>
+ </py:if>
+ </tr>
+ <tr>
+ <td><input py:if="nextaction=='confirm'"
type="button" value="Go Back"
onClick="javascript.history.back(1)" /></td>
+ <td><input type="submit" name="${nextaction}"
value="Submit" /></td>
+ </tr>
+ </table>
+ </form>
+ </body>
+</html>
Modified: branches/0.1.0-STABLE/elections.sql
===================================================================
--- branches/0.1.0-STABLE/elections.sql 2008-05-31 06:01:16 UTC (rev 40)
+++ branches/0.1.0-STABLE/elections.sql 2008-05-31 06:16:24 UTC (rev 41)
@@ -23,8 +23,8 @@
create table legalVoters (
election_id integer not null,
group_name text not null,
-foreign key (election_id) references elections (id),
-primary key (election_id)
+foreign key (election_id) references elections (id)
+-- primary key (election_id)
);
create table candidates (