mini-safe-gem 0.0.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/geocoder-1.8.6/CHANGELOG.md +669 -0
- data/geocoder-1.8.6/LICENSE +20 -0
- data/geocoder-1.8.6/README.md +827 -0
- data/geocoder-1.8.6/bin/console +13 -0
- data/geocoder-1.8.6/bin/geocode +5 -0
- data/geocoder-1.8.6/examples/app_defined_lookup_services.rb +22 -0
- data/geocoder-1.8.6/examples/cache_bypass.rb +48 -0
- data/geocoder-1.8.6/examples/reverse_geocode_job.rb +40 -0
- data/geocoder-1.8.6/lib/easting_northing.rb +319 -0
- data/geocoder-1.8.6/lib/generators/geocoder/config/config_generator.rb +14 -0
- data/geocoder-1.8.6/lib/generators/geocoder/config/templates/initializer.rb +27 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
- data/geocoder-1.8.6/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
- data/geocoder-1.8.6/lib/generators/geocoder/migration_version.rb +15 -0
- data/geocoder-1.8.6/lib/geocoder/cache.rb +77 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/base.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/generic.rb +35 -0
- data/geocoder-1.8.6/lib/geocoder/cache_stores/redis.rb +34 -0
- data/geocoder-1.8.6/lib/geocoder/calculations.rb +420 -0
- data/geocoder-1.8.6/lib/geocoder/cli.rb +121 -0
- data/geocoder-1.8.6/lib/geocoder/configuration.rb +151 -0
- data/geocoder-1.8.6/lib/geocoder/configuration_hash.rb +11 -0
- data/geocoder-1.8.6/lib/geocoder/esri_token.rb +38 -0
- data/geocoder-1.8.6/lib/geocoder/exceptions.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/ip_address.rb +36 -0
- data/geocoder-1.8.6/lib/geocoder/kernel_logger.rb +25 -0
- data/geocoder-1.8.6/lib/geocoder/logger.rb +47 -0
- data/geocoder-1.8.6/lib/geocoder/lookup.rb +155 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/abstract_api.rb +46 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/amap.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/amazon_location_service.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/azure.rb +56 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/baidu.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/baidu_ip.rb +30 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/base.rb +351 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/bing.rb +82 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/esri.rb +114 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/freegeoip.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoapify.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geocoder_ca.rb +53 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geocodio.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoip2.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google.rb +100 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_places_details.rb +64 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_places_search.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/google_premier.rb +61 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/here.rb +73 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location_io.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ip2location_lite.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipbase.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipinfo_io_lite.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipqualityscore.rb +50 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/ipstack.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/latlon.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/location_iq.rb +54 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/mapbox.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/mapquest.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind.rb +90 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/maxmind_local.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/melissa_street.rb +41 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/nominatim.rb +64 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/opencagedata.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/osmnames.rb +57 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pc_miler.rb +87 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pdok_nl.rb +43 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pelias.rb +63 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/photon.rb +89 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/pointpin.rb +69 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/smarty_streets.rb +68 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/telize.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/tencent.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/test.rb +49 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/twogis.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/lookups/yandex.rb +61 -0
- data/geocoder-1.8.6/lib/geocoder/models/active_record.rb +51 -0
- data/geocoder-1.8.6/lib/geocoder/models/base.rb +39 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongo_base.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongo_mapper.rb +26 -0
- data/geocoder-1.8.6/lib/geocoder/models/mongoid.rb +32 -0
- data/geocoder-1.8.6/lib/geocoder/query.rb +125 -0
- data/geocoder-1.8.6/lib/geocoder/railtie.rb +26 -0
- data/geocoder-1.8.6/lib/geocoder/request.rb +114 -0
- data/geocoder-1.8.6/lib/geocoder/results/abstract_api.rb +146 -0
- data/geocoder-1.8.6/lib/geocoder/results/amap.rb +87 -0
- data/geocoder-1.8.6/lib/geocoder/results/amazon_location_service.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/azure.rb +65 -0
- data/geocoder-1.8.6/lib/geocoder/results/baidu.rb +75 -0
- data/geocoder-1.8.6/lib/geocoder/results/baidu_ip.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/ban_data_gouv_fr.rb +282 -0
- data/geocoder-1.8.6/lib/geocoder/results/base.rb +79 -0
- data/geocoder-1.8.6/lib/geocoder/results/bing.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/results/db_ip_com.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/results/esri.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/results/freegeoip.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoapify.rb +179 -0
- data/geocoder-1.8.6/lib/geocoder/results/geocoder_ca.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/results/geocodio.rb +78 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoip2.rb +76 -0
- data/geocoder-1.8.6/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/results/google.rb +150 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_places_details.rb +39 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_places_search.rb +52 -0
- data/geocoder-1.8.6/lib/geocoder/results/google_premier.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/here.rb +77 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location.rb +22 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location_io.rb +21 -0
- data/geocoder-1.8.6/lib/geocoder/results/ip2location_lite.rb +47 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipapi_com.rb +45 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipbase.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipdata_co.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipinfo_io_lite.rb +16 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipqualityscore.rb +54 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipregistry.rb +304 -0
- data/geocoder-1.8.6/lib/geocoder/results/ipstack.rb +60 -0
- data/geocoder-1.8.6/lib/geocoder/results/latlon.rb +71 -0
- data/geocoder-1.8.6/lib/geocoder/results/location_iq.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/mapbox.rb +80 -0
- data/geocoder-1.8.6/lib/geocoder/results/mapquest.rb +48 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind.rb +130 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/geocoder-1.8.6/lib/geocoder/results/maxmind_local.rb +44 -0
- data/geocoder-1.8.6/lib/geocoder/results/melissa_street.rb +46 -0
- data/geocoder-1.8.6/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/nominatim.rb +121 -0
- data/geocoder-1.8.6/lib/geocoder/results/opencagedata.rb +100 -0
- data/geocoder-1.8.6/lib/geocoder/results/osmnames.rb +56 -0
- data/geocoder-1.8.6/lib/geocoder/results/pc_miler.rb +98 -0
- data/geocoder-1.8.6/lib/geocoder/results/pdok_nl.rb +62 -0
- data/geocoder-1.8.6/lib/geocoder/results/pelias.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/results/photon.rb +119 -0
- data/geocoder-1.8.6/lib/geocoder/results/pickpoint.rb +6 -0
- data/geocoder-1.8.6/lib/geocoder/results/pointpin.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
- data/geocoder-1.8.6/lib/geocoder/results/postcodes_io.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/smarty_streets.rb +142 -0
- data/geocoder-1.8.6/lib/geocoder/results/telize.rb +40 -0
- data/geocoder-1.8.6/lib/geocoder/results/tencent.rb +72 -0
- data/geocoder-1.8.6/lib/geocoder/results/test.rb +33 -0
- data/geocoder-1.8.6/lib/geocoder/results/twogis.rb +76 -0
- data/geocoder-1.8.6/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/geocoder-1.8.6/lib/geocoder/results/yandex.rb +292 -0
- data/geocoder-1.8.6/lib/geocoder/sql.rb +110 -0
- data/geocoder-1.8.6/lib/geocoder/stores/active_record.rb +329 -0
- data/geocoder-1.8.6/lib/geocoder/stores/base.rb +115 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongo_base.rb +58 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongo_mapper.rb +13 -0
- data/geocoder-1.8.6/lib/geocoder/stores/mongoid.rb +13 -0
- data/geocoder-1.8.6/lib/geocoder/util.rb +29 -0
- data/geocoder-1.8.6/lib/geocoder/version.rb +3 -0
- data/geocoder-1.8.6/lib/geocoder.rb +48 -0
- data/geocoder-1.8.6/lib/maxmind_database.rb +109 -0
- data/geocoder-1.8.6/lib/tasks/geocoder.rake +54 -0
- data/geocoder-1.8.6/lib/tasks/maxmind.rake +73 -0
- data/mini-safe-gem.gemspec +12 -0
- metadata +214 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require 'geocoder'
|
|
2
|
+
require 'optparse'
|
|
3
|
+
|
|
4
|
+
module Geocoder
|
|
5
|
+
class Cli
|
|
6
|
+
|
|
7
|
+
def self.run(args, out = STDOUT)
|
|
8
|
+
show_url = false
|
|
9
|
+
show_json = false
|
|
10
|
+
|
|
11
|
+
# remove arguments that are probably coordinates so they are not
|
|
12
|
+
# processed as arguments (eg: -31.96047031,115.84274631)
|
|
13
|
+
coords = args.select{ |i| i.match(/^-\d/) }
|
|
14
|
+
args -= coords
|
|
15
|
+
|
|
16
|
+
OptionParser.new{ |opts|
|
|
17
|
+
opts.banner = "Usage:\n geocode [options] <location>"
|
|
18
|
+
opts.separator "\nOptions: "
|
|
19
|
+
|
|
20
|
+
opts.on("-k <key>", "--key <key>",
|
|
21
|
+
"Key for geocoding API (usually optional). Enclose multi-part keys in quotes and separate parts by spaces") do |key|
|
|
22
|
+
if (key_parts = key.split(/\s+/)).size > 1
|
|
23
|
+
Geocoder.configure(:api_key => key_parts)
|
|
24
|
+
else
|
|
25
|
+
Geocoder.configure(:api_key => key)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
opts.on("-l <language>", "--language <language>",
|
|
30
|
+
"Language of output (see API docs for valid choices)") do |language|
|
|
31
|
+
Geocoder.configure(:language => language)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
opts.on("-p <proxy>", "--proxy <proxy>",
|
|
35
|
+
"HTTP proxy server to use (user:pass@host:port)") do |proxy|
|
|
36
|
+
Geocoder.configure(:http_proxy => proxy)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
opts.on("-s <service>", Geocoder::Lookup.all_services_except_test, "--service <service>",
|
|
40
|
+
"Geocoding service: #{Geocoder::Lookup.all_services_except_test * ', '}") do |service|
|
|
41
|
+
Geocoder.configure(:lookup => service.to_sym)
|
|
42
|
+
Geocoder.configure(:ip_lookup => service.to_sym)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
opts.on("-t <seconds>", "--timeout <seconds>",
|
|
46
|
+
"Maximum number of seconds to wait for API response") do |timeout|
|
|
47
|
+
Geocoder.configure(:timeout => timeout.to_i)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
opts.on("-j", "--json", "Print API's raw JSON response") do
|
|
51
|
+
show_json = true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
opts.on("-u", "--url", "Print URL for API query instead of result") do
|
|
55
|
+
show_url = true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
opts.on_tail("-v", "--version", "Print version number") do
|
|
59
|
+
require "geocoder/version"
|
|
60
|
+
out << "Geocoder #{Geocoder::VERSION}\n"
|
|
61
|
+
exit
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
opts.on_tail("-h", "--help", "Print this help") do
|
|
65
|
+
out << "Look up geographic information about a location.\n\n"
|
|
66
|
+
out << opts
|
|
67
|
+
out << "\nCreated and maintained by Alex Reisner, available under the MIT License.\n"
|
|
68
|
+
out << "Report bugs and contribute at http://github.com/alexreisner/geocoder\n"
|
|
69
|
+
exit
|
|
70
|
+
end
|
|
71
|
+
}.parse!(args)
|
|
72
|
+
|
|
73
|
+
# concatenate args with coords that might have been removed
|
|
74
|
+
# before option processing
|
|
75
|
+
query = (args + coords).join(" ")
|
|
76
|
+
|
|
77
|
+
if query == ""
|
|
78
|
+
out << "Please specify a location (run `geocode -h` for more info).\n"
|
|
79
|
+
exit 1
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
if show_url and show_json
|
|
83
|
+
out << "You can only specify one of -j and -u.\n"
|
|
84
|
+
exit 2
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if show_url
|
|
88
|
+
q = Geocoder::Query.new(query)
|
|
89
|
+
out << q.url + "\n"
|
|
90
|
+
exit 0
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
if show_json
|
|
94
|
+
q = Geocoder::Query.new(query)
|
|
95
|
+
out << q.lookup.send(:fetch_raw_data, q) + "\n"
|
|
96
|
+
exit 0
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if (result = Geocoder.search(query).first)
|
|
100
|
+
nominatim = Geocoder::Lookup.get(:nominatim)
|
|
101
|
+
lines = [
|
|
102
|
+
["Latitude", result.latitude],
|
|
103
|
+
["Longitude", result.longitude],
|
|
104
|
+
["Full address", result.address],
|
|
105
|
+
["City", result.city],
|
|
106
|
+
["State/province", result.state],
|
|
107
|
+
["Postal code", result.postal_code],
|
|
108
|
+
["Country", result.country],
|
|
109
|
+
["Map", nominatim.map_link_url(result.coordinates)],
|
|
110
|
+
]
|
|
111
|
+
lines.each do |line|
|
|
112
|
+
out << (line[0] + ": ").ljust(18) + line[1].to_s + "\n"
|
|
113
|
+
end
|
|
114
|
+
exit 0
|
|
115
|
+
else
|
|
116
|
+
out << "Location '#{query}' not found.\n"
|
|
117
|
+
exit 1
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'geocoder/configuration_hash'
|
|
3
|
+
require 'geocoder/util'
|
|
4
|
+
|
|
5
|
+
module Geocoder
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Configuration options should be set by passing a hash:
|
|
9
|
+
#
|
|
10
|
+
# Geocoder.configure(
|
|
11
|
+
# :timeout => 5,
|
|
12
|
+
# :lookup => :yandex,
|
|
13
|
+
# :api_key => "2a9fsa983jaslfj982fjasd",
|
|
14
|
+
# :units => :km
|
|
15
|
+
# )
|
|
16
|
+
#
|
|
17
|
+
def self.configure(options = nil, &block)
|
|
18
|
+
if !options.nil?
|
|
19
|
+
Configuration.instance.configure(options)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Read-only access to the singleton's config data.
|
|
25
|
+
#
|
|
26
|
+
def self.config
|
|
27
|
+
Configuration.instance.data
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# Read-only access to lookup-specific config data.
|
|
32
|
+
#
|
|
33
|
+
def self.config_for_lookup(lookup_name)
|
|
34
|
+
data = config.clone
|
|
35
|
+
data.reject!{ |key,value| !Configuration::OPTIONS.include?(key) }
|
|
36
|
+
if config.has_key?(lookup_name)
|
|
37
|
+
data.merge!(config[lookup_name])
|
|
38
|
+
end
|
|
39
|
+
data
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
# Merge the given hash into a lookup's existing configuration.
|
|
44
|
+
#
|
|
45
|
+
def self.merge_into_lookup_config(lookup_name, options)
|
|
46
|
+
base = Geocoder.config[lookup_name]
|
|
47
|
+
Geocoder.configure(lookup_name => base.merge(options))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class Configuration
|
|
51
|
+
include Singleton
|
|
52
|
+
|
|
53
|
+
OPTIONS = [
|
|
54
|
+
:timeout,
|
|
55
|
+
:lookup,
|
|
56
|
+
:ip_lookup,
|
|
57
|
+
:language,
|
|
58
|
+
:host,
|
|
59
|
+
:http_headers,
|
|
60
|
+
:use_https,
|
|
61
|
+
:http_proxy,
|
|
62
|
+
:https_proxy,
|
|
63
|
+
:api_key,
|
|
64
|
+
:cache,
|
|
65
|
+
:always_raise,
|
|
66
|
+
:units,
|
|
67
|
+
:distances,
|
|
68
|
+
:basic_auth,
|
|
69
|
+
:logger,
|
|
70
|
+
:kernel_logger_level,
|
|
71
|
+
:cache_options
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
attr_accessor :data
|
|
75
|
+
|
|
76
|
+
def self.set_defaults
|
|
77
|
+
instance.set_defaults
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def self.initialize
|
|
81
|
+
instance.send(:initialize)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
OPTIONS.each do |o|
|
|
85
|
+
define_method o do
|
|
86
|
+
@data[o]
|
|
87
|
+
end
|
|
88
|
+
define_method "#{o}=" do |value|
|
|
89
|
+
@data[o] = value
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def configure(options)
|
|
94
|
+
Util.recursive_hash_merge(@data, options)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def initialize # :nodoc
|
|
98
|
+
@data = Geocoder::ConfigurationHash.new
|
|
99
|
+
set_defaults
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def set_defaults
|
|
103
|
+
|
|
104
|
+
# geocoding options
|
|
105
|
+
@data[:timeout] = 3 # geocoding service timeout (secs)
|
|
106
|
+
@data[:lookup] = :nominatim # name of street address geocoding service (symbol)
|
|
107
|
+
@data[:ip_lookup] = :ipinfo_io # name of IP address geocoding service (symbol)
|
|
108
|
+
@data[:language] = :en # ISO-639 language code
|
|
109
|
+
@data[:http_headers] = {} # HTTP headers for lookup
|
|
110
|
+
@data[:use_https] = false # use HTTPS for lookup requests? (if supported)
|
|
111
|
+
@data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
|
|
112
|
+
@data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
|
|
113
|
+
@data[:api_key] = nil # API key for geocoding service
|
|
114
|
+
@data[:basic_auth] = {} # user and password for basic auth ({:user => "user", :password => "password"})
|
|
115
|
+
@data[:logger] = :kernel # :kernel or Logger instance
|
|
116
|
+
@data[:kernel_logger_level] = ::Logger::WARN # log level, if kernel logger is used
|
|
117
|
+
|
|
118
|
+
# exceptions that should not be rescued by default
|
|
119
|
+
# (if you want to implement custom error handling);
|
|
120
|
+
# supports SocketError and Timeout::Error
|
|
121
|
+
@data[:always_raise] = []
|
|
122
|
+
|
|
123
|
+
# calculation options
|
|
124
|
+
@data[:units] = :mi # :mi or :km
|
|
125
|
+
@data[:distances] = :linear # :linear or :spherical
|
|
126
|
+
|
|
127
|
+
# Set the default values for the caching mechanism
|
|
128
|
+
# By default, the cache keys will not expire as IP addresses and phyiscal
|
|
129
|
+
# addresses will rarely change.
|
|
130
|
+
@data[:cache] = nil # cache object (must respond to #[], #[]=, and optionally #keys)
|
|
131
|
+
@data[:cache_prefix] = nil # - DEPRECATED - prefix (string) to use for all cache keys
|
|
132
|
+
@data[:cache_options] = {
|
|
133
|
+
prefix: 'geocoder:',
|
|
134
|
+
expiration: nil
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
instance_eval(OPTIONS.map do |option|
|
|
139
|
+
o = option.to_s
|
|
140
|
+
<<-EOS
|
|
141
|
+
def #{o}
|
|
142
|
+
instance.data[:#{o}]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def #{o}=(value)
|
|
146
|
+
instance.data[:#{o}] = value
|
|
147
|
+
end
|
|
148
|
+
EOS
|
|
149
|
+
end.join("\n\n"))
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Geocoder
|
|
2
|
+
class EsriToken
|
|
3
|
+
attr_accessor :value, :expires_at
|
|
4
|
+
|
|
5
|
+
def initialize(value, expires_at)
|
|
6
|
+
@value = value
|
|
7
|
+
@expires_at = expires_at
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def to_s
|
|
11
|
+
@value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def active?
|
|
15
|
+
@expires_at > Time.now
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.generate_token(client_id, client_secret, expires=1440)
|
|
19
|
+
# creates a new token that will expire in 1 day by default
|
|
20
|
+
getToken = Net::HTTP.post_form URI('https://www.arcgis.com/sharing/rest/oauth2/token'),
|
|
21
|
+
f: 'json',
|
|
22
|
+
client_id: client_id,
|
|
23
|
+
client_secret: client_secret,
|
|
24
|
+
grant_type: 'client_credentials',
|
|
25
|
+
expiration: expires # (minutes) max: 20160, default: 1 day
|
|
26
|
+
|
|
27
|
+
response = JSON.parse(getToken.body)
|
|
28
|
+
|
|
29
|
+
if response['error']
|
|
30
|
+
Geocoder.log(:warn, response['error'])
|
|
31
|
+
else
|
|
32
|
+
token_value = response['access_token']
|
|
33
|
+
expires_at = Time.now + (expires * 60)
|
|
34
|
+
new(token_value, expires_at)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'timeout'
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
|
|
5
|
+
class Error < StandardError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class ConfigurationError < Error
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class OverQueryLimitError < Error
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class ResponseParseError < Error
|
|
15
|
+
attr_reader :response
|
|
16
|
+
|
|
17
|
+
def initialize(response)
|
|
18
|
+
@response = response
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class RequestDenied < Error
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class InvalidRequest < Error
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class InvalidApiKey < Error
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class ServiceUnavailable < Error
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class LookupTimeout < ::Timeout::Error
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class NetworkError < Error
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'resolv'
|
|
2
|
+
module Geocoder
|
|
3
|
+
class IpAddress < String
|
|
4
|
+
PRIVATE_IPS = [
|
|
5
|
+
'10.0.0.0/8',
|
|
6
|
+
'172.16.0.0/12',
|
|
7
|
+
'192.168.0.0/16',
|
|
8
|
+
].map { |ip| IPAddr.new(ip) }.freeze
|
|
9
|
+
|
|
10
|
+
def initialize(ip)
|
|
11
|
+
ip = ip.to_string if ip.is_a?(IPAddr)
|
|
12
|
+
if ip.is_a?(Hash)
|
|
13
|
+
super(**ip)
|
|
14
|
+
else
|
|
15
|
+
super(ip)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def internal?
|
|
20
|
+
loopback? || private?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def loopback?
|
|
24
|
+
valid? and !!(self == "0.0.0.0" or self.match(/\A127\./) or self == "::1")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def private?
|
|
28
|
+
valid? && PRIVATE_IPS.any? { |ip| ip.include?(self) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def valid?
|
|
32
|
+
ip = self[/(?<=\[)(.*?)(?=\])/] || self
|
|
33
|
+
!!((ip =~ Resolv::IPv4::Regex) || (ip =~ Resolv::IPv6::Regex))
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Geocoder
|
|
2
|
+
class KernelLogger
|
|
3
|
+
include Singleton
|
|
4
|
+
|
|
5
|
+
def add(level, message)
|
|
6
|
+
return unless log_message_at_level?(level)
|
|
7
|
+
case level
|
|
8
|
+
when ::Logger::DEBUG, ::Logger::INFO
|
|
9
|
+
puts message
|
|
10
|
+
when ::Logger::WARN
|
|
11
|
+
warn message
|
|
12
|
+
when ::Logger::ERROR
|
|
13
|
+
raise message
|
|
14
|
+
when ::Logger::FATAL
|
|
15
|
+
fail message
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ----------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def log_message_at_level?(level)
|
|
22
|
+
level >= Geocoder.config.kernel_logger_level
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
|
|
5
|
+
def self.log(level, message)
|
|
6
|
+
Logger.instance.log(level, message)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class Logger
|
|
10
|
+
include Singleton
|
|
11
|
+
|
|
12
|
+
SEVERITY = {
|
|
13
|
+
debug: ::Logger::DEBUG,
|
|
14
|
+
info: ::Logger::INFO,
|
|
15
|
+
warn: ::Logger::WARN,
|
|
16
|
+
error: ::Logger::ERROR,
|
|
17
|
+
fatal: ::Logger::FATAL
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
def log(level, message)
|
|
21
|
+
unless valid_level?(level)
|
|
22
|
+
raise StandardError, "Geocoder tried to log a message with an invalid log level."
|
|
23
|
+
end
|
|
24
|
+
if current_logger.respond_to? :add
|
|
25
|
+
current_logger.add(SEVERITY[level], message)
|
|
26
|
+
else
|
|
27
|
+
raise Geocoder::ConfigurationError, "Please specify valid logger for Geocoder. " +
|
|
28
|
+
"Logger specified must be :kernel or must respond to `add(level, message)`."
|
|
29
|
+
end
|
|
30
|
+
nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private # ----------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
def current_logger
|
|
36
|
+
logger = Geocoder.config[:logger]
|
|
37
|
+
if logger == :kernel
|
|
38
|
+
logger = Geocoder::KernelLogger.instance
|
|
39
|
+
end
|
|
40
|
+
logger
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def valid_level?(level)
|
|
44
|
+
SEVERITY.keys.include?(level)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
require "geocoder/lookups/test"
|
|
2
|
+
|
|
3
|
+
module Geocoder
|
|
4
|
+
module Lookup
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Array of valid Lookup service names.
|
|
9
|
+
#
|
|
10
|
+
def all_services
|
|
11
|
+
street_services + ip_services
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Array of valid Lookup service names, excluding :test.
|
|
16
|
+
#
|
|
17
|
+
def all_services_except_test
|
|
18
|
+
all_services - [:test]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# Array of valid Lookup service names, excluding any that do not build their own HTTP requests.
|
|
23
|
+
# For example, Amazon Location Service uses the AWS gem, not HTTP REST requests, to fetch data.
|
|
24
|
+
#
|
|
25
|
+
def all_services_with_http_requests
|
|
26
|
+
all_services_except_test - [:amazon_location_service, :maxmind_local, :geoip2, :ip2location_lite]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# All street address lookup services, default first.
|
|
31
|
+
#
|
|
32
|
+
def street_services
|
|
33
|
+
@street_services ||= [
|
|
34
|
+
:location_iq,
|
|
35
|
+
:azure,
|
|
36
|
+
:esri,
|
|
37
|
+
:google,
|
|
38
|
+
:google_premier,
|
|
39
|
+
:google_places_details,
|
|
40
|
+
:google_places_search,
|
|
41
|
+
:bing,
|
|
42
|
+
:geocoder_ca,
|
|
43
|
+
:yandex,
|
|
44
|
+
:nationaal_georegister_nl,
|
|
45
|
+
:nominatim,
|
|
46
|
+
:mapbox,
|
|
47
|
+
:mapquest,
|
|
48
|
+
:uk_ordnance_survey_names,
|
|
49
|
+
:opencagedata,
|
|
50
|
+
:pelias,
|
|
51
|
+
:pdok_nl,
|
|
52
|
+
:pickpoint,
|
|
53
|
+
:here,
|
|
54
|
+
:baidu,
|
|
55
|
+
:tencent,
|
|
56
|
+
:geocodio,
|
|
57
|
+
:smarty_streets,
|
|
58
|
+
:postcode_anywhere_uk,
|
|
59
|
+
:postcodes_io,
|
|
60
|
+
:geoportail_lu,
|
|
61
|
+
:ban_data_gouv_fr,
|
|
62
|
+
:test,
|
|
63
|
+
:latlon,
|
|
64
|
+
:amap,
|
|
65
|
+
:osmnames,
|
|
66
|
+
:melissa_street,
|
|
67
|
+
:amazon_location_service,
|
|
68
|
+
:geoapify,
|
|
69
|
+
:photon,
|
|
70
|
+
:twogis,
|
|
71
|
+
:pc_miler
|
|
72
|
+
]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
##
|
|
76
|
+
# All IP address lookup services, default first.
|
|
77
|
+
#
|
|
78
|
+
def ip_services
|
|
79
|
+
@ip_services ||= [
|
|
80
|
+
:baidu_ip,
|
|
81
|
+
:abstract_api,
|
|
82
|
+
:freegeoip,
|
|
83
|
+
:geoip2,
|
|
84
|
+
:maxmind,
|
|
85
|
+
:maxmind_local,
|
|
86
|
+
:telize,
|
|
87
|
+
:pointpin,
|
|
88
|
+
:maxmind_geoip2,
|
|
89
|
+
:ipinfo_io,
|
|
90
|
+
:ipinfo_io_lite,
|
|
91
|
+
:ipregistry,
|
|
92
|
+
:ipapi_com,
|
|
93
|
+
:ipdata_co,
|
|
94
|
+
:db_ip_com,
|
|
95
|
+
:ipstack,
|
|
96
|
+
:ip2location,
|
|
97
|
+
:ipgeolocation,
|
|
98
|
+
:ipqualityscore,
|
|
99
|
+
:ipbase,
|
|
100
|
+
:ip2location_io,
|
|
101
|
+
:ip2location_lite
|
|
102
|
+
]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
attr_writer :street_services, :ip_services
|
|
106
|
+
|
|
107
|
+
##
|
|
108
|
+
# Retrieve a Lookup object from the store.
|
|
109
|
+
# Use this instead of Geocoder::Lookup::X.new to get an
|
|
110
|
+
# already-configured Lookup object.
|
|
111
|
+
#
|
|
112
|
+
def get(name)
|
|
113
|
+
@services = {} unless defined?(@services)
|
|
114
|
+
@services[name] = spawn(name) unless @services.include?(name)
|
|
115
|
+
@services[name]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
private # -----------------------------------------------------------------
|
|
120
|
+
|
|
121
|
+
##
|
|
122
|
+
# Spawn a Lookup of the given name.
|
|
123
|
+
#
|
|
124
|
+
def spawn(name)
|
|
125
|
+
if all_services.include?(name)
|
|
126
|
+
name = name.to_s
|
|
127
|
+
instantiate_lookup(name)
|
|
128
|
+
else
|
|
129
|
+
valids = all_services.map(&:inspect).join(", ")
|
|
130
|
+
raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
|
|
131
|
+
"(#{name.inspect} is not one of: #{valids})."
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# Convert an "underscore" version of a name into a "class" version.
|
|
137
|
+
#
|
|
138
|
+
def classify_name(filename)
|
|
139
|
+
filename.to_s.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
##
|
|
143
|
+
# Safely instantiate Lookup
|
|
144
|
+
#
|
|
145
|
+
def instantiate_lookup(name)
|
|
146
|
+
class_name = classify_name(name)
|
|
147
|
+
begin
|
|
148
|
+
Geocoder::Lookup.const_get(class_name, inherit=false)
|
|
149
|
+
rescue NameError
|
|
150
|
+
require "geocoder/lookups/#{name}"
|
|
151
|
+
end
|
|
152
|
+
Geocoder::Lookup.const_get(class_name).new
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'geocoder/lookups/base'
|
|
4
|
+
require 'geocoder/results/abstract_api'
|
|
5
|
+
|
|
6
|
+
module Geocoder::Lookup
|
|
7
|
+
class AbstractApi < Base
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Abstract API"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def required_api_key_parts
|
|
14
|
+
['api_key']
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def supported_protocols
|
|
18
|
+
[:https]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private # ---------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
def base_query_url(query)
|
|
24
|
+
"#{protocol}://ipgeolocation.abstractapi.com/v1/?"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def query_url_params(query)
|
|
28
|
+
params = {api_key: configuration.api_key}
|
|
29
|
+
|
|
30
|
+
ip_address = query.sanitized_text
|
|
31
|
+
if ip_address.is_a?(String) && ip_address.length > 0
|
|
32
|
+
params[:ip_address] = ip_address
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
params.merge(super)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def results(query, reverse = false)
|
|
39
|
+
if doc = fetch_data(query)
|
|
40
|
+
[doc]
|
|
41
|
+
else
|
|
42
|
+
[]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|