create new open voter to allow open full elections
[selectricity-live] / app / controllers / voter_controller.rb
1 # Selectricity: Voting Machinery for the Masses
2 # Copyright (C) 2007, 2008 Benjamin Mako Hill <mako@atdot.cc>
3 # Copyright (C) 2007 Massachusetts Institute of Technology
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Affero General Public License for more details.
14 #
15 # You should have received a copy of the GNU Affero General Public
16 # License along with this program.  If not, see
17 # <http://www.gnu.org/licenses/>.
18
19 class VoterController < ApplicationController
20   helper :sparklines
21   layout 'main'
22   require_dependency "voter"
23   require_dependency "vote"
24   require_dependency "election"
25
26   def index
27     if params[:election_id]
28       @election = Election.find(params[:election_id])
29       unless @election.authenticated?
30         @voter = OpenVoter.find(:all,
31           :conditions => ["session_id = ? and election_id = ?",
32           session.session_id, @election.id])[0]
33       
34         @voter = OpenVoter.new unless @voter
35
36         @voter.election = @election
37         @voter.session_id = session.session_id
38         @password = "open." + @election.id.to_s
39       end
40     elsif params[:urlpassword]
41       password = params[:urlpassword]
42
43       if @voter = FullVoter.find(:all,
44         :conditions => [ "password = ?", password ] )[0]
45         @election = @voter.election
46         @password = @voter.password
47       end
48     end
49
50     if @voter and @election
51       # initialize things if the vote is blank
52       if @voter.vote.nil?
53         @voter.vote = Vote.new 
54         @voter.save
55       end
56     
57       @voter.vote.set_defaults! if @voter.vote.rankings.empty?
58
59       # if the election is now finished 
60       if @election.enddate < Time.now
61         redirect_to :action => :results, :id => @password
62       else
63         @sidebar_content = render_to_string(:partial => 'vote_sidebar')
64         if @election.embeddable? and params[:embed] == "true"
65           #look for custom theme, and assign to instance variabels for widget use
66           if @election.embed_custom_string
67             @top_bar = SkinPicture.find(:first,
68             :conditions => ["filename = ?", @election.embed_custom_string + "top_bar.png"])
69             @default_image = SkinPicture.find(:first,
70             :conditions => ["filename = ?", @election.embed_custom_string + "default_image.png"])
71             @bg1 = SkinPicture.find(:first,
72             :conditions => ["filename = ?", @election.embed_custom_string + "bg1.png"])
73             @bg2 = SkinPicture.find(:first,
74             :conditions => ["filename = ?", @election.embed_custom_string + "bg2.png"])
75             @bottom_bar = SkinPicture.find(:first,
76             :conditions => ["filename = ?", @election.embed_custom_string + "bottom_bar.png"])
77           end
78           render :template => 'embed/full_vote', :layout => 'embed'
79         else
80           render :action => 'full_vote'
81         end
82       end
83     end
84   end
85
86   def login
87     if params[:vote] and params[:vote][:password]
88       redirect_to votepassword_url( :action => 'index', :urlpassword => params[:vote][:password])
89     else
90       redirect_to :action => 'index'
91     end
92   end
93   
94   def pref_tables
95     if authenticate
96       @election = @voter.election
97       @results = @election.results
98       @candidates = {}
99       @election.candidates.each {|c| @candidates[c.id] = c}
100       @names = @election.names_by_id
101       render :template => 'common/pref_tables', :layout => 'basic'
102     else
103       redirect_to :action => 'index'
104     end
105   end
106
107   def details
108     if authenticate
109       @election = @voter.election
110       @votes = @election.votes.select {|v| v.confirmed? }.shuffle
111       @voters = @votes.collect {|v| v.voter}.shuffle
112       render :action => 'details'
113     else
114       redirect_to :action => 'index'
115     end
116   end
117
118   def review
119     if authenticate
120       @voter.vote.time = Time.now
121       @voter.vote.save
122       @voter.reload
123     else
124       redirect_to :action => 'index'
125     end
126   end
127
128   def confirm
129     if authenticate
130       @voter.vote.confirm!
131
132       if @voter.election.embeddable? and params[:embed] == "true" \
133         and @voter.election.early_results?
134         redirect_to :action => :results, :id => @password, :embed => 'true'
135       else
136         render :action => 'thanks'
137       end
138     else
139       redirect_to :action => 'index'
140     end
141   end
142   
143   def reminder
144     if params[:email]
145       voter_array= FullVoter.find(:all, :conditions => ["email = ?", params[:email]])
146       voter_array.delete_if {|voter| voter.election.active == 0}
147       unless voter_array.empty?
148         VoterNotify.deliver_reminder(voter_array)
149       end
150       render :action => 'reminder_sent'
151     end
152   end
153   
154   def results
155     if authenticate and
156       (@voter.election.early_results? \
157        or @voter.election.enddate < Time.now)
158       
159       @election = @voter.election
160       # compute and display results
161
162       @results = @election.results
163       @candidates = {}
164       @election.candidates.each {|c| @candidates[c.id] = c}
165       @names = @election.names_by_id
166         
167       @sidebar_content = render_to_string(:partial => 'results_sidebar')
168       #look for custom theme, and assign to instance variabels for widget use
169       if @election.embed_custom_string
170         @top_bar = SkinPicture.find(:first,
171         :conditions => ["filename = ?", @election.embed_custom_string + "top_bar.png"])
172         @default_image = SkinPicture.find(:first,
173         :conditions => ["filename = ?", @election.embed_custom_string + "default_image.png"])
174         @bg1 = SkinPicture.find(:first,
175         :conditions => ["filename = ?", @election.embed_custom_string + "bg1.png"])
176         @bg2 = SkinPicture.find(:first,
177         :conditions => ["filename = ?", @election.embed_custom_string + "bg2.png"])
178         @bottom_bar = SkinPicture.find(:first,
179         :conditions => ["filename = ?", @election.embed_custom_string + "bottom_bar.png"])
180       end
181       if @election.embeddable? and params[:embed] == "true"
182         render :template => 'embed/results', :layout => 'embed'
183       else
184         render :action => 'results'
185       end
186     else
187       redirect_to :action => 'index'
188     end
189   end
190   
191   private
192   def authenticate
193     password = params[:id]
194     if password == "open"
195       election = Election.find(params[:format])
196       unless election.authenticated?
197         @voter = OpenVoter.find(:all,
198           :conditions => ["session_id = ? and election_id = ?",
199                           session.session_id, election.id])[0]
200         @password = "open." + election.id.to_s
201       end
202     else
203       @voter = FullVoter.find(:all,
204         :conditions => [ "password = ?", password ] )[0]
205       @password = @voter.password
206     end
207     @voter
208   end
209 end
210

Benjamin Mako Hill || Want to submit a patch?