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

Benjamin Mako Hill || Want to submit a patch?