9ba619c918a3f1e1a0858f8ba962984929b17c1d
[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. Please see the COPYING file for
6 # details.
7
8 class VoterController < ApplicationController
9   helper :sparklines
10   layout 'main'
11   require_dependency "voter"
12   require_dependency "vote"
13   require_dependency "election"
14
15   def index
16     if params[:election_id]
17       @election = Election.find(params[:election_id])
18       unless @election.authenticated?
19         @voter = OpenVoter.find(:all,
20           :conditions => ["session_id = ? and election_id = ?",
21           session.session_id, @election.id])[0]
22      
23         @voter = OpenVoter.new unless @voter
24
25         @voter.election = @election
26         @voter.session_id = session.session_id
27         @password = "open." + @election.id.to_s
28       end
29     elsif params[:urlpassword]
30       password = params[:urlpassword]
31
32       if @voter = FullVoter.find(:all,
33         :conditions => [ "password = ?", password ] )[0]
34         @election = @voter.election
35         @password = @voter.password
36       end
37     end
38
39     if @voter and @election
40       # initialize things if the vote is blank
41       if @voter.vote.nil?
42         @voter.vote = Vote.new 
43         @voter.save
44       end
45     
46       @voter.vote.set_defaults! if @voter.vote.rankings.empty?
47
48       # if the election is now finished 
49       if @election.enddate < Time.now
50         redirect_to :action => :results, :id => @password
51       else
52         @sidebar_content = render_to_string(:partial => 'vote_sidebar')
53         if @election.embeddable? and params[:embed] == "true"
54           #look for custom theme, and assign to instance variabels for widget use
55           if @election.embed_custom_string
56             @top_bar = SkinPicture.find(:first,
57             :conditions => ["filename = ?", @election.embed_custom_string + "top_bar.png"])
58             @default_image = SkinPicture.find(:first,
59             :conditions => ["filename = ?", @election.embed_custom_string + "default_image.png"])
60             @bg1 = SkinPicture.find(:first,
61             :conditions => ["filename = ?", @election.embed_custom_string + "bg1.png"])
62             @bg2 = SkinPicture.find(:first,
63             :conditions => ["filename = ?", @election.embed_custom_string + "bg2.png"])
64             @bottom_bar = SkinPicture.find(:first,
65             :conditions => ["filename = ?", @election.embed_custom_string + "bottom_bar.png"])
66           end
67           render :template => 'embed/full_vote', :layout => 'embed'
68         else
69           render :action => 'full_vote'
70         end
71       end
72     end
73   end
74
75   def login
76     if params[:vote] and params[:vote][:password]
77       redirect_to votepassword_url( :action => 'index', :urlpassword => params[:vote][:password])
78     else
79       redirect_to :action => 'index'
80     end
81   end
82   
83   def pref_tables
84     if authenticate
85       @election = @voter.election
86       @results = @election.results
87       @candidates = {}
88       @election.candidates.each {|c| @candidates[c.id] = c}
89       @names = @election.names_by_id
90       render :template => 'common/pref_tables', :layout => 'basic'
91     else
92       redirect_to :action => 'index'
93     end
94   end
95
96   def details
97     if authenticate
98       @election = @voter.election
99       @votes = @election.votes.select {|v| v.confirmed? }.shuffle
100       @voters = @votes.collect {|v| v.voter}.shuffle
101       render :action => 'details'
102     else
103       redirect_to :action => 'index'
104     end
105   end
106
107   def review
108     if authenticate
109       @voter.vote.time = Time.now
110       @voter.vote.save
111       @voter.reload
112     else
113       redirect_to :action => 'index'
114     end
115   end
116
117   def confirm
118     if authenticate
119       @voter.vote.confirm!
120
121       if @voter.election.embeddable? and params[:embed] == "true" \
122         and @voter.election.early_results?
123         redirect_to :action => :results, :id => @password, :embed => 'true'
124       elsif @voter.election.kiosk and params[:kiosk] = "true"
125         redirect_to :action => "kiosk_ready", :id => @password, :kiosk => true
126       else
127         render :action => 'thanks'
128       end
129     else
130       redirect_to :action => 'index'
131     end
132   end
133   
134   def reminder
135     if params[:email]
136       voter_array= FullVoter.find(:all, :conditions => ["email = ?", params[:email]])
137       voter_array.delete_if {|voter| voter.election.active == 0}
138       unless voter_array.empty?
139         VoterNotify.deliver_reminder(voter_array)
140       end
141       render :action => 'reminder_sent'
142     end
143   end
144   
145   def results
146     if authenticate and
147       (@voter.election.early_results? \
148        or @voter.election.enddate < Time.now)
149       
150       @election = @voter.election
151       # compute and display results
152
153       @results = @election.results
154       @candidates = {}
155       @election.candidates.each {|c| @candidates[c.id] = c}
156       @names = @election.names_by_id
157         
158       @sidebar_content = render_to_string(:partial => 'results_sidebar')
159       #look for custom theme, and assign to instance variabels for widget use
160       if @election.embed_custom_string
161         @top_bar = SkinPicture.find(:first,
162         :conditions => ["filename = ?", @election.embed_custom_string + "top_bar.png"])
163         @default_image = SkinPicture.find(:first,
164         :conditions => ["filename = ?", @election.embed_custom_string + "default_image.png"])
165         @bg1 = SkinPicture.find(:first,
166         :conditions => ["filename = ?", @election.embed_custom_string + "bg1.png"])
167         @bg2 = SkinPicture.find(:first,
168         :conditions => ["filename = ?", @election.embed_custom_string + "bg2.png"])
169         @bottom_bar = SkinPicture.find(:first,
170         :conditions => ["filename = ?", @election.embed_custom_string + "bottom_bar.png"])
171       end
172       if @election.embeddable? and params[:embed] == "true"
173         render :template => 'embed/results', :layout => 'embed'
174       else
175         render :action => 'results'
176       end
177     else
178       redirect_to :action => 'index'
179     end
180   end
181  
182   def kiosk_ready
183     reset_session
184
185     if not authenticate
186       redirect_to :action => 'index'
187     end
188   end
189
190   private
191   def authenticate
192     password = params[:id]
193     if password == "open"
194       election = Election.find(params[:format])
195
196       # check to see if the person has voted before
197       unless election.authenticated?
198         @voter = OpenVoter.find(:all,
199           :conditions => ["session_id = ? and election_id = ?",
200                           session.session_id, election.id])[0]
201         @password = "open." + election.id.to_s
202       end
203
204       # if it's ready for kiosk_mode, then we create and authenticate
205       unless @voter and params[:action] == 'kiosk_ready' \
206         and election.kiosk
207        
208         # this is maybe not quite as a dry as it should be
209         @voter = OpenVoter.new unless @voter
210
211         @voter.election = election
212         @voter.session_id = session.session_id
213         @password = "open." + election.id.to_s
214       end
215
216     else
217       @voter = FullVoter.find(:all,
218         :conditions => [ "password = ?", password ] )[0]
219       @password = @voter.password
220     end
221     @voter
222   end
223 end
224

Benjamin Mako Hill || Want to submit a patch?