4ff8140cae14929891528dd43f4b48b87ea4a42e
[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
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       if @voter.vote.confirm!
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     else
142         redirect_to :action => 'index'
143     end
144   end
145   
146   def reminder
147     if params[:email]
148       voter_array= FullVoter.find(:all, :conditions => ["email = ?", params[:email]])
149       voter_array.delete_if {|voter| voter.election.active == 0}
150       unless voter_array.empty?
151         VoterNotify.deliver_reminder(voter_array)
152       end
153       render :action => 'reminder_sent'
154     end
155   end
156   
157   def results
158     debugger
159     if authenticate and
160       (@voter.election.early_results? \
161        or @voter.election.enddate < Time.now)
162       
163       @election = @voter.election
164       # compute and display results
165
166       @results = @election.results
167       @candidates = {}
168       @election.candidates.each {|c| @candidates[c.id] = c}
169       @names = @election.names_by_id
170         
171       @sidebar_content = render_to_string(:partial => 'results_sidebar')
172       #look for custom theme, and assign to instance variabels for widget use
173       if @election.embed_custom_string
174         @top_bar = SkinPicture.find(:first,
175         :conditions => ["filename = ?", @election.embed_custom_string + "top_bar.png"])
176         @default_image = SkinPicture.find(:first,
177         :conditions => ["filename = ?", @election.embed_custom_string + "default_image.png"])
178         @bg1 = SkinPicture.find(:first,
179         :conditions => ["filename = ?", @election.embed_custom_string + "bg1.png"])
180         @bg2 = SkinPicture.find(:first,
181         :conditions => ["filename = ?", @election.embed_custom_string + "bg2.png"])
182         @bottom_bar = SkinPicture.find(:first,
183         :conditions => ["filename = ?", @election.embed_custom_string + "bottom_bar.png"])
184       end
185       if @election.embeddable? and params[:embed] == "true"
186         render :template => 'embed/results', :layout => 'embed'
187       else
188         render :action => 'results'
189       end
190     else
191       redirect_to :action => 'index'
192     end
193   end
194   
195   private
196   def authenticate
197     password = params[:id]
198     if password == "open"
199       election = Election.find(params[:format])
200
201       # double check to make sure the election is not authenticated
202       unless election.authenticated?
203         @voter = OpenVoter.find(:all,
204           :conditions => ["session_id = ? and election_id = ?",
205                           session.session_id, election.id])[0]
206
207         # if the election is over, proceed
208         if (not @voter) and (election.enddate < Time.now)
209           @voter = OpenVoter.new
210           @voter.election = election
211         end
212
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?