]> projects.mako.cc - selectricity-live/blob - app/models/selectricity_service.rb
Fix WHOIS library not to puke on strange IP addresses
[selectricity-live] / app / models / selectricity_service.rb
1 require 'action_controller/integration'
2
3 class SelectricityService < ActionWebService::Base
4   web_service_api SelectricityAPI
5
6   ## Casts a quickvote.
7   ## Expects a quickvote name, a voter ID, and a list of candidate ID's respectively.
8   ## Returns a string containing any potential errors that occurred in the process.
9   def cast_quickvote(election_name, voter_id, vote_list)
10     election = QuickVote.ident_to_quickvote election_name
11     if election
12       candidates=election.candidates.collect { |c| c.id }
13       vote_list[0].each do |vote|
14         raise ArgumentError.new("Invalid Candidate ID #{vote}") unless candidates.index(vote)
15       end
16       raise ArgumentError.new("You must rank all candidates") unless candidates.length <= vote_list[0].length
17       raise ArgumentError.new("Please rank each candidate only once") if vote_list[0].uniq!
18       voter = QuickVoter.new
19       voter.election = election
20       voter.ipaddress = "XMLRPC Request"
21       voter.session_id = "XMLRPC:#{voter_id}"
22       voter.vote=Vote.new
23       voter.vote.votes=vote_list[0]
24       voter.vote.time = Time.now
25       voter.save!
26       voter.vote.confirm!
27       voter.save!
28     else
29       raise ArgumentError.new("Cannot find election #{election_name}")
30     end
31   end
32
33   ## Converts QuickVote candidate ID's to names
34   ## Takes in a QuickVote name and a list of candidate ID's, and returns the names of
35   ## each candidate. Useful for doing just a few lookups; it's more efficient to use
36   ## get_quickvote_candidate_map for presenting info about an entire election.
37   def quickvote_candidate_ids_to_names(shortname, id_list)
38     qv=QuickVote.ident_to_quickvote(shortname)
39     candidates={}
40     raise ArgumentError.new("Quickvote by name #{shortname} doesn't exist") unless qv
41     qv.results
42     qv.candidates.each {|c| candidates[c.id] = c}
43     results=[]
44     id_list.each { |id|
45       name=candidates[id]
46       if name
47         results << name
48       else
49         results << ""
50       end
51     }
52     results
53   end
54
55   ## Return the results of a QuickVote.
56   ## Takes in the name of a quickvote, and returns a structure as described by
57   ## QuickVoteResultStruct
58   def get_quickvote_results(shortname)
59     #TODO: Validate shortname
60     qv=QuickVote.ident_to_quickvote(shortname)
61     result=QuickVoteResultStruct.new
62     unless qv
63       raise ArgumentError.new("No quickvote with name #{shortname} found!")
64     end
65     qv.results
66     result.plurality_winners=qv.plurality_result.winners
67     result.approval_winners=qv.approval_result.winners
68     result.condorcet_winners=qv.condorcet_result.winners
69     result.ssd_winners=qv.ssd_result.winners
70     result.borda_winners=qv.borda_result.winners
71     result
72   end
73
74   ## Returns information regarding all the candidates in a QuickVote
75   ## Takes in a QuickVote name, and returns the list of names and ID's of candidates
76   ## This can be useful for presenting the user with a list of readable names, while
77   ## the software sends results to us in the numeric ID's we require. The two lists are in
78   ## respective order.
79   def get_quickvote_candidate_map(shortname)
80     qv=QuickVote.ident_to_quickvote(shortname)
81     result=QuickVoteCandidateMap.new
82     unless qv
83       raise ArgumentError.new("No quickvote with name #{shortname} found!")
84     end
85     candidates={}
86     qv.candidates.each {|c| candidates[c.id] = c.name}
87     result.candidate_ids=candidates.keys
88     result.candidate_names=candidates.values
89     result
90   end
91
92   ## Get information on all the votes cast in a QuickVote
93   ## Takes in the name of a QuickVote, returns an array of QuickVoterInfo structures.
94   def get_quickvote_votes(shortname)
95     qv = QuickVote.ident_to_quickvote(shortname)
96
97     unless qv
98       raise ArgumentError.new("Cannot find QuickVote #{shortname}")
99     end
100
101     qv.votes.collect do |vote|
102        QuickVoterInfo.new(:voter_id => vote.voter.id,
103                     :voter_ipaddress => vote.voter.ipaddress,
104                     :vote_time => vote.time.to_i,
105                     :vote => vote.votes,
106                     :voter_session_id => vote.voter.session_id)
107     end
108   end
109
110   ## Gets a list of all QuickVotes in the system.
111   def list_quickvotes()
112     QuickVote.find(:all).collect do |election|
113       get_quickvote(election.name)
114     end
115   end
116
117   ## Gets information on a particular QuickVote
118   ## Takes in a QuickVote name
119   def get_quickvote(shortname)
120     unless election = QuickVote.ident_to_quickvote(shortname)
121       raise ArgumentError.new("Cannot find QuickVote named #{shortname}")
122     end
123
124     QuickVoteStruct.new(
125       :id => election.id,
126       :name => election.name,
127       :description => election.description,
128       :candidate_ids => election.candidates.collect {|c| c.id },
129       :candidate_names => election.candidates.collect {|c| c.name } )
130   end
131
132   ## Create a QuickVote
133   ## Pass in a QuickVoteStruct populated with all the fields but the candidate ID's
134   ## Any candidate ID's you fill in will be ignored anyway.
135   def create_quickvote(election)
136     qv = QuickVote.new(:name => election.name,
137                        :description => election.description)
138     qv.candidate_names = election.candidate_names
139
140     if qv.save
141       return ""
142     else
143       raise ArgumentError.new("Saving quickvote FAILED:"+qv.errors.inspect)
144     end
145   end
146
147 end

Benjamin Mako Hill || Want to submit a patch?