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

Benjamin Mako Hill || Want to submit a patch?