+class VoteInfo < ActionWebService::Struct
+ member :voter_id, :int
+ member :voter_ipaddress, :string
+ member :vote_time, :int
+end
+
class VoteResultStruct < ActionWebService::Struct
member :plurality_winners, [:int]
member :approval_winners, [:int]
api_method :get_quickvote_results, :expects => [:string], :returns => [VoteResultStruct]
api_method :get_quickvote_candidate_map, :expects => [:string], :returns => [CandidateMap]
api_method :quickvote_candidate_ids_to_names, :expects => [:string,[:int]], :returns => [[:string]]
+ api_method :get_quickvote_votes, :expects => [:string], :returns => [ [VoteInfo] ]
end
#pref_tally = make_preference_tally(@election)
#@borda_result = BordaVote.new(pref_tally).result
+ @election.results unless @election.borda_result
data, labels = get_borda_points(@election.borda_result)
graph = GruffGraff.new( :graph_type => Gruff::Bar,
# Now I need to create an array with all the times votes were made
election.votes.each do |vote|
- voter_days << Date.parse(vote.time.to_s)
+ next unless vote.time
+ voter_days << Date.parse(vote.time.to_s)
end
voter_days.sort!
# Will build a graph over time, as each successive interval will have more
# vote objects
election.votes.each do |vote|
+ next unless vote.time
buckets.keys.sort.each do |inter|
if vote.time < inter
buckets[inter] << vote
# store the candidate grabbed through ajax and stored in flash
@quickvote.candidatelist = flash[:candlist]
-
+ @quickvote.description=CGI.escapeHTML(@quickvote.description)
# try to save, if it fails, show the page again (the flash should
# still be intact
if @quickvote.save
end
def add_candidate
- candidate_name = params[:ajax][:newcandidate]
- if flash.has_key?(:candlist) and flash[:candlist].instance_of?(Array)
- flash[:candlist] << candidate_name
- else
- flash[:candlist] = [ candidate_name ]
+ candidate_name = CGI.escapeHTML(params[:ajax][:newcandidate])
+ unless candidate_name.strip.empty?
+ if flash.has_key?(:candlist) and flash[:candlist].instance_of?(Array)
+ flash[:candlist] << candidate_name unless flash[:candlist].index(candidate_name)
+ else
+ flash[:candlist] = [ candidate_name ]
+ end
end
flash.keep(:candlist)
render_partial 'candidate_list'
attr_accessor :borda_result
def validate
- if @raw_candidates.length < 2
- errors.add("You must list at least two candidates.")
+ if not @raw_candidates or @raw_candidates.length < 2
+ errors.add(nil, "You must list at least two candidates.")
end
-
+
if name =~ /[^A-Za-z0-9]/
- errors.add("The name must only include numbers and letters.")
+ errors.add(:name, "must only include numbers and letters.")
+ end
+ if name =~ /^[0-9]+$/
+ errors.add(:name, "must not be a number")
+ end
+
+ if name =~ /^(create|index|confirm|change|results)$/
+ errors.add(:name, " is a reserved word.")
end
end
end
def create_candidates
+ return unless errors.empty?
@raw_candidates.each do |name|
candidate = Candidate.new({:name => name})
self.candidates << candidate
### Convert a shortname or id into a QuickVote
def self.ident_to_quickvote(ident)
+ return nil unless ident
if ident.match(/^\d+$/)
quickvote = QuickVote.find(ident)
else
result.candidate_names=candidates.values
result
end
-
+ def get_quickvote_votes(shortname)
+ qv=QuickVote.ident_to_quickvote(shortname)
+ votes=Array.new
+ unless qv
+ return result
+ end
+ qv.votes.each do |vote|
+ votes << VoteInfo.new(:voter_id => vote.voter.id, :voter_ipaddress => vote.voter.ipaddress, :vote_time => vote.time.to_i)
+ end
+ return votes
+ end
+
end
-<% %>
-<%require 'IPAddr' %>
+<%require 'whois/whois' %>
<h1>Results</h1>
<% if @election.shortdesc %>
<h2>Voters</h2>
<table class="voterbox">
<tr>
-<th>IP Address</th>
-<th>DNS/Host</th>
+<th>IP/Host</th>
+<th>Origin</th>
<th>Vote</th>
</tr>
<% for voter in @election.voters %>
<% next unless voter.voted? %>
<tr>
- <td><%= voter.ipaddress %></td>
- <td><% begin %>
- <%= `host #{IPAddr.new(voter.ipaddress).to_s}`.sub(/^.*pointer (.*)\.$/, '\1') %>
+ <td><% begin %>
+ <% raise ArgumentError.new, "Local Server" if voter.ipaddress == "127.0.0.1" %>
+ <% raise ArgumentError.new, "XML-RPC Voter" if voter.ipaddress == "XMLRPC Request" %>
+ <% w= Whois::Whois.new(IPAddr.new(voter.ipaddress).to_s,true)%>
+ <%=(w.host == nil or w.host.empty?) ? voter.ipaddress : w.host%>
+ </td>
+ <td>
+ <%w.search_whois%>
+ <%= (w.all.grep(/^(OrgName|org-name)/)[0] or "").sub(/^(OrgName|org-name)\:/,'').strip -%> - <%= (w.all.grep(/^(NetName|netname)/)[0] or "").sub(/^(NetName|netname)\:/,'').strip %>
<% rescue ArgumentError => err %>
- <%= voter.ipaddress %>
+ <%= err %>
+ </td>
+ <td><%= err%>
<% end %>
</td>
<td><%= voter.vote.votestring %></td>
--- /dev/null
+---
+222.96.0.0/12: Nicor
+218.160.0.0/12: Twnic
+209.94.192.0/19: Lacnic
+155.232.0.0/13: Afrinic
+164.146.0.0/15: Afrinic
+202.16.0.0/14: Nicad
+218.216.0.0/13: Nicad
+202.0.0.0/7: Apnic
+192.71.0.0/16: Ripe
+61.112.0.0/12: Nicad
+141.64.0.0/12: Ripe
+43.0.0.0/8: V6nic
+211.112.0.0/13: Nicor
+211.20.0.0/15: Twnic
+202.224.0.0/11: Nicad
+151.100.0.0/16: Ripe
+160.124.0.0/16: Afrinic
+214.0.0.0/7: Arin
+210.242.0.0/15: Twnic
+61.192.0.0/12: Nicad
+163.156.0.0/14: Ripe
+171.16.0.0/12: Ripe
+200.128.0.0/9: Nicbr
+219.96.0.0/11: Nicad
+149.240.0.0/13: Ripe
+164.0.0.0/11: Ripe
+151.0.0.0/10: Ripe
+192.72.253.0/24: Arin
+221.144.0.0/12: Nicor
+203.66.0.0/16: Twnic
+202.11.0.0/16: Nicad
+0.0.0.0/1: Arin
+149.248.0.0/14: Ripe
+59.0.0.0/11: Nicor
+41.0.0.0/8: Afrinic
+149.204.0.0/16: Ripe
+218.232.0.0/13: Nicor
+218.224.0.0/13: Nicad
+210.248.0.0/13: Nicad
+210.204.0.0/14: Nicor
+116.0.0.0/6: Apnic
+202.24.0.0/15: Nicad
+200.0.0.0/7: Lacnic
+200.17.0.0/16: Nicbr
+125.128.0.0/11: Nicor
+150.254.0.0/16: Ripe
+164.32.0.0/13: Ripe
+211.192.0.0/10: Nicor
+203.69.0.0/16: Twnic
+192.118.0.0/16: Ripe
+202.39.128.0/17: Twnic
+220.149.0.0/16: Nicor
+212.0.0.0/7: Ripe
+211.128.0.0/13: Nicad
+211.120.0.0/13: Nicad
+210.71.128.0/16: Twnic
+203.140.0.0/15: Nicad
+96.0.0.0/3:
+196.0.0.0/6: Arin
+192.164.0.0/14: Ripe
+165.144.0.0/14: Afrinic
+155.240.0.0/16: Afrinic
+218.36.0.0/14: Nicor
+213.154.64.0/19: Afrinic
+210.240.0.0/16: Twnic
+210.128.0.0/11: Nicad
+210.59.128.0/17: Twnic
+223.0.0.0/8:
+219.248.0.0/13: Nicor
+211.72.0.0/16: Twnic
+203.74.0.0/15: Twnic
+203.0.0.0/10: Apnic
+196.0.0.0/8: Afrinic
+149.202.0.0/15: Ripe
+210.241.224.0/19: Twnic
+96.0.0.0/6: Arin
+171.32.0.0/15: Ripe
+220.64.0.0/11: Nicor
+219.240.0.0/15: Nicor
+210.0.0.0/7: Apnic
+211.16.0.0/14: Nicad
+210.92.0.0/14: Nicor
+202.32.0.0/14: Nicad
+220.103.0.0/16: Nicor
+211.75.0.0/16: Twnic
+202.20.128.0/17: Nicor
+208.0.0.0/7: Arin
+202.48.0.0/16: Nicad
+163.200.0.0/14: Afrinic
+61.208.0.0/13: Nicad
+139.24.0.0/14: Ripe
+62.0.0.0/8: Ripe
+222.232.0.0/13: Nicor
+61.84.0.0/15: Nicor
+194.0.0.0/7: Ripe
+126.0.0.0/8: Apnic
+150.183.0.0/16: Nicor
+141.80.0.0/14: Ripe
+163.195.0.0/16: Afrinic
+160.115.0.0/16: Afrinic
+211.32.0.0/11: Nicor
+192.72.0.0/16: Apnic
+164.40.0.0/16: Ripe
+210.61.0.0/16: Twnic
+160.120.0.0/14: Afrinic
+221.160.0.0/13: Nicor
+160.44.0.0/14: Ripe
+151.96.0.0/14: Ripe
+220.0.0.0/6: Apnic
+222.112.0.0/13: Nicor
+220.104.0.0/13: Nicad
+203.136.0.0/14: Nicad
+149.208.0.0/12: Ripe
+141.0.0.0/10: Ripe
+192.116.0.0/15: Ripe
+192.106.0.0/16: Ripe
+202.30.0.0/15: Nicor
+60.0.0.0/7: Apnic
+200.18.0.0/15: Nicbr
+160.220.0.0/16: Ripe
+124.0.0.0/7: Apnic
+58.0.0.0/7: Apnic
+218.0.0.0/7: Apnic
+204.0.0.0/14: Ginntt
+193.0.0.0/8: Ripe
+200.20.0.0/16: Nicbr
+192.162.0.0/16: Ripe
+202.15.0.0/16: Nicad
+163.196.0.0/14: Afrinic
+222.122.0.0/16: Nicor
+221.138.0.0/13: Nicor
+121.128.0.0/10: Nicor
+211.0.0.0/12: Nicad
+210.241.0.0/15: Twnic
+210.216.0.0/13: Nicor
+61.72.0.0/13: Nicor
+192.114.0.0/15: Ripe
+80.0.0.0/5: Ripe
+210.188.0.0/14: Nicad
+210.178.0.0/15: Nicor
+210.90.0.0/15: Nicor
+203.180.0.0/14: Nicad
+202.208.0.0/12: Nicad
+146.48.0.0/16: Ripe
+163.160.0.0/12: Ripe
+192.72.254.0/24: Arin
+213.154.32.0/19: Afrinic
+211.168.0.0/13: Nicor
+211.22.0.0/16: Twnic
+210.180.0.0/14: Nicor
+139.28.0.0/15: Ripe
+165.148.0.0/15: Afrinic
+222.120.0.0/15: Nicor
+220.96.0.0/14: Nicad
+216.0.0.0/8: Arin
+210.96.0.0/11: Nicor
+192.0.0.0/8: Arin
+133.0.0.0/8: Nicad
+149.206.0.0/15: Ripe
+160.116.0.0/14: Afrinic
+218.144.0.0/12: Nicor
+217.0.0.0/8: Ripe
+210.224.0.0/12: Nicad
+210.160.0.0/12: Nicad
+210.65.0.0/16: Twnic
+160.216.0.0/14: Ripe
+92.0.0.0/7: Ripe
+164.148.0.0/14: Afrinic
+189.0.0.0/8: Lacnic
+202.23.0.0/16: Nicad
+145.0.0.0/8: Ripe
+204.0.0.0/6: Arin
+165.143.0.0/16: Afrinic
+169.208.0.0/12: Apnic
+211.104.0.0/13: Nicor
+210.196.0.0/14: Nicad
+24.132.0.0/14: Ripe
+149.224.0.0/12: Ripe
+202.26.0.0/16: Nicad
+218.48.0.0/13: Nicor
+218.40.0.0/13: Nicad
+211.176.0.0/12: Nicor
+203.178.0.0/15: Nicad
+139.20.0.0/14: Ripe
+151.64.0.0/11: Ripe
+190.0.0.0/8: Lacnic
+200.96.0.0/13: Nicbr
+61.80.0.0/14: Nicor
+164.128.0.0/12: Ripe
+160.48.0.0/12: Ripe
+128.0.0.0/2: Arin
+141.84.0.0/15: Ripe
+210.62.252.0/22: Twnic
+203.224.0.0/11: Nicor
+77.0.0.0/8: Ripe
+120.0.0.0/6: Apnic
+88.0.0.0/6: Ripe
+188.0.0.0/8: Ripe
+202.13.0.0/16: Nicad
+78.0.0.0/7: Ripe
--- /dev/null
+---
+2001:4A00::/23: Ripe
+2001:4600::/23: Ripe
+2001:4200::/23: Afrinic
+2001:0200::/23: Apnic
+2400:0000::/12: Apnic
+2001:1C00::/22: Ripe
+2001:8000::/18: Apnic
+2001:1800::/23: Arin
+2001:0600::/23: Ripe
+3FFE:0000::/16: Ipv6Bone
+2001:5000::/20: Ripe
+2001:1A00::/23: Ripe
+2001:0C00::/22: Apnic
+2001:0800::/22: Ripe
+2800:0000::/12: Lacnic
+2620:0000::/23: Arin
+2001:0400::/23: Arin
+2C00:0000::/12: Afrinic
+2610:0000::/23: Arin
+2003:0000::/18: Ripe
+2001:4000::/23: Ripe
+2600:0000::/12: Arin
+2002:0000::/16: Ipv6ToIpv4
+2001:2000::/19: Ripe
+2001:0000::/32: Teredo
+2A00:0000::/12: Ripe
+2001:4C00::/22: Ripe
+2400:0000::/20: Kornet
+2001:4800::/23: Arin
+2001:4400::/23: Apnic
+2001:1400::/22: Ripe
+2001:1000::/22: Lacnic
--- /dev/null
+module Server
+
+ # Define if the module has or not the Class in this module
+ def self.class_exist? str
+ begin
+ self.class_eval str.to_s
+ return true
+ rescue NameError
+ return false
+ end
+ end
+
+ # Class For define a model of Server
+ class Server
+ attr_reader :server
+ end
+
+ # Class for the server Afrinic
+ class Afrinic < Server
+
+ def initialize
+ @server = 'whois.afrinic.net'
+ end
+ end
+
+ # Class for the Server Apnic
+ class Apnic < Server
+
+ def initialize
+ @server = 'whois.apnic.net'
+ end
+ end
+
+ # Class for the Server Ripe
+ class Ripe < Server
+ def initialize
+ @server = 'whois.ripe.net'
+ end
+ end
+
+ # Class for the Server Arin
+ class Arin < Server
+ def initialize
+ @server = 'whois.arin.net'
+ end
+ end
+
+ # Class for the Server Lacnic
+ class Lacnic < Server
+ def initialize
+ @server = 'whois.lacnic.net'
+ end
+ end
+
+ # Class for Server whois.nic.or.kr
+ class Nicor < Server
+ def initialize
+ @server = 'whois.nic.or.kr'
+ end
+ end
+
+ # Class for Server whois.nic.ad.jp
+ class Nicad < Server
+ def initialize
+ @server = 'whois.nic.ad.jp'
+ end
+ end
+
+ # Class for Server whois.nic.br
+ class Nicbr < Server
+ def initialize
+ @server = 'whois.nic.br'
+ end
+ end
+
+ # Class for the teredo RFC 4773
+ class Teredo < Server
+ def initialize
+ @server = nil
+ end
+ end
+
+ # Class for 6To4 RFC 3056
+ class Ipv6ToIpv4 < Server
+ def initialize
+ @server = nil
+ end
+ end
+
+ # Class for server whois.kornet.net
+ class Kornet < Server
+ def initialize
+ @server = 'whois.kornet.net'
+ end
+ end
+
+ # Class for server whois.v6nic.net
+ class V6nic < Server
+ def initialize
+ @server = 'whois.v6nic.net'
+ end
+ end
+
+ # Class for server whois.twnic.net
+ class Twnic < Server
+ def initialize
+ @server = 'whois.twnic.net'
+ end
+ end
+
+ # Class for server whois.verio.net
+ class Verio < Server
+ def initialize
+ @server = 'whois.verio.net'
+ end
+ end
+
+ # Class for server whois.6bone.net
+ class Ipv6Bone < Server
+ def initialize
+ @server = 'whois.6bone.net'
+ end
+ end
+
+ class Ginntt < Server
+ def initialize
+ @server = 'rwhois.gin.ntt.net'
+ end
+ end
+
+end
--- /dev/null
+#!/usr/bin/ruby -w
+
+require 'socket'
+require 'resolv'
+require 'ipaddr'
+require 'yaml'
+require File.dirname(__FILE__) + '/server/server'
+
+# Module for manage all Whois Class
+module Whois
+
+ # Base exception of Whois
+ class WhoisException < Exception
+ end
+
+ # Exception of Whois who made report a bug
+ class WhoisExceptionError < WhoisException
+ def initialize (i)
+ WhoisException.initialize('Report a bug with error #{i} to http://rubyforge.org/projects/whois/')
+ end
+ end
+
+ # Class to get all information about Host or IP with the Whois request
+ class Whois
+
+ Version = '0.4.0'
+
+ attr_reader :all
+ attr_reader :server
+ attr_reader :ip
+ attr_reader :host
+ attr_accessor :host_search
+
+ # Initialize with a request. The request must be an IPv4, or a host string
+ #
+ # The first params now is :
+ # * a string which a Ipv4, Ipv6 or a host.
+ # * A IPAddr instance
+ #
+ # A second param, host_search is optionnal. By default he is false.
+ # If this value is true, a resolv host is made for know the host to this IPv4
+ def initialize(request, host_search=false)
+ @host_search = host_search
+ @host = nil
+ if request.instance_of? IPAddr
+ if request.ipv4?
+ @ip = request
+ @server = server_ipv4
+ elsif request.ipv6?
+ @ip = request
+ @server = server_ipv6
+ else
+ raise WhoisExceptionError.new(1)
+ end
+ elsif Resolv::IPv4::Regex =~ request
+ ipv4_init request
+ unless self.server
+ raise WhoisException.new("no server found for this IPv4 : #{request}")
+ end
+ elsif Resolv::IPv6::Regex =~ request
+ ipv6_init request
+ unless self.server
+ raise WhoisException.new("no server found for this Ipv6 : #{request}")
+ end
+ else
+ # Test if the request is an host or not
+ begin
+ ip = Resolv.getaddress request
+ @ip = IPAddr.new ip
+ @server = server_ipv4
+ @host = request
+ rescue Resolv::ResolvError
+ raise WhoisException.new('host #{request} has no DNS result')
+ end
+ end
+
+ search_host unless @host
+ end
+
+ # Ask of whois server
+ def search_whois
+ s = TCPsocket.open(self.server.server, 43)
+ s.write("#{self.ip.to_s}\n")
+ ret = ''
+ while s.gets do ret += $_ end
+ s.close
+ @all = ret
+ end
+
+
+ # Search the host for this IPv4, if the value host_search is true, else host = nil
+ def search_host
+ begin
+ if @host_search
+ @host = Resolv.getname self.ip.to_s
+ else
+ @host = nil
+ end
+ rescue Resolv::ResolvError
+ @host = nil
+ end
+ end
+
+ private
+
+ # Init value for a ipv4 request
+ def ipv4_init (ip)
+ @ip = IPAddr.new ip
+ @server = server_ipv4
+ end
+
+ # Init value for a ipv6 request
+ def ipv6_init (ip)
+ @ip = IPAddr.new ip
+ @server = server_ipv6
+ end
+
+ # Return the Server with the hash of mask
+ def server_with_hash(ip_hash)
+ # Sort by mask of Ip Range
+ arr_tmp = ip_hash.sort{|b,c| c[0][/\/(.+)/, 1].to_i <=> b[0][/\/(.+)/, 1].to_i}
+ arr_tmp.each do |l|
+ ip_range = IPAddr.new l[0]
+ if ip_range.include? self.ip
+ return Object.instance_eval("Server::#{l[1]}.new")
+ end
+ end
+ end
+
+ # Define the server of Whois in IPC6 list of YAML
+ def server_ipv6
+ ipv6_list = YAML::load_file(File.dirname(__FILE__) + '/data/ipv6.yaml')
+ server = server_with_hash(ipv6_list)
+ unless server.kind_of? Server::Server
+ raise WhoisException.new("no server found for this IPv6 : #{self.ip}")
+ else
+ return server
+ end
+ end
+
+ # Define the server of Whois in IPV4 list of YAML
+ def server_ipv4
+ ipv4_list = YAML::load_file(File.dirname(__FILE__) + '/data/ipv4.yaml')
+ server = server_with_hash(ipv4_list)
+ unless server.kind_of? Server::Server
+ raise WhoisException.new("no server found for this IPv4 : #{self.ip}")
+ else
+ return server
+ end
+ end
+ end
+end
+
+
+if $0 == __FILE__
+ w = Whois::Whois.new '218.14.221.147'
+ puts w.search_whois
+end