really-broken-geocoder 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +557 -0
- data/LICENSE +20 -0
- data/README.md +3 -0
- data/bin/geocode +5 -0
- data/examples/autoexpire_cache_dalli.rb +62 -0
- data/examples/autoexpire_cache_redis.rb +28 -0
- data/examples/cache_bypass.rb +48 -0
- data/examples/reverse_geocode_job.rb +40 -0
- data/lib/generators/geocoder/config/config_generator.rb +14 -0
- data/lib/generators/geocoder/config/templates/initializer.rb +22 -0
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
- data/lib/generators/geocoder/migration_version.rb +15 -0
- data/lib/geocoder.rb +48 -0
- data/lib/geocoder/cache.rb +94 -0
- data/lib/geocoder/calculations.rb +420 -0
- data/lib/geocoder/cli.rb +121 -0
- data/lib/geocoder/configuration.rb +137 -0
- data/lib/geocoder/configuration_hash.rb +11 -0
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/exceptions.rb +40 -0
- data/lib/geocoder/ip_address.rb +26 -0
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +118 -0
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/baidu.rb +63 -0
- data/lib/geocoder/lookups/baidu_ip.rb +30 -0
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +130 -0
- data/lib/geocoder/lookups/base.rb +348 -0
- data/lib/geocoder/lookups/bing.rb +82 -0
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +22 -0
- data/lib/geocoder/lookups/esri.rb +95 -0
- data/lib/geocoder/lookups/freegeoip.rb +60 -0
- data/lib/geocoder/lookups/geocoder_ca.rb +53 -0
- data/lib/geocoder/lookups/geocoder_us.rb +51 -0
- data/lib/geocoder/lookups/geocodio.rb +42 -0
- data/lib/geocoder/lookups/geoip2.rb +45 -0
- data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/lib/geocoder/lookups/google.rb +95 -0
- data/lib/geocoder/lookups/google_places_details.rb +50 -0
- data/lib/geocoder/lookups/google_places_search.rb +33 -0
- data/lib/geocoder/lookups/google_premier.rb +57 -0
- data/lib/geocoder/lookups/here.rb +77 -0
- data/lib/geocoder/lookups/ip2location.rb +75 -0
- data/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +59 -0
- data/lib/geocoder/lookups/location_iq.rb +50 -0
- data/lib/geocoder/lookups/mapbox.rb +59 -0
- data/lib/geocoder/lookups/mapquest.rb +58 -0
- data/lib/geocoder/lookups/maxmind.rb +90 -0
- data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/lib/geocoder/lookups/maxmind_local.rb +65 -0
- data/lib/geocoder/lookups/nominatim.rb +64 -0
- data/lib/geocoder/lookups/opencagedata.rb +65 -0
- data/lib/geocoder/lookups/pelias.rb +63 -0
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +69 -0
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +63 -0
- data/lib/geocoder/lookups/telize.rb +75 -0
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/test.rb +44 -0
- data/lib/geocoder/lookups/yandex.rb +62 -0
- data/lib/geocoder/models/active_record.rb +51 -0
- data/lib/geocoder/models/base.rb +39 -0
- data/lib/geocoder/models/mongo_base.rb +62 -0
- data/lib/geocoder/models/mongo_mapper.rb +26 -0
- data/lib/geocoder/models/mongoid.rb +32 -0
- data/lib/geocoder/query.rb +125 -0
- data/lib/geocoder/railtie.rb +26 -0
- data/lib/geocoder/request.rb +114 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/baidu.rb +79 -0
- data/lib/geocoder/results/baidu_ip.rb +62 -0
- data/lib/geocoder/results/ban_data_gouv_fr.rb +257 -0
- data/lib/geocoder/results/base.rb +79 -0
- data/lib/geocoder/results/bing.rb +52 -0
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/dstk.rb +6 -0
- data/lib/geocoder/results/esri.rb +75 -0
- data/lib/geocoder/results/freegeoip.rb +40 -0
- data/lib/geocoder/results/geocoder_ca.rb +60 -0
- data/lib/geocoder/results/geocoder_us.rb +39 -0
- data/lib/geocoder/results/geocodio.rb +78 -0
- data/lib/geocoder/results/geoip2.rb +76 -0
- data/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/lib/geocoder/results/google.rb +150 -0
- data/lib/geocoder/results/google_places_details.rb +39 -0
- data/lib/geocoder/results/google_places_search.rb +52 -0
- data/lib/geocoder/results/google_premier.rb +6 -0
- data/lib/geocoder/results/here.rb +79 -0
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/latlon.rb +71 -0
- data/lib/geocoder/results/location_iq.rb +6 -0
- data/lib/geocoder/results/mapbox.rb +57 -0
- data/lib/geocoder/results/mapquest.rb +48 -0
- data/lib/geocoder/results/maxmind.rb +130 -0
- data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/lib/geocoder/results/maxmind_local.rb +44 -0
- data/lib/geocoder/results/nominatim.rb +109 -0
- data/lib/geocoder/results/opencagedata.rb +100 -0
- data/lib/geocoder/results/pelias.rb +58 -0
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/pointpin.rb +40 -0
- data/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +142 -0
- data/lib/geocoder/results/telize.rb +40 -0
- data/lib/geocoder/results/tencent.rb +72 -0
- data/lib/geocoder/results/test.rb +33 -0
- data/lib/geocoder/results/yandex.rb +134 -0
- data/lib/geocoder/sql.rb +110 -0
- data/lib/geocoder/stores/active_record.rb +328 -0
- data/lib/geocoder/stores/base.rb +115 -0
- data/lib/geocoder/stores/mongo_base.rb +58 -0
- data/lib/geocoder/stores/mongo_mapper.rb +13 -0
- data/lib/geocoder/stores/mongoid.rb +13 -0
- data/lib/geocoder/version.rb +3 -0
- data/lib/hash_recursive_merge.rb +74 -0
- data/lib/maxmind_database.rb +109 -0
- data/lib/tasks/geocoder.rake +54 -0
- data/lib/tasks/maxmind.rake +73 -0
- metadata +186 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/geoip2'
|
3
|
+
|
4
|
+
module Geocoder
|
5
|
+
module Lookup
|
6
|
+
class Geoip2 < Base
|
7
|
+
attr_reader :gem_name
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
unless configuration[:file].nil?
|
11
|
+
begin
|
12
|
+
@gem_name = configuration[:lib] || 'maxminddb'
|
13
|
+
require @gem_name
|
14
|
+
rescue LoadError
|
15
|
+
raise "Could not load Maxmind DB dependency. To use the GeoIP2 lookup you must add the #{@gem_name} gem to your Gemfile or have it installed in your system."
|
16
|
+
end
|
17
|
+
|
18
|
+
@mmdb = db_class.new(configuration[:file].to_s)
|
19
|
+
end
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def name
|
24
|
+
'GeoIP2'
|
25
|
+
end
|
26
|
+
|
27
|
+
def required_api_key_parts
|
28
|
+
[]
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def db_class
|
34
|
+
gem_name == 'hive_geoip2' ? Hive::GeoIP2 : MaxMindDB
|
35
|
+
end
|
36
|
+
|
37
|
+
def results(query)
|
38
|
+
return [] unless configuration[:file]
|
39
|
+
|
40
|
+
result = @mmdb.lookup(query.to_s)
|
41
|
+
result.nil? ? [] : [result]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require "geocoder/results/geoportail_lu"
|
3
|
+
|
4
|
+
module Geocoder
|
5
|
+
module Lookup
|
6
|
+
class GeoportailLu < Base
|
7
|
+
|
8
|
+
def name
|
9
|
+
"Geoportail.lu"
|
10
|
+
end
|
11
|
+
|
12
|
+
private # ---------------------------------------------------------------
|
13
|
+
|
14
|
+
def base_query_url(query)
|
15
|
+
if query.reverse_geocode?
|
16
|
+
reverse_geocode_url_base_path
|
17
|
+
else
|
18
|
+
search_url_base_path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def search_url_base_path
|
23
|
+
"#{protocol}://api.geoportail.lu/geocoder/search?"
|
24
|
+
end
|
25
|
+
|
26
|
+
def reverse_geocode_url_base_path
|
27
|
+
"#{protocol}://api.geoportail.lu/geocoder/reverseGeocode?"
|
28
|
+
end
|
29
|
+
|
30
|
+
def query_url_geoportail_lu_params(query)
|
31
|
+
query.reverse_geocode? ? reverse_geocode_params(query) : search_params(query)
|
32
|
+
end
|
33
|
+
|
34
|
+
def search_params(query)
|
35
|
+
{
|
36
|
+
queryString: query.sanitized_text
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def reverse_geocode_params(query)
|
41
|
+
lat_lon = query.coordinates
|
42
|
+
{
|
43
|
+
lat: lat_lon.first,
|
44
|
+
lon: lat_lon.last
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def query_url_params(query)
|
49
|
+
query_url_geoportail_lu_params(query).merge(super)
|
50
|
+
end
|
51
|
+
|
52
|
+
def results(query)
|
53
|
+
return [] unless doc = fetch_data(query)
|
54
|
+
if doc['success'] == true
|
55
|
+
result = doc['results']
|
56
|
+
else
|
57
|
+
result = []
|
58
|
+
raise_error(Geocoder::Error) ||
|
59
|
+
warn("Geportail.lu Geocoding API error")
|
60
|
+
end
|
61
|
+
result
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require "geocoder/results/google"
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Google < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"Google"
|
9
|
+
end
|
10
|
+
|
11
|
+
def map_link_url(coordinates)
|
12
|
+
"http://maps.google.com/maps?q=#{coordinates.join(',')}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def supported_protocols
|
16
|
+
# Google requires HTTPS if an API key is used.
|
17
|
+
if configuration.api_key
|
18
|
+
[:https]
|
19
|
+
else
|
20
|
+
[:http, :https]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private # ---------------------------------------------------------------
|
25
|
+
|
26
|
+
def base_query_url(query)
|
27
|
+
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?"
|
28
|
+
end
|
29
|
+
|
30
|
+
def configure_ssl!(client)
|
31
|
+
client.instance_eval {
|
32
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
33
|
+
options = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
|
34
|
+
if OpenSSL::SSL.const_defined?('OP_NO_COMPRESSION')
|
35
|
+
options |= OpenSSL::SSL::OP_NO_COMPRESSION
|
36
|
+
end
|
37
|
+
@ssl_context.set_params({options: options})
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def valid_response?(response)
|
42
|
+
json = parse_json(response.body)
|
43
|
+
status = json["status"] if json
|
44
|
+
super(response) and ['OK', 'ZERO_RESULTS'].include?(status)
|
45
|
+
end
|
46
|
+
|
47
|
+
def results(query)
|
48
|
+
return [] unless doc = fetch_data(query)
|
49
|
+
case doc['status']; when "OK" # OK status implies >0 results
|
50
|
+
return doc['results']
|
51
|
+
when "OVER_QUERY_LIMIT"
|
52
|
+
raise_error(Geocoder::OverQueryLimitError) ||
|
53
|
+
Geocoder.log(:warn, "#{name} API error: over query limit.")
|
54
|
+
when "REQUEST_DENIED"
|
55
|
+
raise_error(Geocoder::RequestDenied, doc['error_message']) ||
|
56
|
+
Geocoder.log(:warn, "#{name} API error: request denied (#{doc['error_message']}).")
|
57
|
+
when "INVALID_REQUEST"
|
58
|
+
raise_error(Geocoder::InvalidRequest, doc['error_message']) ||
|
59
|
+
Geocoder.log(:warn, "#{name} API error: invalid request (#{doc['error_message']}).")
|
60
|
+
end
|
61
|
+
return []
|
62
|
+
end
|
63
|
+
|
64
|
+
def query_url_google_params(query)
|
65
|
+
params = {
|
66
|
+
:sensor => "false",
|
67
|
+
:language => (query.language || configuration.language)
|
68
|
+
}
|
69
|
+
if query.options[:google_place_id]
|
70
|
+
params[:place_id] = query.sanitized_text
|
71
|
+
else
|
72
|
+
params[(query.reverse_geocode? ? :latlng : :address)] = query.sanitized_text
|
73
|
+
end
|
74
|
+
unless (bounds = query.options[:bounds]).nil?
|
75
|
+
params[:bounds] = bounds.map{ |point| "%f,%f" % point }.join('|')
|
76
|
+
end
|
77
|
+
unless (region = query.options[:region]).nil?
|
78
|
+
params[:region] = region
|
79
|
+
end
|
80
|
+
unless (components = query.options[:components]).nil?
|
81
|
+
params[:components] = components.is_a?(Array) ? components.join("|") : components
|
82
|
+
end
|
83
|
+
unless (result_type = query.options[:result_type]).nil?
|
84
|
+
params[:result_type] = result_type.is_a?(Array) ? result_type.join("|") : result_type
|
85
|
+
end
|
86
|
+
params
|
87
|
+
end
|
88
|
+
|
89
|
+
def query_url_params(query)
|
90
|
+
query_url_google_params(query).merge(
|
91
|
+
:key => configuration.api_key
|
92
|
+
).merge(super)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "geocoder/lookups/google"
|
2
|
+
require "geocoder/results/google_places_details"
|
3
|
+
|
4
|
+
module Geocoder
|
5
|
+
module Lookup
|
6
|
+
class GooglePlacesDetails < Google
|
7
|
+
def name
|
8
|
+
"Google Places Details"
|
9
|
+
end
|
10
|
+
|
11
|
+
def required_api_key_parts
|
12
|
+
["key"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def supported_protocols
|
16
|
+
[:https]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def base_query_url(query)
|
22
|
+
"#{protocol}://maps.googleapis.com/maps/api/place/details/json?"
|
23
|
+
end
|
24
|
+
|
25
|
+
def results(query)
|
26
|
+
return [] unless doc = fetch_data(query)
|
27
|
+
|
28
|
+
case doc["status"]
|
29
|
+
when "OK"
|
30
|
+
return [doc["result"]]
|
31
|
+
when "OVER_QUERY_LIMIT"
|
32
|
+
raise_error(Geocoder::OverQueryLimitError) || Geocoder.log(:warn, "Google Places Details API error: over query limit.")
|
33
|
+
when "REQUEST_DENIED"
|
34
|
+
raise_error(Geocoder::RequestDenied) || Geocoder.log(:warn, "Google Places Details API error: request denied.")
|
35
|
+
when "INVALID_REQUEST"
|
36
|
+
raise_error(Geocoder::InvalidRequest) || Geocoder.log(:warn, "Google Places Details API error: invalid request.")
|
37
|
+
end
|
38
|
+
|
39
|
+
[]
|
40
|
+
end
|
41
|
+
|
42
|
+
def query_url_google_params(query)
|
43
|
+
{
|
44
|
+
placeid: query.text,
|
45
|
+
language: query.language || configuration.language
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "geocoder/lookups/google"
|
2
|
+
require "geocoder/results/google_places_search"
|
3
|
+
|
4
|
+
module Geocoder
|
5
|
+
module Lookup
|
6
|
+
class GooglePlacesSearch < Google
|
7
|
+
def name
|
8
|
+
"Google Places Search"
|
9
|
+
end
|
10
|
+
|
11
|
+
def required_api_key_parts
|
12
|
+
["key"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def supported_protocols
|
16
|
+
[:https]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def base_query_url(query)
|
22
|
+
"#{protocol}://maps.googleapis.com/maps/api/place/textsearch/json?"
|
23
|
+
end
|
24
|
+
|
25
|
+
def query_url_google_params(query)
|
26
|
+
{
|
27
|
+
query: query.text,
|
28
|
+
language: query.language || configuration.language
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
require 'geocoder/lookups/google'
|
4
|
+
require 'geocoder/results/google_premier'
|
5
|
+
|
6
|
+
module Geocoder::Lookup
|
7
|
+
class GooglePremier < Google
|
8
|
+
|
9
|
+
def name
|
10
|
+
"Google Premier"
|
11
|
+
end
|
12
|
+
|
13
|
+
def required_api_key_parts
|
14
|
+
["private key"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def query_url(query)
|
18
|
+
path = "/maps/api/geocode/json?" + url_query_string(query)
|
19
|
+
"#{protocol}://maps.googleapis.com#{path}&signature=#{sign(path)}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private # ---------------------------------------------------------------
|
23
|
+
|
24
|
+
def cache_key(query)
|
25
|
+
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + hash_to_query(cache_key_params(query))
|
26
|
+
end
|
27
|
+
|
28
|
+
def cache_key_params(query)
|
29
|
+
query_url_google_params(query).merge(super).reject do |k,v|
|
30
|
+
[:key, :client, :channel].include?(k)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def query_url_params(query)
|
35
|
+
query_url_google_params(query).merge(super).merge(
|
36
|
+
:key => nil, # don't use param inherited from Google lookup
|
37
|
+
:client => configuration.api_key[1],
|
38
|
+
:channel => configuration.api_key[2]
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def sign(string)
|
43
|
+
raw_private_key = url_safe_base64_decode(configuration.api_key[0])
|
44
|
+
digest = OpenSSL::Digest.new('sha1')
|
45
|
+
raw_signature = OpenSSL::HMAC.digest(digest, raw_private_key, string)
|
46
|
+
url_safe_base64_encode(raw_signature)
|
47
|
+
end
|
48
|
+
|
49
|
+
def url_safe_base64_decode(base64_string)
|
50
|
+
Base64.decode64(base64_string.tr('-_', '+/'))
|
51
|
+
end
|
52
|
+
|
53
|
+
def url_safe_base64_encode(raw)
|
54
|
+
Base64.encode64(raw).tr('+/', '-_').strip
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/here'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Here < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"Here"
|
9
|
+
end
|
10
|
+
|
11
|
+
def required_api_key_parts
|
12
|
+
["app_id", "app_code"]
|
13
|
+
end
|
14
|
+
|
15
|
+
private # ---------------------------------------------------------------
|
16
|
+
|
17
|
+
def base_query_url(query)
|
18
|
+
"#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.api.here.com/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?"
|
19
|
+
end
|
20
|
+
|
21
|
+
def results(query)
|
22
|
+
return [] unless doc = fetch_data(query)
|
23
|
+
return [] unless doc['Response'] && doc['Response']['View']
|
24
|
+
if r=doc['Response']['View']
|
25
|
+
return [] if r.nil? || !r.is_a?(Array) || r.empty?
|
26
|
+
return r.first['Result']
|
27
|
+
end
|
28
|
+
[]
|
29
|
+
end
|
30
|
+
|
31
|
+
def query_url_here_options(query, reverse_geocode)
|
32
|
+
options = {
|
33
|
+
gen: 9,
|
34
|
+
app_id: api_key,
|
35
|
+
app_code: api_code,
|
36
|
+
language: (query.language || configuration.language)
|
37
|
+
}
|
38
|
+
if reverse_geocode
|
39
|
+
options[:mode] = :retrieveAddresses
|
40
|
+
return options
|
41
|
+
end
|
42
|
+
|
43
|
+
unless (country = query.options[:country]).nil?
|
44
|
+
options[:country] = country
|
45
|
+
end
|
46
|
+
|
47
|
+
unless (mapview = query.options[:bounds]).nil?
|
48
|
+
options[:mapview] = mapview.map{ |point| "%f,%f" % point }.join(';')
|
49
|
+
end
|
50
|
+
options
|
51
|
+
end
|
52
|
+
|
53
|
+
def query_url_params(query)
|
54
|
+
if query.reverse_geocode?
|
55
|
+
super.merge(query_url_here_options(query, true)).merge(
|
56
|
+
prox: query.sanitized_text
|
57
|
+
)
|
58
|
+
else
|
59
|
+
super.merge(query_url_here_options(query, false)).merge(
|
60
|
+
searchtext: query.sanitized_text
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def api_key
|
66
|
+
if (a = configuration.api_key)
|
67
|
+
return a.first if a.is_a?(Array)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def api_code
|
72
|
+
if (a = configuration.api_key)
|
73
|
+
return a.last if a.is_a?(Array)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/ip2location'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Ip2location < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
"IP2LocationApi"
|
9
|
+
end
|
10
|
+
|
11
|
+
def supported_protocols
|
12
|
+
[:http, :https]
|
13
|
+
end
|
14
|
+
|
15
|
+
private # ----------------------------------------------------------------
|
16
|
+
|
17
|
+
def base_query_url(query)
|
18
|
+
"#{protocol}://api.ip2location.com/?"
|
19
|
+
end
|
20
|
+
|
21
|
+
def query_url_params(query)
|
22
|
+
{
|
23
|
+
key: configuration.api_key ? configuration.api_key : "demo",
|
24
|
+
format: "json",
|
25
|
+
ip: query.sanitized_text
|
26
|
+
}.merge(super)
|
27
|
+
end
|
28
|
+
|
29
|
+
def results(query)
|
30
|
+
# don't look up a loopback or private address, just return the stored result
|
31
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
32
|
+
return [] unless doc = fetch_data(query)
|
33
|
+
if doc["response"] == "INVALID ACCOUNT"
|
34
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "INVALID ACCOUNT")
|
35
|
+
return []
|
36
|
+
else
|
37
|
+
return [doc]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def reserved_result(query)
|
42
|
+
{
|
43
|
+
"country_code" => "INVALID IP ADDRESS",
|
44
|
+
"country_name" => "INVALID IP ADDRESS",
|
45
|
+
"region_name" => "INVALID IP ADDRESS",
|
46
|
+
"city_name" => "INVALID IP ADDRESS",
|
47
|
+
"latitude" => "INVALID IP ADDRESS",
|
48
|
+
"longitude" => "INVALID IP ADDRESS",
|
49
|
+
"zip_code" => "INVALID IP ADDRESS",
|
50
|
+
"time_zone" => "INVALID IP ADDRESS",
|
51
|
+
"isp" => "INVALID IP ADDRESS",
|
52
|
+
"domain" => "INVALID IP ADDRESS",
|
53
|
+
"net_speed" => "INVALID IP ADDRESS",
|
54
|
+
"idd_code" => "INVALID IP ADDRESS",
|
55
|
+
"area_code" => "INVALID IP ADDRESS",
|
56
|
+
"weather_station_code" => "INVALID IP ADDRESS",
|
57
|
+
"weather_station_name" => "INVALID IP ADDRESS",
|
58
|
+
"mcc" => "INVALID IP ADDRESS",
|
59
|
+
"mnc" => "INVALID IP ADDRESS",
|
60
|
+
"mobile_brand" => "INVALID IP ADDRESS",
|
61
|
+
"elevation" => "INVALID IP ADDRESS",
|
62
|
+
"usage_type" => "INVALID IP ADDRESS"
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def query_url_params(query)
|
67
|
+
params = super
|
68
|
+
if configuration.has_key?(:package)
|
69
|
+
params.merge!(package: configuration[:package])
|
70
|
+
end
|
71
|
+
params
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|