Add support for GeoIP lookups using Quova.
authorTom Hughes <tom@compton.nu>
Wed, 25 Nov 2009 00:52:44 +0000 (00:52 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 25 Nov 2009 00:52:44 +0000 (00:52 +0000)
config/application.yml
config/environment.rb
lib/osm.rb
lib/quova.rb [new file with mode: 0644]

index d4a8537e8185fc95b4ff412e7fb66c091b66b001..363cc6398286467dcb907def552bc04d20f4d86d 100644 (file)
@@ -19,6 +19,9 @@ standard_settings: &standard_settings
   max_messages_per_hour: 60
   # Domain for handling message replies
   #messages_domain: "messages.openstreetmap.org"
+  # Quova authentication details
+  #quova_username: ""
+  #quova_password: ""
  
 development:
   <<: *standard_settings
index 12a8b542404319b3e56a6da7ba62f9e164d947bf..83bfbbf2a40ec8a4f7539ea57b7c4f8676505bff 100644 (file)
@@ -52,6 +52,7 @@ Rails::Initializer.run do |config|
   # note: this should be changed to 0.3.6 as soon as it's released, as this has fixes for
   # uploading multipart documents.
   config.gem 'oauth', :version => '>=0.2.1'
+  config.gem 'httpclient'
 
   # Only load the plugins named here, in the order given. By default, all plugins 
   # in vendor/plugins are loaded in alphabetical order.
index 554ebfaef7a6cb6e06d13710272fb9380b1a95b5..cb23b0c97eb6b0bda038e7dfbdb403b08898503f 100644 (file)
@@ -448,12 +448,20 @@ module OSM
 
   def self.IPLocation(ip_address)
     Timeout::timeout(4) do
-      Net::HTTP.start('api.hostip.info') do |http|
-        country = http.get("/country.php?ip=#{ip_address}").body
-        country = "GB" if country == "UK"
-        country = Country.find_by_code(country)
-        return { :minlon => country.min_lon, :minlat => country.min_lat, :maxlon => country.max_lon, :maxlat => country.max_lat }
+      ipinfo = Quova::IpInfo.new(ip_address)
+
+      if ipinfo.status == Quova::Success then
+        country = ipinfo.country_code
+      else
+        Net::HTTP.start('api.hostip.info') do |http|
+          country = http.get("/country.php?ip=#{ip_address}").body
+          country = "GB" if country == "UK"
+        end
       end
+
+      country = Country.find_by_code(country.upcase)
+
+      return { :minlon => country.min_lon, :minlat => country.min_lat, :maxlon => country.max_lon, :maxlat => country.max_lat }
     end
 
     return nil
diff --git a/lib/quova.rb b/lib/quova.rb
new file mode 100644 (file)
index 0000000..a7318d6
--- /dev/null
@@ -0,0 +1,66 @@
+##
+# Load required libraries
+require 'soap/wsdlDriver'
+
+##
+# Monkey patch WSDL parser to stop it moaning
+module WSDL
+  class Parser
+    def warn(msg)
+    end
+  end
+end
+
+##
+# Provide interface to Quova geolocation service
+module Quova
+  ##
+  # Access details for WSDL description
+  WSDL_URL="https://webservices.quova.com/OnDemand/GeoPoint/v1/default.asmx?WSDL"
+  WSDL_USER = APP_CONFIG['quova_username']
+  WSDL_PASS = APP_CONFIG['quova_password']
+
+  ##
+  # Status codes
+  Success = 0
+  IPV6NoSupport = 1
+  InvalidCredentials = 2
+  NotMapped = 3
+  InvalidIPFormat = 4
+  IPAddressNull = 5
+  AccessDenied = 6
+  QueryLimit = 7
+  OutOfService = 10
+
+  ##
+  # Create SOAP endpoint
+  @@soap = SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driver
+  @@soap.options["protocol.http.basic_auth"] << [WSDL_URL, WSDL_USER, WSDL_PASS]
+
+  ##
+  # Accessor for SOAP endpoint
+  def self.soap
+    @@soap
+  end
+
+  ##
+  # Class representing geolocation details for an IP address
+  class IpInfo
+    def initialize(ip_address)
+      @ipinfo = Quova::soap.GetIpInfo(:ipAddress => ip_address)
+    end
+
+    def status
+      @ipinfo["GetIpInfoResult"]["Response"]["Status"].to_i
+    end
+    def country_code
+      @ipinfo["GetIpInfoResult"]["Location"]["Country"]["Name"]
+    end
+
+    def country_confidence
+      @ipinfo["GetIpInfoResult"]["Location"]["Country"]["Confidence"]
+    end
+  end
+end
+