In the middle of adding custom theme supports. Skin_pictures table added to store...
[selectricity] / app / controllers / election_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 ElectionController < ApplicationController
20   require_dependency "raw_voter_list"
21   require_dependency "voter"
22   require_dependency "vote"
23   require_dependency "candidate"
24   layout 'main'
25
26   ## methods for displaying, creating,
27   ## and manipulating election overview data
28   ####################################################################
29
30   def new
31     redirect_to :action => 'general_information'
32   end
33   
34   def general_information
35     @sidebar_content = render_to_string :partial => 'progress',
36                                         :locals => { :page => 'overview' }
37     @election = Election.new
38     render :action => 'general_information'
39   end
40   
41   def create_election
42     @election = Election.new(params[:election])
43     
44     # default options
45     @election.user = session[:user]
46     @election.anonymous = 1
47     @election.startdate = Time.now
48
49     if @election.save
50       flash[:notice] = 'Election was successfully created.'
51       redirect_to :action => 'edit_candidates', :id => @election.id
52     else
53       render :action => 'general_information'
54     end
55   end
56   
57   # TODO add filter to verify that the person working on or looking at
58   # something is the owner
59   def edit_general_information
60     @election = Election.find(params[:id])
61   end
62   
63   def update_general_information
64     @election = Election.find(params[:id])
65     
66     if params[:skin_picture]
67       add_theme
68     end
69     
70     if @election.update_attributes(params[:election])
71       flash[:notice] = 'Election was successfully updated.'
72       redirect_to :action => 'show', :id => @election
73     else
74       render :action => 'edit'
75     end
76   end
77   
78   def add_theme
79     debugger
80     skin_picture = SkinPicture.new(params[:skin_picture])
81     skin_picture.save
82   end
83
84   def show
85     @sidebar_content = render_to_string :partial => 'progress',
86                                         :locals => { :page => 'review' }
87
88     @election = Election.find(params[:id])
89     if @election.type == QuickVote
90       redirect_to(:controller => 'quickvote', :action => 'index', :ident => @election.id)
91     end
92       
93   end
94
95   def start_election
96     @election = Election.find(params[:id])
97     
98     @election.voters.each do |voter|
99       voter.vote = Vote.new
100       email_voter voter unless voter.email.nil?
101     end
102
103     @election.activate!
104     redirect_to :action => 'show', :id => @election.id
105   end
106
107   # methods fod display, adding, deleting, and manipulating candidate
108   # information for elections
109   ####################################################################
110   def edit_candidates
111     @sidebar_content = render_to_string :partial => 'progress',
112                                         :locals => { :page => 'candidates' }
113     @election = Election.find( params[:id] )
114   end
115
116   def add_candidate
117     @election = Election.find(params[:id])
118     @candidate = Candidate.new(params[:candidate])
119     @election.candidates << @candidate
120
121     if @candidate.save
122       # check to see if they've uploaded a picture
123       if params[:picture][:uploaded_data]
124         picture = Picture.new(params[:picture])
125         @candidate.picture = picture if picture.save
126       end
127
128       @candidate = Candidate.new
129       redirect_to :action => 'edit_candidates', :id => @election.id
130     else
131       render :action => 'edit_candidates', :id => @election.id
132     end
133   end
134   
135   def delete_candidate
136     candidate = Candidate.find( params[:id] )
137     candidate.destroy
138   end
139
140   def candidate_picture
141     candidate = Candidate.find( params[:id] )
142     send_data( candidate.picture.data,
143                :filename => candidate.picture.filename,
144                :type => candidate.picture.filetype,
145                :disposition => 'inline' )
146   end
147
148   ## methods for displaying, adding, deleting, and manipulating voters
149   ## for a particular election
150   ####################################################################
151   def new_voters
152     redirect_to :action => 'edit_voters', :id => params[:id]
153   end
154   
155   def edit_voters
156     @sidebar_content = render_to_string :partial => 'progress',
157                                         :locals => { :page => 'voters' }
158
159     @election = Election.find( params[:id] )
160     if params.has_key?( :raw_voter_list )
161       process_incoming_voters( params[:raw_voter_list] )
162     end
163     @raw_voter_list = RawVoterList.new
164   end
165   
166   def delete_voter
167     voter = Voter.find( params[:id] )
168     voter.destroy
169   end
170
171   def toggle_authenticated
172     @election = Election.find(params[:id])
173     if params[:authenticated] == "1"
174       @election.authenticated = true
175     else
176       @election.authenticated = false
177     end
178     @election.save
179   end
180   
181   ## methods for computing and printing results
182   ####################################################################
183   def results
184     @election = Election.find( params[:id] )
185     votes = []
186     
187     @election.voters.each do |voter|
188       if voter.vote and voter.vote.confirmed?
189         votes << voter.vote.rankings.sort.collect {|vote| vote.candidate_id}
190       end
191     end
192     
193     @voteobj = CloneproofSSDVote.new(votes)
194     @resultobj = @voteobj.result
195     @winners = @resultobj.winners
196     
197     @candidates_by_id = {}
198     @election.candidates.each {|cand| @candidates_by_id[cand.id] = cand}
199     
200   end
201   
202   def detailed_results
203    
204     self.results
205
206     @voter_list = []
207     @vote_list = []
208     
209     @election.voters.each do |voter|
210       if voter.vote and voter.vote.confirmed?
211         @voter_list << voter.email
212               @vote_list << voter.vote
213       end
214     end
215
216     @vote_list.sort!
217     @vote_list.sort! { |a,b| a.token <=> b.token }
218   end
219
220   ## private methods
221   ####################################################################
222   private
223
224     def process_incoming_voters(raw_voter_list)
225       incoming_voters = RawVoterList.new( raw_voter_list )
226
227       unless incoming_voters.entries.empty?
228         incoming_voters.each do |new_voter|
229           new_voter.email.strip! # There's a trailing \r on all but the last in
230                                  # the list!
231           if new_voter.valid?
232             # the new voter should be in good shape. save add to the election
233             @election.voters << new_voter
234                   new_voter.save
235           end
236           # TODO: Can we do some kind of AJAX error message for the voter being invalid?
237         end
238         @election.save
239       end
240  
241       # reset the next time to have a the same default value for emailing
242       @raw_voter_list = RawVoterList.new
243       @raw_voter_list.email = incoming_voters.email
244     end
245
246     def email_voter(voter=nil)
247       if voter
248         VoterNotify.deliver_votestart(voter)
249         voter.contacted=1
250         voter.save
251       end
252     end
253
254 end

Benjamin Mako Hill || Want to submit a patch?