geocoder 1.2.7 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of geocoder might be problematic. Click here for more details.

Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +31 -28
  4. data/examples/reverse_geocode_job.rb +40 -0
  5. data/lib/geocoder.rb +1 -0
  6. data/lib/geocoder/configuration.rb +5 -1
  7. data/lib/geocoder/exceptions.rb +3 -0
  8. data/lib/geocoder/ip_address.rb +2 -10
  9. data/lib/geocoder/logger.rb +55 -0
  10. data/lib/geocoder/lookup.rb +2 -1
  11. data/lib/geocoder/lookups/baidu.rb +5 -5
  12. data/lib/geocoder/lookups/baidu_ip.rb +5 -5
  13. data/lib/geocoder/lookups/base.rb +21 -16
  14. data/lib/geocoder/lookups/bing.rb +15 -2
  15. data/lib/geocoder/lookups/esri.rb +1 -1
  16. data/lib/geocoder/lookups/geocoder_ca.rb +1 -2
  17. data/lib/geocoder/lookups/geocodio.rb +3 -3
  18. data/lib/geocoder/lookups/google.rb +3 -3
  19. data/lib/geocoder/lookups/google_places_details.rb +3 -3
  20. data/lib/geocoder/lookups/mapquest.rb +3 -3
  21. data/lib/geocoder/lookups/maxmind.rb +1 -1
  22. data/lib/geocoder/lookups/maxmind_geoip2.rb +69 -0
  23. data/lib/geocoder/lookups/nominatim.rb +1 -1
  24. data/lib/geocoder/lookups/opencagedata.rb +4 -4
  25. data/lib/geocoder/lookups/pointpin.rb +4 -4
  26. data/lib/geocoder/lookups/postcode_anywhere_uk.rb +3 -3
  27. data/lib/geocoder/lookups/yahoo.rb +3 -3
  28. data/lib/geocoder/lookups/yandex.rb +3 -3
  29. data/lib/geocoder/query.rb +1 -1
  30. data/lib/geocoder/request.rb +70 -12
  31. data/lib/geocoder/results/geoip2.rb +8 -14
  32. data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
  33. data/lib/geocoder/results/yandex.rb +5 -5
  34. data/lib/geocoder/version.rb +1 -1
  35. metadata +6 -147
  36. data/.gitignore +0 -6
  37. data/.travis.yml +0 -32
  38. data/Rakefile +0 -25
  39. data/examples/sidekiq_worker.rb +0 -16
  40. data/gemfiles/Gemfile.mongoid-2.4.x +0 -16
  41. data/test/fixtures/baidu_invalid_key +0 -1
  42. data/test/fixtures/baidu_ip_202_198_16_3 +0 -19
  43. data/test/fixtures/baidu_ip_invalid_key +0 -1
  44. data/test/fixtures/baidu_ip_no_results +0 -1
  45. data/test/fixtures/baidu_no_results +0 -1
  46. data/test/fixtures/baidu_reverse +0 -1
  47. data/test/fixtures/baidu_shanghai_pearl_tower +0 -12
  48. data/test/fixtures/bing_invalid_key +0 -1
  49. data/test/fixtures/bing_madison_square_garden +0 -40
  50. data/test/fixtures/bing_no_results +0 -16
  51. data/test/fixtures/bing_reverse +0 -42
  52. data/test/fixtures/cloudmade_invalid_key +0 -1
  53. data/test/fixtures/cloudmade_madison_square_garden +0 -1
  54. data/test/fixtures/cloudmade_no_results +0 -1
  55. data/test/fixtures/esri_madison_square_garden +0 -59
  56. data/test/fixtures/esri_no_results +0 -8
  57. data/test/fixtures/esri_reverse +0 -21
  58. data/test/fixtures/freegeoip_74_200_247_59 +0 -12
  59. data/test/fixtures/freegeoip_no_results +0 -1
  60. data/test/fixtures/geocoder_ca_madison_square_garden +0 -1
  61. data/test/fixtures/geocoder_ca_no_results +0 -1
  62. data/test/fixtures/geocoder_ca_reverse +0 -34
  63. data/test/fixtures/geocoder_us_madison_square_garden +0 -1
  64. data/test/fixtures/geocoder_us_no_results +0 -1
  65. data/test/fixtures/geocodio_1101_pennsylvania_ave +0 -1
  66. data/test/fixtures/geocodio_bad_api_key +0 -3
  67. data/test/fixtures/geocodio_invalid +0 -4
  68. data/test/fixtures/geocodio_no_results +0 -1
  69. data/test/fixtures/geocodio_over_query_limit +0 -4
  70. data/test/fixtures/google_garbage +0 -456
  71. data/test/fixtures/google_madison_square_garden +0 -57
  72. data/test/fixtures/google_no_city_data +0 -44
  73. data/test/fixtures/google_no_locality +0 -51
  74. data/test/fixtures/google_no_results +0 -4
  75. data/test/fixtures/google_over_limit +0 -4
  76. data/test/fixtures/google_places_details_invalid_request +0 -4
  77. data/test/fixtures/google_places_details_madison_square_garden +0 -120
  78. data/test/fixtures/google_places_details_no_results +0 -4
  79. data/test/fixtures/google_places_details_no_reviews +0 -60
  80. data/test/fixtures/google_places_details_no_types +0 -66
  81. data/test/fixtures/here_madison_square_garden +0 -72
  82. data/test/fixtures/here_no_results +0 -8
  83. data/test/fixtures/mapquest_error +0 -16
  84. data/test/fixtures/mapquest_invalid_api_key +0 -16
  85. data/test/fixtures/mapquest_invalid_request +0 -16
  86. data/test/fixtures/mapquest_madison_square_garden +0 -52
  87. data/test/fixtures/mapquest_no_results +0 -16
  88. data/test/fixtures/maxmind_24_24_24_21 +0 -1
  89. data/test/fixtures/maxmind_24_24_24_22 +0 -1
  90. data/test/fixtures/maxmind_24_24_24_23 +0 -1
  91. data/test/fixtures/maxmind_24_24_24_24 +0 -1
  92. data/test/fixtures/maxmind_74_200_247_59 +0 -1
  93. data/test/fixtures/maxmind_invalid_key +0 -1
  94. data/test/fixtures/maxmind_no_results +0 -1
  95. data/test/fixtures/nominatim_madison_square_garden +0 -150
  96. data/test/fixtures/nominatim_no_results +0 -1
  97. data/test/fixtures/nominatim_over_limit +0 -1
  98. data/test/fixtures/okf_kirstinmaki +0 -67
  99. data/test/fixtures/okf_no_results +0 -4
  100. data/test/fixtures/opencagedata_invalid_api_key +0 -25
  101. data/test/fixtures/opencagedata_invalid_request +0 -26
  102. data/test/fixtures/opencagedata_madison_square_garden +0 -73
  103. data/test/fixtures/opencagedata_no_results +0 -29
  104. data/test/fixtures/opencagedata_over_limit +0 -31
  105. data/test/fixtures/ovi_madison_square_garden +0 -72
  106. data/test/fixtures/ovi_no_results +0 -8
  107. data/test/fixtures/pointpin_10_10_10_10 +0 -1
  108. data/test/fixtures/pointpin_555_555_555_555 +0 -1
  109. data/test/fixtures/pointpin_80_111_555_555 +0 -1
  110. data/test/fixtures/pointpin_no_results +0 -1
  111. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_WR26NJ +0 -1
  112. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_generic_error +0 -1
  113. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_hampshire +0 -1
  114. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_key_limit_exceeded +0 -1
  115. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_no_results +0 -1
  116. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_romsey +0 -1
  117. data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_unknown_key +0 -1
  118. data/test/fixtures/smarty_streets_11211 +0 -1
  119. data/test/fixtures/smarty_streets_madison_square_garden +0 -47
  120. data/test/fixtures/smarty_streets_no_results +0 -1
  121. data/test/fixtures/telize_10_10_10_10 +0 -1
  122. data/test/fixtures/telize_555_555_555_555 +0 -4
  123. data/test/fixtures/telize_74_200_247_59 +0 -1
  124. data/test/fixtures/telize_no_results +0 -1
  125. data/test/fixtures/yahoo_error +0 -1
  126. data/test/fixtures/yahoo_invalid_key +0 -2
  127. data/test/fixtures/yahoo_madison_square_garden +0 -52
  128. data/test/fixtures/yahoo_no_results +0 -10
  129. data/test/fixtures/yahoo_over_limit +0 -2
  130. data/test/fixtures/yandex_canada_rue_dupuis_14 +0 -446
  131. data/test/fixtures/yandex_invalid_key +0 -1
  132. data/test/fixtures/yandex_kremlin +0 -48
  133. data/test/fixtures/yandex_new_york +0 -1
  134. data/test/fixtures/yandex_no_administrative_area +0 -53
  135. data/test/fixtures/yandex_no_city_and_town +0 -112
  136. data/test/fixtures/yandex_no_results +0 -16
  137. data/test/integration/http_client_test.rb +0 -31
  138. data/test/mongoid_test_helper.rb +0 -43
  139. data/test/test_helper.rb +0 -423
  140. data/test/unit/active_record_test.rb +0 -16
  141. data/test/unit/cache_test.rb +0 -37
  142. data/test/unit/calculations_test.rb +0 -220
  143. data/test/unit/configuration_test.rb +0 -55
  144. data/test/unit/error_handling_test.rb +0 -79
  145. data/test/unit/geocoder_test.rb +0 -78
  146. data/test/unit/https_test.rb +0 -17
  147. data/test/unit/ip_address_test.rb +0 -27
  148. data/test/unit/lookup_test.rb +0 -153
  149. data/test/unit/lookups/bing_test.rb +0 -68
  150. data/test/unit/lookups/dstk_test.rb +0 -26
  151. data/test/unit/lookups/esri_test.rb +0 -48
  152. data/test/unit/lookups/freegeoip_test.rb +0 -27
  153. data/test/unit/lookups/geocoder_ca_test.rb +0 -17
  154. data/test/unit/lookups/geocodio_test.rb +0 -56
  155. data/test/unit/lookups/geoip2_test.rb +0 -27
  156. data/test/unit/lookups/google_places_details_test.rb +0 -122
  157. data/test/unit/lookups/google_premier_test.rb +0 -22
  158. data/test/unit/lookups/google_test.rb +0 -84
  159. data/test/unit/lookups/mapquest_test.rb +0 -60
  160. data/test/unit/lookups/maxmind_local_test.rb +0 -28
  161. data/test/unit/lookups/maxmind_test.rb +0 -63
  162. data/test/unit/lookups/nominatim_test.rb +0 -31
  163. data/test/unit/lookups/okf_test.rb +0 -38
  164. data/test/unit/lookups/opencagedata_test.rb +0 -64
  165. data/test/unit/lookups/pointpin_test.rb +0 -30
  166. data/test/unit/lookups/postcode_anywhere_uk_test.rb +0 -70
  167. data/test/unit/lookups/smarty_streets_test.rb +0 -71
  168. data/test/unit/lookups/telize_test.rb +0 -36
  169. data/test/unit/lookups/yahoo_test.rb +0 -35
  170. data/test/unit/method_aliases_test.rb +0 -26
  171. data/test/unit/model_test.rb +0 -38
  172. data/test/unit/mongoid_test.rb +0 -47
  173. data/test/unit/near_test.rb +0 -87
  174. data/test/unit/oauth_util_test.rb +0 -31
  175. data/test/unit/proxy_test.rb +0 -37
  176. data/test/unit/query_test.rb +0 -52
  177. data/test/unit/rake_task_test.rb +0 -21
  178. data/test/unit/request_test.rb +0 -35
  179. data/test/unit/result_test.rb +0 -81
  180. data/test/unit/test_mode_test.rb +0 -70
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e80b63580339ffae3893ed71c9cb97081c2b63eb
4
- data.tar.gz: a133f7574566f3dccca311af4cac43a9e661533a
3
+ metadata.gz: d961c40e5dd577d90ddac243ccb32889ef88414e
4
+ data.tar.gz: 275e6174c8aa69f413e5fea4cda24c92110fcc49
5
5
  SHA512:
6
- metadata.gz: b1302d7eabd3c367075ae4af684833e9cbb5af3dcce856716ece5bbb5eba4933fc001235b2638861943362678a6187a029c2f6184f285ab4ed525b2d68b9eca4
7
- data.tar.gz: 94690e53ca9f0b17f0b56a96b2eb4184c5fe96f2ee769eefc1f5f6ecc07c7a334d9fa6cf6a5ef3f986771c5aeaeae1c8566d21b2fbbaebf4c75e6b62a963836f
6
+ metadata.gz: 56be16e5480d37be9acfe3b5b7014ac218c11d82f9a559bd5047e1a93e6a0401230fb66d303d949d3d297464c101f18ecb8dc258395230f76641e195f8be982d
7
+ data.tar.gz: 881e348fa2484ee731b3c0b7c53564c9ce6413d7772e9fe6e5bfa9501fae4162e95f3d08b0c033016c50cd39b2d9a70b855d17f071d83a83f8d5cf1539c6e17f
@@ -3,6 +3,15 @@ Changelog
3
3
 
4
4
  Major changes to Geocoder for each release. Please see the Git log for complete list of changes.
5
5
 
6
+ 1.2.8 (2015 Mar 21)
7
+ -------------------
8
+ * Add :maxmind_geoip2 lookup (thanks github.com/TrangPham).
9
+ * Add ability to force/specify query type (street or IP address) (thanks github.com/TrangPham).
10
+ * Add :basic_auth configuration (thanks github.com/TrangPham).
11
+ * Add `paranoid_location` method for Rails controllers (thanks github.com/edslocomb).
12
+ * Add :logger configuration (thanks github.com/TrangPham).
13
+ * Improve error condition handling with Bing (thanks github.com/TrangPham).
14
+
6
15
  1.2.7 (2015 Jan 24)
7
16
  -------------------
8
17
  * DROP SUPPORT for Ruby 1.9.2.
@@ -14,7 +23,6 @@ Major changes to Geocoder for each release. Please see the Git log for complete
14
23
  * Add ability to raise exception when response parsing fails (thanks github.com/spiderpug).
15
24
  * Fix double-loading of Railtie (thanks github.com/wfleming and zhouguangming).
16
25
 
17
-
18
26
  1.2.6 (2014 Nov 8)
19
27
  ------------------
20
28
  * Add :geoip2 lookup (thanks github.com/ChristianHoj).
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  Geocoder
2
2
  ========
3
3
 
4
- Geocoder is a complete geocoding solution for Ruby. With Rails it adds geocoding (by street or IP address), reverse geocoding (find street address based on given coordinates), and distance queries. It's as simple as calling `geocode` on your objects, and then using a scope like `Venue.near("Billings, MT")`.
4
+ Geocoder is a complete geocoding solution for Ruby. With Rails it adds geocoding (by street or IP address), reverse geocoding (finding street address based on given coordinates), and distance queries. It's as simple as calling `geocode` on your objects, and then using a scope like `Venue.near("Billings, MT")`.
5
+
6
+ _Please note that this README is for the current `HEAD` and may document features not present in the latest gem release. For this reason, you may want to instead view the README for your particular version._
5
7
 
6
8
 
7
9
  Compatibility
@@ -123,12 +125,14 @@ The exact code will vary depending on the method you use for your geocodable str
123
125
  Request Geocoding by IP Address
124
126
  -------------------------------
125
127
 
126
- Geocoder adds a `location` method to the standard `Rack::Request` object so you can easily look up the location of any HTTP request by IP address. For example, in a Rails controller or a Sinatra app:
128
+ Geocoder adds `location` and `safe_location` methods to the standard `Rack::Request` object so you can easily look up the location of any HTTP request by IP address. For example, in a Rails controller or a Sinatra app:
127
129
 
128
130
  # returns Geocoder::Result object
129
131
  result = request.location
130
132
 
131
- Note that this will usually return `nil` in your test and development environments because things like "localhost" and "0.0.0.0" are not an Internet IP addresses.
133
+ **The `location` method is vulnerable to trivial IP address spoofing via HTTP headers.** If that's a problem for your application, use `safe_location` instead, but be aware that `safe_location` will *not* try to trace a request's originating IP through proxy headers; you will instead get the location of the last proxy the request passed through, if any (excepting any proxies you have explicitly whitelisted in your Rack config).
134
+
135
+ Note that these methods will usually return `nil` in your test and development environments because things like "localhost" and "0.0.0.0" are not an Internet IP addresses.
132
136
 
133
137
  See _Advanced Geocoding_ below for more information about `Geocoder::Result` objects.
134
138
 
@@ -212,11 +216,6 @@ You are not stuck with using the `latitude` and `longitude` database column name
212
216
  geocoded_by :address, :latitude => :lat, :longitude => :lon # ActiveRecord
213
217
  geocoded_by :address, :coordinates => :coords # MongoDB
214
218
 
215
- This means you can geocode multiple addresses as well:
216
-
217
- geocoded_by :start_address, latitude: :start_latitude, longitude: :start_longitude
218
- geocoded_by :end_address, latitude: :end_latitude, longitude: :end_longitude
219
-
220
219
  The `address` method can return any string you'd use to search Google Maps. For example, any of the following are acceptable:
221
220
 
222
221
  * "714 Green St, Big Town, MO"
@@ -304,7 +303,7 @@ Every `Geocoder::Result` object, `result`, provides the following data:
304
303
  * `result.country` - string
305
304
  * `result.country_code` - string
306
305
 
307
- If you're familiar with the results returned by the geocoding service you're using you can access even more data, but you'll need to be familiar with the particular `Geocoder::Result` object you're using and the structure of your geocoding service's responses. (See below for links to geocoding service documentation.)
306
+ If you're familiar with the results returned by the geocoding service you're using you can access even more data (call the `#data` method of any Geocoder::Result object to get the full parsed response), but you'll need to be familiar with the particular `Geocoder::Result` object you're using and the structure of your geocoding service's responses. (See below for links to geocoding service documentation.)
308
307
 
309
308
 
310
309
  Geocoding Service ("Lookup") Configuration
@@ -653,18 +652,33 @@ This uses the PostcodeAnywhere UK Geocode service, this will geocode any string
653
652
  * **Terms of Service**: ?
654
653
  * **Limitations**: ?
655
654
 
656
- #### MaxMind Web Services (`:maxmind`)
655
+ #### MaxMind Legacy Web Services (`:maxmind`)
657
656
 
658
657
  * **API key**: required
659
658
  * **Quota**: Request Packs can be purchased
660
659
  * **Region**: world
661
660
  * **SSL support**: yes
662
661
  * **Languages**: English
663
- * **Documentation**: http://www.maxmind.com/app/web_services
662
+ * **Documentation**: http://dev.maxmind.com/geoip/legacy/web-services/
664
663
  * **Terms of Service**: ?
665
664
  * **Limitations**: ?
666
665
  * **Notes**: You must specify which MaxMind service you are using in your configuration. For example: `Geocoder.configure(:maxmind => {:service => :omni})`.
667
666
 
667
+ #### Baidu IP (`:baidu_ip`)
668
+
669
+ * **API key**: required
670
+ * **Quota**: No quota limits for geocoding
671
+ * **Region**: China
672
+ * **SSL support**: no
673
+ * **Languages**: Chinese (Simplified)
674
+ * **Documentation**: http://developer.baidu.com/map/webservice-geocoding.htm
675
+ * **Terms of Service**: http://developer.baidu.com/map/law.htm
676
+ * **Limitations**: Only good for non-commercial use. For commercial usage please check http://developer.baidu.com/map/question.htm#qa0013
677
+ * **Notes**: To use Baidu set `Geocoder.configure(:lookup => :baidu_ip, :api_key => "your_api_key")`.
678
+
679
+
680
+ ### IP Address Local Database Services
681
+
668
682
  #### MaxMind Local (`:maxmind_local`) - EXPERIMENTAL
669
683
 
670
684
  This lookup provides methods for geocoding IP addresses without making a call to a remote API (improves speed and availability). It works, but support is new and should not be considered production-ready. Please [report any bugs](https://github.com/alexreisner/geocoder/issues) you encounter.
@@ -697,23 +711,11 @@ You can generate ActiveRecord migrations and download and import data via provid
697
711
 
698
712
  You can replace `city` with `country` in any of the above tasks, generators, and configurations.
699
713
 
700
- #### Baidu IP (`:baidu_ip`)
701
-
702
- * **API key**: required
703
- * **Quota**: No quota limits for geocoding
704
- * **Region**: China
705
- * **SSL support**: no
706
- * **Languages**: Chinese (Simplified)
707
- * **Documentation**: http://developer.baidu.com/map/webservice-geocoding.htm
708
- * **Terms of Service**: http://developer.baidu.com/map/law.htm
709
- * **Limitations**: Only good for non-commercial use. For commercial usage please check http://developer.baidu.com/map/question.htm#qa0013
710
- * **Notes**: To use Baidu set `Geocoder.configure(:lookup => :baidu_ip, :api_key => "your_api_key")`.
711
-
712
714
  #### GeoLite2 (`:geoip2`)
713
715
 
714
716
  This lookup provides methods for geocoding IP addresses without making a call to a remote API (improves speed and availability). It works, but support is new and should not be considered production-ready. Please [report any bugs](https://github.com/alexreisner/geocoder/issues) you encounter.
715
717
 
716
- * **API key**: none (requires a GeoIP2 or free GeoLite2 City or Country binary database which can be downloaded from [MaxMind](http://dev.maxmind.com/geoip/geoip2/geoip2/))
718
+ * **API key**: none (requires a GeoIP2 or free GeoLite2 City or Country binary database which can be downloaded from [MaxMind](http://dev.maxmind.com/geoip/geoip2/))
717
719
  * **Quota**: none
718
720
  * **Region**: world
719
721
  * **SSL support**: N/A
@@ -977,7 +979,7 @@ http://github.com/alexreisner/geocoder_test
977
979
  Error Handling
978
980
  --------------
979
981
 
980
- By default Geocoder will rescue any exceptions raised by calls to a geocoding service and return an empty array (using warn() to inform you of the error). You can override this on a per-exception basis, and also have Geocoder raise its own exceptions for certain events (eg: API quota exceeded) by using the `:always_raise` option:
982
+ By default Geocoder will rescue any exceptions raised by calls to a geocoding service and return an empty array. You can override this on a per-exception basis, and also have Geocoder raise its own exceptions for certain events (eg: API quota exceeded) by using the `:always_raise` option:
981
983
 
982
984
  Geocoder.configure(:always_raise => [SocketError, TimeoutError])
983
985
 
@@ -993,8 +995,9 @@ The raise-able exceptions are:
993
995
  Geocoder::RequestDenied
994
996
  Geocoder::InvalidRequest
995
997
  Geocoder::InvalidApiKey
998
+ Geocoder::ServiceUnavailable
996
999
 
997
- Note that not all lookups support all exceptions.
1000
+ Note that only a few of the above exceptions are raised by any given lookup, so there's no guarantee if you configure Geocoder to raise `ServiceUnavailable` that it will actually be raised under those conditions (because most APIs don't return 503 when they should; you may get a `TimeoutError` instead). Please see the source code for your particular lookup for details.
998
1001
 
999
1002
 
1000
1003
  Troubleshooting
@@ -1034,7 +1037,7 @@ Reporting Issues
1034
1037
 
1035
1038
  When reporting an issue, please list the version of Geocoder you are using and any relevant information about your application (Rails version, database type and version, etc). Also avoid vague language like "it doesn't work." Please describe as specifically as you can what behavior your are actually seeing (eg: an error message? a nil return value?).
1036
1039
 
1037
- Please DO NOT use GitHub issues to ask questions about how to use Geocoder. Sites like StackOverflow are a better forum for such discussions.
1040
+ Please DO NOT use GitHub issues to ask questions about how to use Geocoder. Sites like [StackOverflow](http://www.stackoverflow.com/) are a better forum for such discussions.
1038
1041
 
1039
1042
 
1040
1043
  ### Known Issue
@@ -1069,4 +1072,4 @@ Contributions are welcome via pull requests on Github. Please respect the follow
1069
1072
  * Be aware that the pull request review process is not immediate, and is generally proportional to the size of the pull request.
1070
1073
 
1071
1074
 
1072
- Copyright (c) 2009-12 Alex Reisner, released under the MIT license
1075
+ Copyright (c) 2009-15 Alex Reisner, released under the MIT license
@@ -0,0 +1,40 @@
1
+ # This class implements an ActiveJob job for performing reverse-geocoding
2
+ # asynchronously. Example usage:
3
+
4
+ # if @location.save && @location.address.blank?
5
+ # ReverseGeocodeJob.perform_later(@location)
6
+ # end
7
+
8
+ # Be sure to configure the queue adapter in config/application.rb:
9
+ # config.active_job.queue_adapter = :sidekiq
10
+
11
+ # You can read the Rails docs for more information on configuring ActiveJob:
12
+ # http://edgeguides.rubyonrails.org/active_job_basics.html
13
+
14
+ class ReverseGeocodeJob < ActiveJob::Base
15
+ queue_as :high
16
+
17
+ def perform(location)
18
+ address = address(location)
19
+
20
+ if address.present?
21
+ location.update(address: address)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def address(location)
28
+ Geocoder.address(location.coordinates)
29
+ rescue => exception
30
+ MonitoringService.notify(exception, location: { id: location.id })
31
+
32
+ if retryable?(exception)
33
+ raise exception
34
+ end
35
+ end
36
+
37
+ def retryable?(exception)
38
+ exception.is_a?(TimeoutError) || exception.is_a?(SocketError)
39
+ end
40
+ end
@@ -1,4 +1,5 @@
1
1
  require "geocoder/configuration"
2
+ require "geocoder/logger"
2
3
  require "geocoder/query"
3
4
  require "geocoder/calculations"
4
5
  require "geocoder/exceptions"
@@ -55,7 +55,9 @@ module Geocoder
55
55
  :cache_prefix,
56
56
  :always_raise,
57
57
  :units,
58
- :distances
58
+ :distances,
59
+ :basic_auth,
60
+ :logger
59
61
  ]
60
62
 
61
63
  attr_accessor :data
@@ -96,6 +98,8 @@ module Geocoder
96
98
  @data[:api_key] = nil # API key for geocoding service
97
99
  @data[:cache] = nil # cache object (must respond to #[], #[]=, and #keys)
98
100
  @data[:cache_prefix] = "geocoder:" # prefix (string) to use for all cache keys
101
+ @data[:basic_auth] = {} # user and password for basic auth ({:user => "user", :password => "password"})
102
+ @data[:logger] = :kernel # :kernel or Logger instance
99
103
 
100
104
  # exceptions that should not be rescued by default
101
105
  # (if you want to implement custom error handling);
@@ -26,4 +26,7 @@ module Geocoder
26
26
  class InvalidApiKey < Error
27
27
  end
28
28
 
29
+ class ServiceUnavailable < Error
30
+ end
31
+
29
32
  end
@@ -1,3 +1,4 @@
1
+ require 'resolv'
1
2
  module Geocoder
2
3
  class IpAddress < String
3
4
 
@@ -6,16 +7,7 @@ module Geocoder
6
7
  end
7
8
 
8
9
  def valid?
9
- ipregex = %r{
10
- \A( # String Starts
11
- ((::ffff:)?((\d{1,3})\.){3}\d{1,3}) # Check for IPv4
12
- | # .... Or
13
- (\S+?(:\S+?){6}\S+) # Check for IPv6
14
- | # .... Or
15
- (::1) # IPv6 loopback
16
- )\z
17
- }x
18
- !!self.match(ipregex)
10
+ !!((self =~ Resolv::IPv4::Regex) || (self =~ Resolv::IPv6::Regex))
19
11
  end
20
12
  end
21
13
  end
@@ -0,0 +1,55 @@
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
+ return nil unless valid_level?(level)
22
+
23
+ logger = Geocoder.config[:logger]
24
+
25
+ if logger == :kernel
26
+ kernel_log(level, message)
27
+ elsif logger.kind_of? ::Logger
28
+ logger.add(SEVERITY[level], message)
29
+ else
30
+ raise Geocoder::ConfigurationError, "Please specify valid logger for Geocoder. " +
31
+ "Logger specified must be :kernel or must respond to `add(level, message)`."
32
+ end
33
+ nil
34
+ end
35
+
36
+ private
37
+
38
+ def kernel_log(level, message)
39
+ case level
40
+ when :debug, :info
41
+ puts message
42
+ when :warn
43
+ warn message
44
+ when :error
45
+ raise message
46
+ when :fatal
47
+ fail message
48
+ end
49
+ end
50
+
51
+ def valid_level?(level)
52
+ [:debug, :info, :warn, :error, :fatal].include? level
53
+ end
54
+ end
55
+ end
@@ -56,7 +56,8 @@ module Geocoder
56
56
  :maxmind,
57
57
  :maxmind_local,
58
58
  :telize,
59
- :pointpin
59
+ :pointpin,
60
+ :maxmind_geoip2
60
61
  ]
61
62
  end
62
63
 
@@ -25,19 +25,19 @@ module Geocoder::Lookup
25
25
  return [doc['result']] unless doc['result'].blank?
26
26
  when 1, 3, 4
27
27
  raise_error(Geocoder::Error, "server error.") ||
28
- warn("Baidu Geocoding API error: server error.")
28
+ Geocoder.log(:warn, "Baidu Geocoding API error: server error.")
29
29
  when 2
30
30
  raise_error(Geocoder::InvalidRequest, "invalid request.") ||
31
- warn("Baidu Geocoding API error: invalid request.")
31
+ Geocoder.log(:warn, "Baidu Geocoding API error: invalid request.")
32
32
  when 5
33
33
  raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
34
- warn("Baidu Geocoding API error: invalid api key.")
34
+ Geocoder.log(:warn, "Baidu Geocoding API error: invalid api key.")
35
35
  when 101, 102, 200..299
36
36
  raise_error(Geocoder::RequestDenied, "request denied") ||
37
- warn("Baidu Geocoding API error: request denied.")
37
+ Geocoder.log(:warn, "Baidu Geocoding API error: request denied.")
38
38
  when 300..399
39
39
  raise_error(Geocoder::OverQueryLimitError, "over query limit.") ||
40
- warn("Baidu Geocoding API error: over query limit.")
40
+ Geocoder.log(:warn, "Baidu Geocoding API error: over query limit.")
41
41
  end
42
42
  return []
43
43
  end
@@ -25,19 +25,19 @@ module Geocoder::Lookup
25
25
  return [doc['content']] unless doc['content'].blank?
26
26
  when 1, 3, 4
27
27
  raise_error(Geocoder::Error, "server error.") ||
28
- warn("Baidu IP Geocoding API error: server error.")
28
+ Geocoder.log(:warn, "Baidu IP Geocoding API error: server error.")
29
29
  when 2
30
30
  raise_error(Geocoder::InvalidRequest, "invalid request.") ||
31
- warn("Baidu IP Geocoding API error: invalid request.")
31
+ Geocoder.log(:warn, "Baidu IP Geocoding API error: invalid request.")
32
32
  when 5
33
33
  raise_error(Geocoder::InvalidApiKey, "invalid api key.") ||
34
- warn("Baidu IP Geocoding API error: invalid api key.")
34
+ Geocoder.log(:warn, "Baidu IP Geocoding API error: invalid api key.")
35
35
  when 101, 102, 200..299
36
36
  raise_error(Geocoder::RequestDenied, "request denied.") ||
37
- warn("Baidu IP Geocoding API error: request denied.")
37
+ Geocoder.log(:warn, "Baidu IP Geocoding API error: request denied.")
38
38
  when 300..399
39
39
  raise_error(Geocoder::OverQueryLimitError, "over query limit") ||
40
- warn("Baidu IP Geocoding API error: over query limit.")
40
+ Geocoder.log(:warn, "Baidu IP Geocoding API error: over query limit.")
41
41
  end
42
42
  return []
43
43
  end
@@ -168,12 +168,12 @@ module Geocoder
168
168
  def fetch_data(query)
169
169
  parse_raw_data fetch_raw_data(query)
170
170
  rescue SocketError => err
171
- raise_error(err) or warn "Geocoding API connection cannot be established."
171
+ raise_error(err) or Geocoder.log(:warn, "Geocoding API connection cannot be established.")
172
172
  rescue Errno::ECONNREFUSED => err
173
- raise_error(err) or warn "Geocoding API connection refused."
173
+ raise_error(err) or Geocoder.log(:warn, "Geocoding API connection refused.")
174
174
  rescue TimeoutError => err
175
- raise_error(err) or warn "Geocoding API not responding fast enough " +
176
- "(use Geocoder.configure(:timeout => ...) to set limit)."
175
+ raise_error(err) or Geocoder.log(:warn, "Geocoding API not responding fast enough " +
176
+ "(use Geocoder.configure(:timeout => ...) to set limit).")
177
177
  end
178
178
 
179
179
  def parse_json(data)
@@ -183,7 +183,7 @@ module Geocoder
183
183
  JSON.parse(data)
184
184
  end
185
185
  rescue => err
186
- raise_error(ResponseParseError.new(data)) or warn "Geocoding API's response was not valid JSON."
186
+ raise_error(ResponseParseError.new(data)) or Geocoder.log(:warn, "Geocoding API's response was not valid JSON.")
187
187
  end
188
188
 
189
189
  ##
@@ -242,16 +242,19 @@ module Geocoder
242
242
  def check_response_for_errors!(response)
243
243
  if response.code.to_i == 400
244
244
  raise_error(Geocoder::InvalidRequest) ||
245
- warn("Geocoding API error: 400 Bad Request")
245
+ Geocoder.log(:warn, "Geocoding API error: 400 Bad Request")
246
246
  elsif response.code.to_i == 401
247
247
  raise_error(Geocoder::RequestDenied) ||
248
- warn("Geocoding API error: 401 Unauthorized")
248
+ Geocoder.log(:warn, "Geocoding API error: 401 Unauthorized")
249
249
  elsif response.code.to_i == 402
250
250
  raise_error(Geocoder::OverQueryLimitError) ||
251
- warn("Geocoding API error: 402 Payment Required")
251
+ Geocoder.log(:warn, "Geocoding API error: 402 Payment Required")
252
252
  elsif response.code.to_i == 429
253
253
  raise_error(Geocoder::OverQueryLimitError) ||
254
- warn("Geocoding API error: 429 Too Many Requests")
254
+ Geocoder.log(:warn, "Geocoding API error: 429 Too Many Requests")
255
+ elsif response.code.to_i == 503
256
+ raise_error(Geocoder::ServiceUnavailable) ||
257
+ Geocoder.log(:warn, "Geocoding API error: 503 Service Unavailable")
255
258
  end
256
259
  end
257
260
 
@@ -262,13 +265,15 @@ module Geocoder
262
265
  def make_api_request(query)
263
266
  timeout(configuration.timeout) do
264
267
  uri = URI.parse(query_url(query))
265
- args = [uri.host, uri.port]
266
- args = args.push(uri.user, uri.password) unless uri.user.nil? or uri.password.nil?
267
- opts = {}
268
- opts[:use_ssl] = use_ssl?
269
-
270
- http_client.start(*args, opts) do |client|
271
- client.get(uri.request_uri, configuration.http_headers)
268
+ http_client.start(uri.host, uri.port, use_ssl: use_ssl?) do |client|
269
+ req = Net::HTTP::Get.new(uri.request_uri, configuration.http_headers)
270
+ if configuration.basic_auth[:user] and configuration.basic_auth[:password]
271
+ req.basic_auth(
272
+ configuration.basic_auth[:user],
273
+ configuration.basic_auth[:password]
274
+ )
275
+ end
276
+ client.request(req)
272
277
  end
273
278
  end
274
279
  end