diff --git a/README.md b/README.md index f651dc80a07b76adc2f7a9d2c1fd9c121a0374e1..3fcd7606354ef9799f2a92f26b9be1d92d67514f 100644 --- a/README.md +++ b/README.md @@ -372,7 +372,7 @@ Please see the [source code for each lookup](https://github.com/alexreisner/geoc Or, to search within a particular region with Google: Geocoder.search("...", :params => {:region => "..."}) - + Or, to use parameters in your model: class Venue @@ -382,7 +382,7 @@ Or, to use parameters in your model: # store the fetched address in the full_address attribute reverse_geocoded_by :latitude, :longitude, :address => :full_address, :params => {:region => "..."} - end + end ### Configure Multiple Services @@ -852,6 +852,16 @@ This uses the PostcodeAnywhere UK Geocode service, this will geocode any string * **Documentation**: http://ip-api.com/docs/ * **Terms of Service**: https://signup.ip-api.com/terms +#### DB-IP.com (`:db_ip_com`) + +* **API key**: required +* **Quota**: 2,500/day (with free API Key, 50,000/day and up for paid API keys) +* **Region**: world +* **SSL support**: yes (with paid API keys - see https://db-ip.com/api/) +* **Languages**: English (English with free API key, multiple languages with paid API keys) +* **Documentation**: https://db-ip.com/api/doc.php +* **Terms of Service**: https://db-ip.com/tos.php + ### IP Address Local Database Services #### MaxMind Local (`:maxmind_local`) - EXPERIMENTAL diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb index bc0882652a4ae0e62c97baeeb4954c915c07921e..2d71041905c289b5990bfe0b3fa4b4b335a3d28a 100644 --- a/lib/geocoder/lookup.rb +++ b/lib/geocoder/lookup.rb @@ -70,7 +70,8 @@ module Geocoder :pointpin, :maxmind_geoip2, :ipinfo_io, - :ipapi_com + :ipapi_com, + :db_ip_com ] end diff --git a/lib/geocoder/lookups/db_ip_com.rb b/lib/geocoder/lookups/db_ip_com.rb new file mode 100644 index 0000000000000000000000000000000000000000..8a03215757ead93bba3a68e1e49877fc47162189 --- /dev/null +++ b/lib/geocoder/lookups/db_ip_com.rb @@ -0,0 +1,45 @@ +require 'geocoder/lookups/base' +require 'geocoder/results/db_ip_com' + +module Geocoder::Lookup + class DbIpCom < Base + + def name + 'DB-IP.com' + end + + def supported_protocols + [:https, :http] + end + + def required_api_key_parts + ['api_key'] + end + + def query_url(query) + query_params = if query.options[:params] + "?#{url_query_string(query)}" + end + + "#{protocol}://api.db-ip.com/v2/#{configuration.api_key}/#{query.sanitized_text}#{query_params}" + end + + private + + def results(query) + return [] unless doc = fetch_data(query) + + if doc['error'] + if doc['error'] == 'invalid API key' + raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, 'Invalid DB-IP API key.') + else + Geocoder.log(:warn, "DB-IP Geocoding API error: #{doc['error']}.") + end + + return [] + else + return [ doc ] + end + end + end +end diff --git a/lib/geocoder/results/db_ip_com.rb b/lib/geocoder/results/db_ip_com.rb new file mode 100644 index 0000000000000000000000000000000000000000..2328bd0dd9b2d1dc69029f134557744900ffc9cc --- /dev/null +++ b/lib/geocoder/results/db_ip_com.rb @@ -0,0 +1,63 @@ +require 'geocoder/results/base' + +module Geocoder::Result + class DbIpCom < Base + + def coordinates + ['latitude', 'longitude'].map{ |coordinate_name| @data[coordinate_name] } + end + + def address(format = :full) + s = state_code.to_s == "" ? "" : ", #{state_code}" + "#{city}#{s} #{zip_code}, #{country_name}".sub(/^[ ,]*/, "") + end + + def city + @data['city'] + end + + def district + @data['district'] + end + + def state_code + @data['stateProv'] + end + alias_method :state, :state_code + + def zip_code + @data['zipCode'] + end + alias_method :postal_code, :zip_code + + def country_name + @data['countryName'] + end + alias_method :country, :country_name + + def country_code + @data['countryCode'] + end + + def continent_name + @data['continentName'] + end + alias_method :continent, :continent_name + + def continent_code + @data['continentCode'] + end + + def time_zone + @data['timeZone'] + end + + def gmt_offset + @data['gmtOffset'] + end + + def currency_code + @data['currencyCode'] + end + end +end diff --git a/test/fixtures/db_ip_com_23_255_240_0 b/test/fixtures/db_ip_com_23_255_240_0 new file mode 100644 index 0000000000000000000000000000000000000000..035da4234b2890b73c7e307c7cc73ed1fc8c4a1e --- /dev/null +++ b/test/fixtures/db_ip_com_23_255_240_0 @@ -0,0 +1,27 @@ +{ + "ipAddress": "23.255.240.0", + "continentCode": "NA", + "continentName": "North America", + "countryCode": "US", + "countryName": "United States", + "currencyCode": "USD", + "phonePrefix": "1", + "languages": [ + "en-US", + "es-US", + "haw", + "fr" + ], + "stateProv": "California", + "district": "Santa Clara County", + "city": "Mountain View", + "geonameId": 5375480, + "zipCode": "94043", + "latitude": 37.3861, + "longitude": -122.084, + "gmtOffset": -7, + "timeZone": "America\/Los_Angeles", + "isp": "Google Fiber Inc.", + "linkType": "fttx", + "organization": "Google Fiber Inc." +} \ No newline at end of file diff --git a/test/fixtures/db_ip_com_invalid_key b/test/fixtures/db_ip_com_invalid_key new file mode 100644 index 0000000000000000000000000000000000000000..91cab5ee4f73a4ccd51b3d3a7f6528d37038ca6e --- /dev/null +++ b/test/fixtures/db_ip_com_invalid_key @@ -0,0 +1 @@ +{"error":"invalid API key"} \ No newline at end of file diff --git a/test/fixtures/db_ip_com_no_results b/test/fixtures/db_ip_com_no_results new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/test_helper.rb b/test/test_helper.rb index b51b77ea9053748a04a8cb7f6d84afcc557b06c3..55978055c8d8e55ce18fc692e4d933ad09f762c6 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -161,6 +161,14 @@ module Geocoder end end + require 'geocoder/lookups/db_ip_com' + class DbIpCom + private + def default_fixture_filename + "db_ip_com_23_255_240_0" + end + end + require 'geocoder/lookups/google_premier' class GooglePremier private diff --git a/test/unit/lookup_test.rb b/test/unit/lookup_test.rb index 4fa3a28daa49bb1e427f3e7e5548094f4201cb98..8dcaf8047fa61f1d239a10d50eae2c63a5ba0571 100644 --- a/test/unit/lookup_test.rb +++ b/test/unit/lookup_test.rb @@ -117,6 +117,12 @@ class LookupTest < GeocoderTestCase assert_match "ak=MY_KEY", g.query_url(Geocoder::Query.new("Madison Square Garden, New York, NY 10001, United States")) end + def test_db_ip_com_api_key + Geocoder.configure(:api_key => "MY_KEY") + g = Geocoder::Lookup::DbIpCom.new + assert_match "\/MY_KEY\/", g.query_url(Geocoder::Query.new("232.65.123.94")) + end + def test_pointpin_api_key Geocoder.configure(:api_key => "MY_KEY") g = Geocoder::Lookup::Pointpin.new diff --git a/test/unit/lookups/db_ip_com_test.rb b/test/unit/lookups/db_ip_com_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..47fc26e68f3b3207628979e143451edf56359fa0 --- /dev/null +++ b/test/unit/lookups/db_ip_com_test.rb @@ -0,0 +1,64 @@ +# encoding: utf-8 +require 'test_helper' + +class DbIpComTest < GeocoderTestCase + + def configure_for_free_api_access + Geocoder.configure(ip_lookup: :db_ip_com, db_ip_com: { api_key: 'MY_API_KEY' }) + set_api_key!(:db_ip_com) + end + + def configure_for_paid_api_access + Geocoder.configure(ip_lookup: :db_ip_com, db_ip_com: { api_key: 'MY_API_KEY', use_https: true }) + set_api_key!(:db_ip_com) + end + + def teardown + Geocoder::Configuration.instance.set_defaults + end + + def test_no_results + configure_for_free_api_access + results = Geocoder.search('no results') + assert_equal 0, results.length + end + + def test_result_on_ip_address_search + configure_for_free_api_access + result = Geocoder.search('23.255.240.0').first + assert result.is_a?(Geocoder::Result::DbIpCom) + end + + def test_result_components + configure_for_free_api_access + result = Geocoder.search('23.255.240.0').first + + assert_equal [37.3861, -122.084], result.coordinates + assert_equal 'Mountain View, California 94043, United States', result.address + assert_equal 'Mountain View', result.city + assert_equal 'Santa Clara County', result.district + assert_equal 'California', result.state_code + assert_equal '94043', result.zip_code + assert_equal 'United States', result.country_name + assert_equal 'US', result.country_code + assert_equal 'North America', result.continent_name + assert_equal 'NA', result.continent_code + assert_equal 'America/Los_Angeles', result.time_zone + assert_equal(-7, result.gmt_offset) + assert_equal 'USD', result.currency_code + end + + def test_free_host_config + configure_for_free_api_access + lookup = Geocoder::Lookup::DbIpCom.new + query = Geocoder::Query.new("23.255.240.0") + assert_match 'http://api.db-ip.com/v2/MY_API_KEY/23.255.240.0', lookup.query_url(query) + end + + def test_paid_host_config + configure_for_paid_api_access + lookup = Geocoder::Lookup::DbIpCom.new + query = Geocoder::Query.new("23.255.240.0") + assert_match 'https://api.db-ip.com/v2/MY_API_KEY/23.255.240.0', lookup.query_url(query) + end +end