geocoder 1.1.9 → 1.8.0

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.
Files changed (238) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +309 -0
  3. data/LICENSE +1 -1
  4. data/README.md +544 -540
  5. data/bin/console +13 -0
  6. data/examples/app_defined_lookup_services.rb +22 -0
  7. data/examples/reverse_geocode_job.rb +40 -0
  8. data/lib/easting_northing.rb +171 -0
  9. data/lib/generators/geocoder/config/templates/initializer.rb +22 -16
  10. data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +30 -0
  11. data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +30 -0
  12. data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +30 -0
  13. data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +17 -0
  14. data/lib/generators/geocoder/migration_version.rb +15 -0
  15. data/lib/geocoder/cache.rb +20 -32
  16. data/lib/geocoder/cache_stores/base.rb +40 -0
  17. data/lib/geocoder/cache_stores/generic.rb +35 -0
  18. data/lib/geocoder/cache_stores/redis.rb +34 -0
  19. data/lib/geocoder/calculations.rb +67 -36
  20. data/lib/geocoder/cli.rb +2 -2
  21. data/lib/geocoder/configuration.rb +33 -16
  22. data/lib/geocoder/configuration_hash.rb +4 -4
  23. data/lib/geocoder/esri_token.rb +38 -0
  24. data/lib/geocoder/exceptions.rb +19 -0
  25. data/lib/geocoder/ip_address.rb +33 -0
  26. data/lib/geocoder/kernel_logger.rb +25 -0
  27. data/lib/geocoder/logger.rb +47 -0
  28. data/lib/geocoder/lookup.rb +74 -11
  29. data/lib/geocoder/lookups/abstract_api.rb +46 -0
  30. data/lib/geocoder/lookups/amap.rb +63 -0
  31. data/lib/geocoder/lookups/amazon_location_service.rb +54 -0
  32. data/lib/geocoder/lookups/baidu.rb +24 -15
  33. data/lib/geocoder/lookups/baidu_ip.rb +30 -0
  34. data/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
  35. data/lib/geocoder/lookups/base.rb +109 -23
  36. data/lib/geocoder/lookups/bing.rb +45 -10
  37. data/lib/geocoder/lookups/db_ip_com.rb +52 -0
  38. data/lib/geocoder/lookups/dstk.rb +4 -2
  39. data/lib/geocoder/lookups/esri.rb +61 -8
  40. data/lib/geocoder/lookups/freegeoip.rb +25 -6
  41. data/lib/geocoder/lookups/geoapify.rb +72 -0
  42. data/lib/geocoder/lookups/geocoder_ca.rb +5 -6
  43. data/lib/geocoder/lookups/geocodio.rb +42 -0
  44. data/lib/geocoder/lookups/geoip2.rb +49 -0
  45. data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
  46. data/lib/geocoder/lookups/google.rb +45 -12
  47. data/lib/geocoder/lookups/google_places_details.rb +64 -0
  48. data/lib/geocoder/lookups/google_places_search.rb +76 -0
  49. data/lib/geocoder/lookups/google_premier.rb +16 -2
  50. data/lib/geocoder/lookups/here.rb +73 -0
  51. data/lib/geocoder/lookups/ip2location.rb +71 -0
  52. data/lib/geocoder/lookups/ipapi_com.rb +82 -0
  53. data/lib/geocoder/lookups/ipdata_co.rb +62 -0
  54. data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
  55. data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
  56. data/lib/geocoder/lookups/ipqualityscore.rb +50 -0
  57. data/lib/geocoder/lookups/ipregistry.rb +68 -0
  58. data/lib/geocoder/lookups/ipstack.rb +63 -0
  59. data/lib/geocoder/lookups/latlon.rb +58 -0
  60. data/lib/geocoder/lookups/location_iq.rb +54 -0
  61. data/lib/geocoder/lookups/mapbox.rb +59 -0
  62. data/lib/geocoder/lookups/mapquest.rb +9 -10
  63. data/lib/geocoder/lookups/maxmind.rb +10 -8
  64. data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
  65. data/lib/geocoder/lookups/maxmind_local.rb +71 -0
  66. data/lib/geocoder/lookups/melissa_street.rb +41 -0
  67. data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
  68. data/lib/geocoder/lookups/nominatim.rb +26 -6
  69. data/lib/geocoder/lookups/opencagedata.rb +65 -0
  70. data/lib/geocoder/lookups/osmnames.rb +57 -0
  71. data/lib/geocoder/lookups/pelias.rb +63 -0
  72. data/lib/geocoder/lookups/photon.rb +89 -0
  73. data/lib/geocoder/lookups/pickpoint.rb +41 -0
  74. data/lib/geocoder/lookups/pointpin.rb +69 -0
  75. data/lib/geocoder/lookups/postcode_anywhere_uk.rb +50 -0
  76. data/lib/geocoder/lookups/postcodes_io.rb +31 -0
  77. data/lib/geocoder/lookups/smarty_streets.rb +68 -0
  78. data/lib/geocoder/lookups/telize.rb +75 -0
  79. data/lib/geocoder/lookups/tencent.rb +59 -0
  80. data/lib/geocoder/lookups/test.rb +4 -0
  81. data/lib/geocoder/lookups/twogis.rb +58 -0
  82. data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
  83. data/lib/geocoder/lookups/yandex.rb +18 -11
  84. data/lib/geocoder/models/active_record.rb +9 -4
  85. data/lib/geocoder/models/base.rb +1 -4
  86. data/lib/geocoder/models/mongo_base.rb +6 -4
  87. data/lib/geocoder/query.rb +23 -5
  88. data/lib/geocoder/railtie.rb +2 -2
  89. data/lib/geocoder/request.rb +102 -11
  90. data/lib/geocoder/results/abstract_api.rb +146 -0
  91. data/lib/geocoder/results/amap.rb +87 -0
  92. data/lib/geocoder/results/amazon_location_service.rb +57 -0
  93. data/lib/geocoder/results/baidu.rb +10 -14
  94. data/lib/geocoder/results/baidu_ip.rb +62 -0
  95. data/lib/geocoder/results/ban_data_gouv_fr.rb +282 -0
  96. data/lib/geocoder/results/base.rb +13 -1
  97. data/lib/geocoder/results/bing.rb +5 -1
  98. data/lib/geocoder/results/db_ip_com.rb +58 -0
  99. data/lib/geocoder/results/esri.rb +35 -8
  100. data/lib/geocoder/results/freegeoip.rb +2 -7
  101. data/lib/geocoder/results/geoapify.rb +179 -0
  102. data/lib/geocoder/results/geocoder_ca.rb +3 -3
  103. data/lib/geocoder/results/geocodio.rb +78 -0
  104. data/lib/geocoder/results/geoip2.rb +76 -0
  105. data/lib/geocoder/results/geoportail_lu.rb +71 -0
  106. data/lib/geocoder/results/google.rb +26 -0
  107. data/lib/geocoder/results/google_places_details.rb +39 -0
  108. data/lib/geocoder/results/google_places_search.rb +52 -0
  109. data/lib/geocoder/results/here.rb +77 -0
  110. data/lib/geocoder/results/ip2location.rb +22 -0
  111. data/lib/geocoder/results/ipapi_com.rb +45 -0
  112. data/lib/geocoder/results/ipdata_co.rb +40 -0
  113. data/lib/geocoder/results/ipgeolocation.rb +59 -0
  114. data/lib/geocoder/results/ipinfo_io.rb +48 -0
  115. data/lib/geocoder/results/ipqualityscore.rb +54 -0
  116. data/lib/geocoder/results/ipregistry.rb +304 -0
  117. data/lib/geocoder/results/ipstack.rb +60 -0
  118. data/lib/geocoder/results/latlon.rb +71 -0
  119. data/lib/geocoder/results/location_iq.rb +6 -0
  120. data/lib/geocoder/results/mapbox.rb +63 -0
  121. data/lib/geocoder/results/mapquest.rb +5 -8
  122. data/lib/geocoder/results/maxmind.rb +0 -5
  123. data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
  124. data/lib/geocoder/results/maxmind_local.rb +44 -0
  125. data/lib/geocoder/results/melissa_street.rb +46 -0
  126. data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
  127. data/lib/geocoder/results/nominatim.rb +41 -14
  128. data/lib/geocoder/results/opencagedata.rb +100 -0
  129. data/lib/geocoder/results/osmnames.rb +56 -0
  130. data/lib/geocoder/results/pelias.rb +58 -0
  131. data/lib/geocoder/results/photon.rb +119 -0
  132. data/lib/geocoder/results/pickpoint.rb +6 -0
  133. data/lib/geocoder/results/pointpin.rb +40 -0
  134. data/lib/geocoder/results/postcode_anywhere_uk.rb +42 -0
  135. data/lib/geocoder/results/postcodes_io.rb +40 -0
  136. data/lib/geocoder/results/smarty_streets.rb +142 -0
  137. data/lib/geocoder/results/telize.rb +40 -0
  138. data/lib/geocoder/results/tencent.rb +72 -0
  139. data/lib/geocoder/results/test.rb +20 -3
  140. data/lib/geocoder/results/twogis.rb +76 -0
  141. data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
  142. data/lib/geocoder/results/yandex.rb +244 -32
  143. data/lib/geocoder/sql.rb +25 -21
  144. data/lib/geocoder/stores/active_record.rb +82 -26
  145. data/lib/geocoder/stores/base.rb +9 -14
  146. data/lib/geocoder/stores/mongo_base.rb +0 -31
  147. data/lib/geocoder/util.rb +29 -0
  148. data/lib/geocoder/version.rb +1 -1
  149. data/lib/geocoder.rb +6 -13
  150. data/lib/maxmind_database.rb +109 -0
  151. data/lib/tasks/geocoder.rake +30 -3
  152. data/lib/tasks/maxmind.rake +73 -0
  153. metadata +115 -98
  154. data/.gitignore +0 -5
  155. data/.travis.yml +0 -27
  156. data/Rakefile +0 -25
  157. data/examples/autoexpire_cache_dalli.rb +0 -62
  158. data/examples/autoexpire_cache_redis.rb +0 -28
  159. data/gemfiles/Gemfile.mongoid-2.4.x +0 -15
  160. data/lib/geocoder/lookups/geocoder_us.rb +0 -39
  161. data/lib/geocoder/lookups/ovi.rb +0 -62
  162. data/lib/geocoder/lookups/yahoo.rb +0 -86
  163. data/lib/geocoder/results/geocoder_us.rb +0 -39
  164. data/lib/geocoder/results/ovi.rb +0 -62
  165. data/lib/geocoder/results/yahoo.rb +0 -55
  166. data/lib/hash_recursive_merge.rb +0 -74
  167. data/lib/oauth_util.rb +0 -112
  168. data/test/active_record_test.rb +0 -15
  169. data/test/cache_test.rb +0 -35
  170. data/test/calculations_test.rb +0 -211
  171. data/test/configuration_test.rb +0 -78
  172. data/test/custom_block_test.rb +0 -32
  173. data/test/error_handling_test.rb +0 -43
  174. data/test/fixtures/baidu_invalid_key +0 -1
  175. data/test/fixtures/baidu_no_results +0 -1
  176. data/test/fixtures/baidu_reverse +0 -1
  177. data/test/fixtures/baidu_shanghai_pearl_tower +0 -12
  178. data/test/fixtures/bing_invalid_key +0 -1
  179. data/test/fixtures/bing_madison_square_garden +0 -40
  180. data/test/fixtures/bing_no_results +0 -16
  181. data/test/fixtures/bing_reverse +0 -42
  182. data/test/fixtures/esri_madison_square_garden +0 -59
  183. data/test/fixtures/esri_no_results +0 -8
  184. data/test/fixtures/esri_reverse +0 -21
  185. data/test/fixtures/freegeoip_74_200_247_59 +0 -12
  186. data/test/fixtures/freegeoip_no_results +0 -1
  187. data/test/fixtures/geocoder_ca_madison_square_garden +0 -1
  188. data/test/fixtures/geocoder_ca_no_results +0 -1
  189. data/test/fixtures/geocoder_ca_reverse +0 -34
  190. data/test/fixtures/geocoder_us_madison_square_garden +0 -1
  191. data/test/fixtures/geocoder_us_no_results +0 -1
  192. data/test/fixtures/google_garbage +0 -456
  193. data/test/fixtures/google_madison_square_garden +0 -57
  194. data/test/fixtures/google_no_city_data +0 -44
  195. data/test/fixtures/google_no_locality +0 -51
  196. data/test/fixtures/google_no_results +0 -4
  197. data/test/fixtures/google_over_limit +0 -4
  198. data/test/fixtures/mapquest_error +0 -16
  199. data/test/fixtures/mapquest_invalid_api_key +0 -16
  200. data/test/fixtures/mapquest_invalid_request +0 -16
  201. data/test/fixtures/mapquest_madison_square_garden +0 -52
  202. data/test/fixtures/mapquest_no_results +0 -16
  203. data/test/fixtures/maxmind_24_24_24_21 +0 -1
  204. data/test/fixtures/maxmind_24_24_24_22 +0 -1
  205. data/test/fixtures/maxmind_24_24_24_23 +0 -1
  206. data/test/fixtures/maxmind_24_24_24_24 +0 -1
  207. data/test/fixtures/maxmind_74_200_247_59 +0 -1
  208. data/test/fixtures/maxmind_invalid_key +0 -1
  209. data/test/fixtures/maxmind_no_results +0 -1
  210. data/test/fixtures/nominatim_madison_square_garden +0 -150
  211. data/test/fixtures/nominatim_no_results +0 -1
  212. data/test/fixtures/ovi_madison_square_garden +0 -72
  213. data/test/fixtures/ovi_no_results +0 -8
  214. data/test/fixtures/yahoo_error +0 -1
  215. data/test/fixtures/yahoo_invalid_key +0 -2
  216. data/test/fixtures/yahoo_madison_square_garden +0 -52
  217. data/test/fixtures/yahoo_no_results +0 -10
  218. data/test/fixtures/yahoo_over_limit +0 -2
  219. data/test/fixtures/yandex_invalid_key +0 -1
  220. data/test/fixtures/yandex_kremlin +0 -48
  221. data/test/fixtures/yandex_no_city_and_town +0 -112
  222. data/test/fixtures/yandex_no_results +0 -16
  223. data/test/geocoder_test.rb +0 -59
  224. data/test/https_test.rb +0 -16
  225. data/test/integration/smoke_test.rb +0 -26
  226. data/test/lookup_test.rb +0 -117
  227. data/test/method_aliases_test.rb +0 -25
  228. data/test/mongoid_test.rb +0 -46
  229. data/test/mongoid_test_helper.rb +0 -43
  230. data/test/near_test.rb +0 -61
  231. data/test/oauth_util_test.rb +0 -30
  232. data/test/proxy_test.rb +0 -36
  233. data/test/query_test.rb +0 -52
  234. data/test/request_test.rb +0 -29
  235. data/test/result_test.rb +0 -42
  236. data/test/services_test.rb +0 -393
  237. data/test/test_helper.rb +0 -289
  238. data/test/test_mode_test.rb +0 -59
data/.travis.yml DELETED
@@ -1,27 +0,0 @@
1
- rvm:
2
- - 1.8.7
3
- - 1.9.2
4
- - 1.9.3
5
- - 2.0.0
6
- - jruby-19mode
7
- gemfile:
8
- - Gemfile
9
- - gemfiles/Gemfile.mongoid-2.4.x
10
- env: SSL_CERT_DIR=/etc/ssl/certs
11
- matrix:
12
- exclude:
13
- - rvm: 1.8.7
14
- gemfile: Gemfile
15
- env: SSL_CERT_DIR=/etc/ssl/certs
16
- - rvm: 1.9.2
17
- gemfile: Gemfile
18
- env: SSL_CERT_DIR=/etc/ssl/certs
19
- - rvm: 1.9.3
20
- gemfile: gemfiles/Gemfile.mongoid-2.4.x
21
- env: SSL_CERT_DIR=/etc/ssl/certs
22
- - rvm: 2.0.0
23
- gemfile: gemfiles/Gemfile.mongoid-2.4.x
24
- env: SSL_CERT_DIR=/etc/ssl/certs
25
- - rvm: jruby-19mode
26
- gemfile: gemfiles/Gemfile.mongoid-2.4.x
27
- env: SSL_CERT_DIR=/etc/ssl/certs
data/Rakefile DELETED
@@ -1,25 +0,0 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
3
-
4
- require 'rake/testtask'
5
- Rake::TestTask.new(:test) do |test|
6
- test.libs << 'lib' << 'test'
7
- test.pattern = 'test/*_test.rb'
8
- test.verbose = true
9
- end
10
-
11
- Rake::TestTask.new(:integration) do |test|
12
- test.libs << 'lib' << 'test'
13
- test.pattern = 'test/integration/*_test.rb'
14
- test.verbose = true
15
- end
16
-
17
- task :default => [:test]
18
-
19
- require 'rdoc/task'
20
- Rake::RDocTask.new do |rdoc|
21
- rdoc.rdoc_dir = 'rdoc'
22
- rdoc.title = "Geocoder #{Geocoder::VERSION}"
23
- rdoc.rdoc_files.include('*.rdoc')
24
- rdoc.rdoc_files.include('lib/**/*.rb')
25
- end
@@ -1,62 +0,0 @@
1
- # This class implements a cache with simple delegation to the the Dalli Memcached client
2
- # https://github.com/mperham/dalli
3
- #
4
- # A TTL is set on initialization
5
-
6
- class AutoexpireCacheDalli
7
- def initialize(store, ttl = 86400)
8
- @store = store
9
- @keys = 'GeocoderDalliClientKeys'
10
- @ttl = ttl
11
- end
12
-
13
- def [](url)
14
- res = @store.get(url)
15
- res = YAML::load(res) if res.present?
16
- res
17
- end
18
-
19
- def []=(url, value)
20
- if value.nil?
21
- del(url)
22
- else
23
- key_cache_add(url) if @store.add(url, YAML::dump(value), @ttl)
24
- end
25
- value
26
- end
27
-
28
- def keys
29
- key_cache
30
- end
31
-
32
- def del(url)
33
- key_cache_delete(url) if @store.delete(url)
34
- end
35
-
36
- private
37
-
38
- def key_cache
39
- the_keys = @store.get(@keys)
40
- if the_keys.nil?
41
- @store.add(@keys, YAML::dump([]))
42
- []
43
- else
44
- YAML::load(the_keys)
45
- end
46
- end
47
-
48
- def key_cache_add(key)
49
- @store.replace(@keys, YAML::dump(key_cache << key))
50
- end
51
-
52
- def key_cache_delete(key)
53
- tmp = key_cache
54
- tmp.delete(key)
55
- @store.replace(@keys, YAML::dump(tmp))
56
- end
57
- end
58
-
59
- # Here Dalli is set up as on Heroku using the Memcachier gem.
60
- # https://devcenter.heroku.com/articles/memcachier#ruby
61
- # On other setups you might have to specify your Memcached server in Dalli::Client.new
62
- Geocoder.configure(:cache => AutoexpireCacheDalli.new(Dalli::Client.new))
@@ -1,28 +0,0 @@
1
- # This class implements a cache with simple delegation to the Redis store, but
2
- # when it creates a key/value pair, it also sends an EXPIRE command with a TTL.
3
- # It should be fairly simple to do the same thing with Memcached.
4
- class AutoexpireCacheRedis
5
- def initialize(store, ttl = 86400)
6
- @store = store
7
- @ttl = ttl
8
- end
9
-
10
- def [](url)
11
- @store.[](url)
12
- end
13
-
14
- def []=(url, value)
15
- @store.[]=(url, value)
16
- @store.expire(url, @ttl)
17
- end
18
-
19
- def keys
20
- @store.keys
21
- end
22
-
23
- def del(url)
24
- @store.del(url)
25
- end
26
- end
27
-
28
- Geocoder.configure(:cache => AutoexpireCacheRedis.new(Redis.new))
@@ -1,15 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec :path => '..'
4
-
5
- group :development, :test do
6
- gem 'rake'
7
- gem 'mongoid', '2.4.11'
8
- gem 'bson_ext', :platforms => :ruby
9
-
10
- gem 'rails'
11
-
12
- platforms :jruby do
13
- gem 'jruby-openssl'
14
- end
15
- end
@@ -1,39 +0,0 @@
1
- require 'geocoder/lookups/base'
2
- require "geocoder/results/geocoder_us"
3
-
4
- module Geocoder::Lookup
5
- class GeocoderUs < Base
6
-
7
- def name
8
- "Geocoder.us"
9
- end
10
-
11
- def query_url(query)
12
- if configuration.api_key
13
- "http://#{configuration.api_key}@geocoder.us/member/service/csv/geocode?" + url_query_string(query)
14
- else
15
- "http://geocoder.us/service/csv/geocode?" + url_query_string(query)
16
- end
17
- end
18
-
19
- private
20
-
21
- def results(query)
22
- return [] unless doc = fetch_data(query)
23
- if doc[0].to_s =~ /^(\d+)\:/
24
- return []
25
- else
26
- return [doc.size == 5 ? ((doc[0..1] << nil) + doc[2..4]) : doc]
27
- end
28
- end
29
-
30
- def query_url_params(query)
31
- (query.text =~ /^\d{5}(?:-\d{4})?$/ ? {:zip => query} : {:address => query.sanitized_text}).merge(super)
32
- end
33
-
34
- def parse_raw_data(raw_data)
35
- raw_data.chomp.split(',')
36
- end
37
- end
38
- end
39
-
@@ -1,62 +0,0 @@
1
- require 'geocoder/lookups/base'
2
- require 'geocoder/results/ovi'
3
-
4
- module Geocoder::Lookup
5
- class Ovi < Base
6
-
7
- def name
8
- "Ovi"
9
- end
10
-
11
- def required_api_key_parts
12
- []
13
- end
14
-
15
- def query_url(query)
16
- "#{protocol}://lbs.ovi.com/search/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?" + url_query_string(query)
17
- end
18
-
19
- private # ---------------------------------------------------------------
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_params(query)
32
- options = {
33
- :gen=>1,
34
- :app_id=>api_key,
35
- :app_code=>api_code
36
- }
37
-
38
- if query.reverse_geocode?
39
- super.merge(options).merge(
40
- :prox=>query.sanitized_text,
41
- :mode=>:retrieveAddresses
42
- )
43
- else
44
- super.merge(options).merge(
45
- :searchtext=>query.sanitized_text
46
- )
47
- end
48
- end
49
-
50
- def api_key
51
- if a=configuration.api_key
52
- return a.first if a.is_a?(Array)
53
- end
54
- end
55
-
56
- def api_code
57
- if a=configuration.api_key
58
- return a.last if a.is_a?(Array)
59
- end
60
- end
61
- end
62
- end
@@ -1,86 +0,0 @@
1
- require 'geocoder/lookups/base'
2
- require "geocoder/results/yahoo"
3
- require 'oauth_util'
4
-
5
- module Geocoder::Lookup
6
- class Yahoo < Base
7
-
8
- def name
9
- "Yahoo BOSS"
10
- end
11
-
12
- def map_link_url(coordinates)
13
- "http://maps.yahoo.com/#lat=#{coordinates[0]}&lon=#{coordinates[1]}"
14
- end
15
-
16
- def required_api_key_parts
17
- ["consumer key", "consumer secret"]
18
- end
19
-
20
- def query_url(query)
21
- parsed_url = URI.parse(raw_url(query))
22
- o = OauthUtil.new
23
- o.consumer_key = configuration.api_key[0]
24
- o.consumer_secret = configuration.api_key[1]
25
- base_url + o.sign(parsed_url).query_string
26
- end
27
-
28
- private # ---------------------------------------------------------------
29
-
30
- def results(query)
31
- return [] unless doc = fetch_data(query)
32
- doc = doc['bossresponse']
33
- if doc['responsecode'].to_i == 200
34
- if doc['placefinder']['count'].to_i > 0
35
- return doc['placefinder']['results']
36
- else
37
- return []
38
- end
39
- else
40
- warn "Yahoo Geocoding API error: #{doc['responsecode']} (#{doc['reason']})."
41
- return []
42
- end
43
- end
44
-
45
- ##
46
- # Yahoo returns errors as XML even when JSON format is specified.
47
- # Handle that here, without parsing the XML
48
- # (which would add unnecessary complexity).
49
- # Yahoo auth errors can also be cryptic, so add raw error desc
50
- # to warning message.
51
- #
52
- def parse_raw_data(raw_data)
53
- if raw_data.match /^<\?xml/
54
- if raw_data.include?("Rate Limit Exceeded")
55
- raise_error(Geocoder::OverQueryLimitError) || warn("Over API query limit.")
56
- elsif raw_data =~ /<yahoo:description>(Please provide valid credentials.*)<\/yahoo:description>/i
57
- raise_error(Geocoder::InvalidApiKey) || warn("Invalid API key. Error response: #{$1}")
58
- end
59
- else
60
- super(raw_data)
61
- end
62
- end
63
-
64
- def query_url_params(query)
65
- {
66
- :location => query.sanitized_text,
67
- :flags => "JXTSR",
68
- :gflags => "AC#{'R' if query.reverse_geocode?}",
69
- :locale => "#{configuration.language}_US",
70
- :appid => configuration.api_key
71
- }.merge(super)
72
- end
73
-
74
- def cache_key(query)
75
- raw_url(query)
76
- end
77
-
78
- def base_url
79
- "#{protocol}://yboss.yahooapis.com/geo/placefinder?"
80
- end
81
-
82
- def raw_url(query)
83
- base_url + url_query_string(query)
84
- end
85
- end
86
- end
@@ -1,39 +0,0 @@
1
- require 'geocoder/results/base'
2
-
3
- module Geocoder::Result
4
- class GeocoderUs < Base
5
- def coordinates
6
- [@data[0].to_f, @data[1].to_f]
7
- end
8
-
9
- def address(format = :full)
10
- "#{street_address}, #{city}, #{state} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
11
- end
12
-
13
- def street_address
14
- @data[2]
15
- end
16
-
17
- def city
18
- @data[3]
19
- end
20
-
21
- def state
22
- @data[4]
23
- end
24
-
25
- alias_method :state_code, :state
26
-
27
- def postal_code
28
- @data[5]
29
- end
30
-
31
- def country
32
- 'United States'
33
- end
34
-
35
- def country_code
36
- 'US'
37
- end
38
- end
39
- end
@@ -1,62 +0,0 @@
1
- require 'geocoder/results/base'
2
-
3
- module Geocoder::Result
4
- class Ovi < Base
5
-
6
- ##
7
- # A string in the given format.
8
- #
9
- def address(format = :full)
10
- address_data['Label']
11
- end
12
-
13
- ##
14
- # A two-element array: [lat, lon].
15
- #
16
- def coordinates
17
- fail unless d = @data['Location']['DisplayPosition']
18
- [d['Latitude'].to_f, d['Longitude'].to_f]
19
- end
20
-
21
- def state
22
- address_data['County']
23
- end
24
-
25
- def province
26
- address_data['County']
27
- end
28
-
29
- def postal_code
30
- address_data['PostalCode']
31
- end
32
-
33
- def city
34
- address_data['City']
35
- end
36
-
37
- def state_code
38
- address_data['State']
39
- end
40
-
41
- def province_code
42
- address_data['State']
43
- end
44
-
45
- def country
46
- fail unless d = address_data['AdditionalData']
47
- if v = d.find{|ad| ad['key']=='CountryName'}
48
- return v['value']
49
- end
50
- end
51
-
52
- def country_code
53
- address_data['Country']
54
- end
55
-
56
- private # ----------------------------------------------------------------
57
-
58
- def address_data
59
- @data['Location']['Address'] || fail
60
- end
61
- end
62
- end
@@ -1,55 +0,0 @@
1
- require 'geocoder/results/base'
2
-
3
- module Geocoder::Result
4
- class Yahoo < Base
5
-
6
- def address(format = :full)
7
- (1..4).to_a.map{ |i| @data["line#{i}"] }.reject{ |i| i.nil? or i == "" }.join(", ")
8
- end
9
-
10
- def city
11
- @data['city']
12
- end
13
-
14
- def state
15
- @data['state']
16
- end
17
-
18
- def state_code
19
- @data['statecode']
20
- end
21
-
22
- def country
23
- @data['country']
24
- end
25
-
26
- def country_code
27
- @data['countrycode']
28
- end
29
-
30
- def postal_code
31
- @data['postal']
32
- end
33
-
34
- def address_hash
35
- @data['hash']
36
- end
37
-
38
- def self.response_attributes
39
- %w[quality offsetlat offsetlon radius boundingbox name
40
- line1 line2 line3 line4 cross house street xstreet unittype unit
41
- city state statecode country countrycode postal
42
- neighborhood county countycode
43
- level0 level1 level2 level3 level4 level0code level1code level2code
44
- timezone areacode uzip hash woeid woetype]
45
- end
46
-
47
- response_attributes.each do |a|
48
- unless method_defined?(a)
49
- define_method a do
50
- @data[a]
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,74 +0,0 @@
1
- #
2
- # = Hash Recursive Merge
3
- #
4
- # Merges a Ruby Hash recursively, Also known as deep merge.
5
- # Recursive version of Hash#merge and Hash#merge!.
6
- #
7
- # Category:: Ruby
8
- # Package:: Hash
9
- # Author:: Simone Carletti <weppos@weppos.net>
10
- # Copyright:: 2007-2008 The Authors
11
- # License:: MIT License
12
- # Link:: http://www.simonecarletti.com/
13
- # Source:: http://gist.github.com/gists/6391/
14
- #
15
- module HashRecursiveMerge
16
-
17
- #
18
- # Recursive version of Hash#merge!
19
- #
20
- # Adds the contents of +other_hash+ to +hsh+,
21
- # merging entries in +hsh+ with duplicate keys with those from +other_hash+.
22
- #
23
- # Compared with Hash#merge!, this method supports nested hashes.
24
- # When both +hsh+ and +other_hash+ contains an entry with the same key,
25
- # it merges and returns the values from both arrays.
26
- #
27
- # h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
28
- # h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
29
- # h1.rmerge!(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
30
- #
31
- # Simply using Hash#merge! would return
32
- #
33
- # h1.merge!(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
34
- #
35
- def rmerge!(other_hash)
36
- merge!(other_hash) do |key, oldval, newval|
37
- oldval.class == self.class ? oldval.rmerge!(newval) : newval
38
- end
39
- end
40
-
41
- #
42
- # Recursive version of Hash#merge
43
- #
44
- # Compared with Hash#merge!, this method supports nested hashes.
45
- # When both +hsh+ and +other_hash+ contains an entry with the same key,
46
- # it merges and returns the values from both arrays.
47
- #
48
- # Compared with Hash#merge, this method provides a different approch
49
- # for merging nasted hashes.
50
- # If the value of a given key is an Hash and both +other_hash+ abd +hsh
51
- # includes the same key, the value is merged instead replaced with
52
- # +other_hash+ value.
53
- #
54
- # h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
55
- # h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
56
- # h1.rmerge(h2) #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
57
- #
58
- # Simply using Hash#merge would return
59
- #
60
- # h1.merge(h2) #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
61
- #
62
- def rmerge(other_hash)
63
- r = {}
64
- merge(other_hash) do |key, oldval, newval|
65
- r[key] = oldval.class == self.class ? oldval.rmerge(newval) : newval
66
- end
67
- end
68
-
69
- end
70
-
71
-
72
- class Hash
73
- include HashRecursiveMerge
74
- end
data/lib/oauth_util.rb DELETED
@@ -1,112 +0,0 @@
1
- # A utility for signing an url using OAuth in a way that's convenient for debugging
2
- # Note: the standard Ruby OAuth lib is here http://github.com/mojodna/oauth
3
- # Source: http://gist.github.com/383159
4
- # License: http://gist.github.com/375593
5
- # Usage: see example.rb below
6
- #
7
- # NOTE: This file has been modified from the original Gist:
8
- #
9
- # 1. Fix to prevent param-array conversion, as mentioned in Gist comment.
10
- # 2. Query string escaping has been changed. See:
11
- # https://github.com/alexreisner/geocoder/pull/360
12
- #
13
-
14
- require 'uri'
15
- require 'cgi'
16
- require 'openssl'
17
- require 'base64'
18
-
19
- class OauthUtil
20
-
21
- attr_accessor :consumer_key, :consumer_secret, :token, :token_secret, :req_method,
22
- :sig_method, :oauth_version, :callback_url, :params, :req_url, :base_str
23
-
24
- def initialize
25
- @consumer_key = ''
26
- @consumer_secret = ''
27
- @token = ''
28
- @token_secret = ''
29
- @req_method = 'GET'
30
- @sig_method = 'HMAC-SHA1'
31
- @oauth_version = '1.0'
32
- @callback_url = ''
33
- end
34
-
35
- # openssl::random_bytes returns non-word chars, which need to be removed. using alt method to get length
36
- # ref http://snippets.dzone.com/posts/show/491
37
- def nonce
38
- Array.new( 5 ) { rand(256) }.pack('C*').unpack('H*').first
39
- end
40
-
41
- def percent_encode( string )
42
-
43
- # ref http://snippets.dzone.com/posts/show/1260
44
- return URI.escape( string, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]") ).gsub('*', '%2A')
45
- end
46
-
47
- # @ref http://oauth.net/core/1.0/#rfc.section.9.2
48
- def signature
49
- key = percent_encode( @consumer_secret ) + '&' + percent_encode( @token_secret )
50
-
51
- # ref: http://blog.nathanielbibler.com/post/63031273/openssl-hmac-vs-ruby-hmac-benchmarks
52
- digest = OpenSSL::Digest::Digest.new( 'sha1' )
53
- hmac = OpenSSL::HMAC.digest( digest, key, @base_str )
54
-
55
- # ref http://groups.google.com/group/oauth-ruby/browse_thread/thread/9110ed8c8f3cae81
56
- Base64.encode64( hmac ).chomp.gsub( /\n/, '' )
57
- end
58
-
59
- # sort (very important as it affects the signature), concat, and percent encode
60
- # @ref http://oauth.net/core/1.0/#rfc.section.9.1.1
61
- # @ref http://oauth.net/core/1.0/#9.2.1
62
- # @ref http://oauth.net/core/1.0/#rfc.section.A.5.1
63
- def query_string
64
- pairs = []
65
- @params.sort.each { | key, val |
66
- pairs.push( "#{ CGI.escape(key.to_s).gsub(/%(5B|5D)/n) { [$1].pack('H*') } }=#{ CGI.escape(val.to_s) }" )
67
- }
68
- pairs.join '&'
69
- end
70
-
71
- # organize params & create signature
72
- def sign( parsed_url )
73
-
74
- @params = {
75
- 'oauth_consumer_key' => @consumer_key,
76
- 'oauth_nonce' => nonce,
77
- 'oauth_signature_method' => @sig_method,
78
- 'oauth_timestamp' => Time.now.to_i.to_s,
79
- 'oauth_version' => @oauth_version
80
- }
81
-
82
- # if url has query, merge key/values into params obj overwriting defaults
83
- if parsed_url.query
84
- CGI.parse( parsed_url.query ).each do |k,v|
85
- if v.is_a?(Array) && v.count == 1
86
- @params[k] = v.first
87
- else
88
- @params[k] = v
89
- end
90
- end
91
- end
92
-
93
- # @ref http://oauth.net/core/1.0/#rfc.section.9.1.2
94
- @req_url = parsed_url.scheme + '://' + parsed_url.host + parsed_url.path
95
-
96
- # create base str. make it an object attr for ez debugging
97
- # ref http://oauth.net/core/1.0/#anchor14
98
- @base_str = [
99
- @req_method,
100
- percent_encode( req_url ),
101
-
102
- # normalization is just x-www-form-urlencoded
103
- percent_encode( query_string )
104
-
105
- ].join( '&' )
106
-
107
- # add signature
108
- @params[ 'oauth_signature' ] = signature
109
-
110
- return self
111
- end
112
- end